【问题标题】:Should I prefer Export-ModuleMember or the global scope when exposing PowerShell module members?在公开 PowerShell 模块成员时,我应该更喜欢 Export-ModuleMember 还是全局范围?
【发布时间】:2021-12-03 21:24:51
【问题描述】:

我一直在编写 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 而不会全局公开这些导出的函数),但我不确定。

【问题讨论】:

    标签: powershell cmdlets


    【解决方案1】:

    你是正确的。不正确的导出函数会在安装模块时规避通常预期的行为。

    例如,Import-Module 可防止在某个 cmdlet 踩踏当前会话已可用的 cmdlet 时发生破坏。用全局范围声明一个函数可以绕过这一点,并且很少有时间应该这样做,除非模块 的目的是实际覆盖某些东西(比如它可能设置或修改某些提示大大地)。 通过模块文档的方式安装模块应该非常清楚谁在安装模块

    注意: Clobbering 与类继承中重载或覆盖成员的基本原则相同。创建一个具有相同名称的新实体,该实体可能(重载)也可能不(覆盖)具有不同的签名。

    即使Import-Module 默认情况下会导致破坏,Import-Module -AllowClobber 也是解决方案,如果您需要破坏现有命令的 cmdlet,并让用户选择是否允许破坏。


    但我也不推荐Export-ModuleMember。相反,您应该使用清单 (ModuleName.psd1) 来准备您的模块,并在那里指定导出的函数和 cmdlet。 There are also many other things you can set in the manifest as well.

    它的好处是使模块定义在操作上更容易理解。现在您不必在代码中乱扔一堆Export-ModuleMember 命令。

    注意:如果您没有在模块清单中指定要导出的函数或 cmdlet,或者没有并且没有使用 Export-ModuleMember全部 函数和 cmdlet 将被导出。这可能是可取的,也可能不适用于给定的模块,但理解这一点很重要。


    关于编写模块的附加信息

    根据 cmets 的要求,这里有一些关于设计和编写 PowerShell 模块的附加链接:

    【讨论】:

    • 谢谢,本德!是否有任何官方 MSDN 文档推荐这些方法中的任何一种,或者您的建议仅仅是基于您观察到的效果?
    • 我不知道,但 MSDN 阅读量很大。有解释 cmdlet、模块清单和范围如何工作的文档,但这些都在单独的文档区域中。我认为 MS 没有官方文件说“做或不做某事”。有一些关于创建和维护模块的文档,这部分文档可能会涉及不同方法的陷阱和好处。我所说的大部分内容来自个人经验、api/cmdlet 文档、我自己的模块开发以及我观察其他模块的行为方式。我将编辑一个指向以上更多内容的链接。
    猜你喜欢
    • 1970-01-01
    • 2013-12-13
    • 2015-06-13
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 2019-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多