【问题标题】:Loading bundled AMD modules with SystemJS使用 SystemJS 加载捆绑的 AMD 模块
【发布时间】:2017-02-28 23:48:03
【问题描述】:

我有几个 AMD 模块使用 TypeScript 的 --outFile 选项编译到一个文件中:

define("partA", ["require", "exports"], function (require, exports) {
    "use strict";
    function partAFunc() {
        console.log('partAFunc');
        return 'partAFunc';
    }
    exports.partAFunc = partAFunc;
});
define("partB", ["require", "exports"], function (require, exports) {
    "use strict";
    exports.partB = 42;
});
define("partC", ["require", "exports"], function (require, exports) {
    ...
});

现在我只想加载partA 模块并调用它的partAfunc(),这样我就可以在Node.js 中执行以下操作:

SystemJS.config({
  map: {
    'main': 'my-bundle.js',
  },
});

SystemJS.import('main').then((m) => {
  SystemJS.import('partA').then((m) => {
    m.partAFunc();
  });
});

第一次导入 SystemJS.import('main') 只是注册所有模块,然后 SystemJS.import('partA') 工作,因为模块 partA 已经注册(或者至少我猜它是这样做的)。

但是,为什么我不能只使用 SystemJS.import('partA') 并将捆绑包设置为依赖项:

SystemJS.config({
  meta: {
    'partA': {
      deps: [ 'my-bundle.js' ],
    }
  }
});

SystemJS.import('partA').then((m) => {
  m.partAFunc();
});

meta 被完全忽略。 https://github.com/systemjs/systemjs/blob/master/docs/config-api.md#meta 的文档说:

在此模块之前加载的依赖项。通过常规路径和地图规范化。仅支持 cjs、amd 和全局格式。

看起来 SystemJS 首先检查文件 partA 是否存在(显然不存在)并抛出错误(我用现有文件对其进行了测试,meta 配置有效):

(node:60981) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: ENOENT: no such file or directory, open '/Users/.../partA'
  Instantiating /Users/.../partA
  Loading partA

我希望当第一个变体与两个嵌套的 SystemJS.import 调用一起使用时,以下内容也应该起作用。

SystemJS.config({
  map: {
    'partA': 'my-bundle.js',
  },
});

SystemJS.import('partA').then((m) => {
  // m.partAFunc();
  console.log(m)
});

这会打印一个空对象。看起来当单个文件中有多个模块时,它只是注册它们而不加载它们中的任何一个?

我阅读了https://github.com/systemjs/systemjs/tree/master/docs 中的所有文档,但我想我还是迷路了。

【问题讨论】:

    标签: javascript node.js systemjs es6-module-loader es6-modules


    【解决方案1】:

    您需要做的是使用bundles 设置并像这样设置您的包:

        bundles: {
          'my-bundle.js': ['partA', 'partB', 'partC'],
        }, 
    

    粗略地说,这告诉 SystemJS “当你寻找模块 partA 时,获取并执行名为 my-bundle.js 的模块,你会在那里找到 partA。”


    您使用meta 的方法不起作用。您的 meta 设置没有说“不要尝试获取名为 partA 的模块,而 获取 my-bundle.js”它说“当您处理 partA 时,除了它已经拥有的依赖项,请将my-bundle.js 添加到依赖项列表中。” SystemJS 仍将获取partA。它没有理由等到它执行完my-bundle.js 后再尝试获取它,因此它会立即启动获取并失败。

    【讨论】:

    • 我认为bundles 选项仅适用于使用 SystemJS Builder 创建的包,这意味着我需要使用系统模块格式。我正在使用 AMD 格式。我想我现在明白deps 的作用了。它按顺序加载模块,因此两者都需要存在,但它们首先使用deps 执行。
    • 您可以将 bundle 与 AMD 模块一起使用。我已经做到了。不涉及 SystemJS 构建器。该文档具有误导性。它对构建器的说明和使用System.register 的目的是为了说明(这是一种 方法)。它不是规定的
    • 这很有趣,我刚刚测试过,它也确实适用于 AMD 模块。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多