在公开 PowerShell 模块成员时,我应该更喜欢 Export-ModuleMember 还是全局范围?
Should I prefer Export-ModuleMember or the global scope when exposing PowerShell module members?
我一直在编写一个 Cmdlet,并且为了保持界面整洁,我一直在使用 Export-ModuleMember
.
手动导出我关心的功能
但是,有人指出我也可以将函数直接放在 global:
scope 中,而无需调用 Export-ModuleMember
.
哪个更好?
# Option A: Export-ModuleMember
function Do-Something {}
Export-ModuleMember -Function Do-Something
# Option B: global scope
function global:Do-AnotherThing {}
# Something else?
谢谢!
我的直觉是 Export-ModuleMember
更好,因为它让调用者决定函数最终在哪个范围内(例如,另一个 cmdlet 可以导入我的 cmdlet 而无需全局公开那些导出的函数),但我不是当然。
你说得对。不正确地导出函数会规避安装模块时通常预期的行为。
例如,Import-Module
可以防止 cmdlet 破坏当前会话已经可用的 cmdlet 等情况下的破坏。声明一个具有全局作用域的函数可以避免这种情况,并且很少有时候应该这样做,除非模块 的目的是 实际覆盖某些东西(比如它可能设置或修改以某种方式提示)。 按预期执行此操作应该crystal通过模块文档清楚地知道谁在安装模块。
Note: Clobbering is the same basic principle of overloading or overriding members in class inheritance. Creating a new entity with the same name that may (overload) or may not (override) have a different signature.
即使默认情况下 Import-Module
破坏错误,如果您需要会破坏现有命令的 cmdlet 并让用户选择是否允许,Import-Module -AllowClobber
是解决方案破坏。
但我也不推荐Export-ModuleMember either. Rather, you should prepare your module with a manifest (ModuleName.psd1
) instead, and specify the exported functions and cmdlets there. There are also many other things you can set in the manifest as well。
它的好处是使模块定义在操作上更容易理解。现在您不必用一堆 Export-ModuleMember
命令乱扔代码。
Note: If you don't specify the functions or cmdlets to export in your module manifest, or don't have one and do not make use of Export-ModuleMember
, all functions and cmdlets will be exported. This may be desirable or it may not be for a given module, but it's important to understand.
关于编写模块的附加信息
根据评论中的要求,这里有一些关于设计和编写 PowerShell 模块的附加链接:
- Writing a Windows PowerShell Module
- 尽管这在 旧版 SDK 部分中,但本部分中的信息对于学习如何创建模块仍然有用。不过要避免创建管理单元。
- PowerShell Module Authoring Considerations and PowerShell Scripting Performance Considerations
- 两个页面所在的脚本和开发部分包含很多关于顶层模块的有用信息。如果你对模块开发很认真,我建议你好好读一读这部分内容。
我一直在编写一个 Cmdlet,并且为了保持界面整洁,我一直在使用 Export-ModuleMember
.
但是,有人指出我也可以将函数直接放在 global:
scope 中,而无需调用 Export-ModuleMember
.
哪个更好?
# Option A: Export-ModuleMember
function Do-Something {}
Export-ModuleMember -Function Do-Something
# Option B: global scope
function global:Do-AnotherThing {}
# Something else?
谢谢!
我的直觉是 Export-ModuleMember
更好,因为它让调用者决定函数最终在哪个范围内(例如,另一个 cmdlet 可以导入我的 cmdlet 而无需全局公开那些导出的函数),但我不是当然。
你说得对。不正确地导出函数会规避安装模块时通常预期的行为。
例如,Import-Module
可以防止 cmdlet 破坏当前会话已经可用的 cmdlet 等情况下的破坏。声明一个具有全局作用域的函数可以避免这种情况,并且很少有时候应该这样做,除非模块 的目的是 实际覆盖某些东西(比如它可能设置或修改以某种方式提示)。 按预期执行此操作应该crystal通过模块文档清楚地知道谁在安装模块。
Note: Clobbering is the same basic principle of overloading or overriding members in class inheritance. Creating a new entity with the same name that may (overload) or may not (override) have a different signature.
即使默认情况下 Import-Module
破坏错误,如果您需要会破坏现有命令的 cmdlet 并让用户选择是否允许,Import-Module -AllowClobber
是解决方案破坏。
但我也不推荐Export-ModuleMember either. Rather, you should prepare your module with a manifest (ModuleName.psd1
) instead, and specify the exported functions and cmdlets there. There are also many other things you can set in the manifest as well。
它的好处是使模块定义在操作上更容易理解。现在您不必用一堆 Export-ModuleMember
命令乱扔代码。
Note: If you don't specify the functions or cmdlets to export in your module manifest, or don't have one and do not make use of
Export-ModuleMember
, all functions and cmdlets will be exported. This may be desirable or it may not be for a given module, but it's important to understand.
关于编写模块的附加信息
根据评论中的要求,这里有一些关于设计和编写 PowerShell 模块的附加链接:
- Writing a Windows PowerShell Module
- 尽管这在 旧版 SDK 部分中,但本部分中的信息对于学习如何创建模块仍然有用。不过要避免创建管理单元。
- PowerShell Module Authoring Considerations and PowerShell Scripting Performance Considerations
- 两个页面所在的脚本和开发部分包含很多关于顶层模块的有用信息。如果你对模块开发很认真,我建议你好好读一读这部分内容。