8

我正在构建一个模块,用于导出我想通过我的配置文件提供的 cmdlet。此 cmdlet 的实现分布在多个实现文件中,这些文件包含我不想公开的实现功能。所以我使用Export-ModuleMember来隐藏它们。

文件get_something.psm1

import-module .\get_something_impl.psm1

function Get-Something {
    [cmdletbinding()]
    Get-SomethingImplementation
}

Export-ModuleMember -Function Get-Something

然后我将get_something.psm1添加到我的个人资料中。通过仅导出Get-Something,我的所有实现功能都保持“私有”。

我遇到的问题是,在使用Export-ModuleMember命令时,每次我需要其中的一个函数时,我都必须在我的实现文件中导入一个模块。例如,假设我有一个模块 person.psm1 和一个函数Get-Person,我需要在我的所有实现文件中调用它。现在我必须在需要调用Get-Person的每个文件中导入person.psm1。这是使用Export-ModuleMember-Function Get-Something的结果。没有它,我只需要导入person.psm1一次,它就可以使用了。

从本质上讲,Export-ModuleMember不仅阻止了我对外部的实现。它阻止了我自己的实现。

这是预期的并被认为是设计 PowerShell 模块的正常方面吗?

4

1 回答 1

24

这实际上是在模块开发过程中的一些争论。最初,Export-ModuleMember需要导出任何功能。这变得乏味和限制。因此,默认情况下,模块中的所有函数都是可见的,但变量和别名不可见,只要您从未Export-ModuleMember.PSM1.

如果您使用Export-ModuleMember,它将开始限制该列表。导出较少数量的函数可能不是一个坏主意,但您必须谨慎使用它。

你可以写:

Export-ModuleMember -Function a,b,c

它导出了一些功能。

或者

Export-ModuleMember -Function *

后者相当于Export-ModuleMember完全省略。

如果你愿意,你可以使用更多限制性的通配符,但我发现 99% 的时间,你根本不需要费心。

您似乎要问的另一件事是如何最好地处理模块依赖关系。如今,在编写脚本时导入一个或两个模块相当普遍,就像在 C# 项目中包含一个或两个程序集相当普遍一样。如果您在模块内部执行此操作,则可以使用-Globalon 标志Import-Module,并避免使用-Force(这将重新加载模块)。这使得在不同功能中重用模块的效率更高。它还减少了“循环”(卸载和重新加载)模块的问题,不幸的是,许多模块做得不好。

在每个函数中引用模块的替代方法是使用模块清单 ( Get-Help New-ModuleManifest)。模块清单非常有趣,模块开发的许多部分都需要学习。如果您在RequiredModules模块清单列表中包含一个模块,它将在导入模块之前自动加载(至少在 PowerShell 3 和更高版本中)。如果您在NestedModules模块清单列表中包含一个模块,它将作为模块的一部分加载,而由模块导出的命令将由您的模块导出。

模块设计是一头棘手的野兽,但做得对是非常有益的。祝你好运。

于 2014-03-06T06:44:56.317 回答