警告:在输出全局变量中未提供外部模块“X”的名称 - 猜测为“X”。

20
WARNING: No name was provided for external module 'moment' in output.globals – guessing 'momentImported'
WARNING: No name was provided for external module 'odata-parser' in output.globals – guessing 'parser'

当我尝试将我的库打包成通用模块定义时,收到此警告消息。可以通过在ng-package.json中添加umdModuleIds来修复警告。 文档给出了以下解释:
当编写UMD bundle时,ng-packagr会尽力为UMD模块标识符提供常见的默认值。同时,rollup会尽力猜测外部依赖项的模块ID。即使如此,您应确保外部依赖项的UMD模块标识符正确。如果ng-packagr没有提供默认值,并且rollup无法猜测正确的标识符,则应通过在库的包文件部分使用umdModuleIds显式地提供模块标识符,如下所示:... umdModuleIds:
外部依赖关系及其对应的UMD模块标识符的映射。映射键是TypeScript / EcmaScript模块标识符。映射值是UMD模块ID。该映射的目的是正确地捆绑UMD模块文件(使用rollup)。默认情况下,支持rxjstslib@angular/*依赖项符号。
我如何找到或检查moment、odata-parser或任何其他必须添加到umdModuleIds的模块的UMD ID的正确性?
1个回答

30

我也觉得这些文档很难理解。在ng-package.json中,ng-packagr的umdModuleIds设置是将导入名称映射到UMD在javascript global对象中注册的模块ID。

所谓导入名称,是指在你的typescript代码中:

import * as moment from 'moment';

字符串moment应该是umdModuleIds下的关键字。

值应该与包的UMD捆绑中注册的全局变量相匹配。如果您查看正在导入的JS文件,您会看到设置global.X值。对于moment.js,代码块如下:

//! moment.js

;(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    global.moment = factory()
}(this, (function () { 'use strict';

这行代码global.moment = ...会给你所需的。因此,为了正确导入moment,你的ng-package.json应包含:

  "lib": {
    "entryFile": "src/public-api.ts",
    "umdModuleIds": {
      "moment": "moment"
    }
  }

在这种情况下,ng-packagr的猜测是正确的——导入名称与UMD全局变量匹配,但你需要明确指定它,以便ng-packagr可以确定。

对于NPM依赖项,应该有另一种(更好的)方法来解决这个问题,即将库依赖关系添加到库的package.json文件中(与ng-package.json文件相同的目录中的package.json)。我建议先尝试这种方法-我相信当依赖项包含在package.json中时,ng-packagr会正确地找到UMD模块ID。

然而,在使用本地库(与angular工作区相同的库)或其他无法被ng-packagr分析的库的情况下,有必要查看UMD ID并确保它们匹配。例如,如果您为内部库使用作用域/命名空间名称,如@mycompany/util,则会发现UMD模块ID注册如下:

文件:~/dist/util/bundles/mycompany-util.umd.js

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define('@mycompany/util', ['exports'], factory) :
    (global = global || self, factory((global.mycompany = global.mycompany || {}, global.mycompany.util = {})));
}(this, (function (exports) { 'use strict';

因此,鉴于该行代码 global.mycompany.util =,您需要指定UMD模块ID,例如:

    "umdModuleIds": {
      "@mycompany/util": "mycompany.util"
      ...
    }

1
谢谢您的反馈。能否再讲一下当@mycompany/product-name/ui-module-name这样的情况该怎么处理呢?我试过用"@mycompany/product-name/ui-module-name": "mycompany['product-name']['ui-module-name']"来解析,但是似乎不行,并且提示信息为No name was provided for external module '@mycompany/product-name/ui-module-name' in output.globals – guessing 'uiModuleName' - GarethAS
你尝试过查看@mycompany/product-name/ui-module-name umd.js文件的前几行吗?你只需要在依赖库的ng-package.json中匹配它。 - crimbo
不幸的是,这也不好。它“猜测”uiModuleName,但迄今为止我尝试过的一切都没有起作用。 - GarethAS
将Angular升级到v13会自动删除umdModuleIds,因此我认为我们不应再使用它。 - Raphaël Balet
我同意@RaphaëlBalet的观点 - Angular 13及以上版本不再使用Angular Package Format(https://angular.io/guide/angular-package-format)构建UMD输出,因此对于ng 13+来说,这个问题和答案已经不相关了。然而,对于旧代码仍然是相关的。 - crimbo
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接