【问题标题】:Creating single AMD module from many TypeScript classes compiled as AMD modules?从许多编译为 AMD 模块的 TypeScript 类创建单个 AMD 模块?
【发布时间】:2015-09-27 13:07:30
【问题描述】:

我正在尝试创建一个由许多小文件(编译为 JavaScript-AMD 模块的 TypeScript 文件)构建的单个 AMD 库(模块)文件。

问题是:

  1. 类之间存在循环依赖关系。 (父母需要了解孩子,孩子需要了解父母)
  2. 我想摆脱所有的 define() 和 require() 调用,除了 "myLibrary" 的主定义

创建单个文件的主要原因:

  1. 加载时间(requirejs 不应用于引用所有小文件)
  2. AMD 模块无法(?)解决的循环依赖关系

我的主要问题是:

  • 有没有工具可以做到这一点? r.js (grunt-contrib-requirejs) 让我对 define() 的所有内部调用都留在里面失败了。

我目前的项目布局类似于下面的例子:

root
|-- myLibrary
|   |-- packageA
|   |   |-- ClassA1.ts
|   |   +-- ClassA2.ts
|   |-- packageB
|   |   |-- ClassB1.ts
|   |   +-- ClassB2.ts
|   |-- packageA.ts
|   +-- packageB.ts
+-- myLibrary.ts

myLibrary.ts的代码很简单:

export import packageA = require("./packageA");
export import packageB = require("./packageB");

像这样简单地编译成 AMD 模块:

define(["require", "exports", "./myLibrary/packageA", "./myLibrary/packageB"], function (require, exports, packageA, packageB) {
    exports.packageA = packageA;
    exports.packageB = packageB;
});

包文件的结构相同。例如 packageA.ts 看起来像这样:

// Typescript source:
export * from "./packageA/ClassA1";
export * from "./packageA/ClassA2";

// Compiled as Javascript:
define(["require", "exports", "./packageA/ClassA1", "./packageA/ClassA2"], function (require, exports, ClassA1_1, ClassA2_1) {
    function __export(m) {
        for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
    }
    __export(ClassA1_1);
    __export(ClassA1_2);
});

目前得到了什么:

define("myLibrary/packageA/ClassA1",["require", "exports"], function(require, exports) {
    var MyClassA1 = (function() {
        // The content of the class ...
    })();
    exports.MyClassA1 = MyClassA1;
});
define("myLibrary/packageA/ClassA2", ...

// The other stuff ...    

define(["require", "exports", "./myLibrary/packageA", "./myLibrary/packageB"], function (require, exports, packageA, packageB) {
    exports.packageA = packageA;
    exports.packageB = packageB;
});

我想要的:

define(["require", "exports"], function(require, exports) {
    //... The entire code of packageA without define or require.
    var packageA = ...;
    //...
    export.packageA = packageA;
    export.packageB = packageB;
});

【问题讨论】:

    标签: javascript build gruntjs typescript amd


    【解决方案1】:

    他们已经在their roadmap 中捆绑了一个模块。

    由于我们在撰写本文时处于 TypeScript 1.6,并且他们说它将在 1.7 中实现,因此您需要等待 vnext,它应该很快就会发布。

    【讨论】:

    • 这很好听,但遗憾的是并没有解决我的当前问题。我真的很想看看如何使用当前可用的工具来完成它。
    • @Niabot 这对我们大多数人来说是一个很大的愿望,不幸的是,没有简单的方法可以实现您想要的。你需要自己开发它。当他们最终批准下一个版本的模块捆绑时,我几乎是这样做的,所以我会等待(它将在下个月可用,所以,不用等太久)。但是让我们看看是否有人在这里提供了奇迹帮助:)
    【解决方案2】:

    目前,您需要使用其他类型的 AMD 优化器。特别是,您可以使用 r.js,它是 RequireJS 项目的一部分。它将检查您的 AMD 模块并将它们发送到不同的层。

    但目前,如果您将 TypeScript 项目配置为使用 UMD,r.js 优化器将无法识别 properly your UMD modules,因此唯一的选择是将 AMD 用于您的项目。

    我认为即使在 TypeScript 1.7+ 中添加了某种连接,您可能仍希望使用功能更丰富的工具,例如 r.js,因为它可以更好地优化和控制 AMD 应用程序,因为在一个复杂的项目中,层和依赖项通常很复杂。

    【讨论】:

    • 如果 RequireJS (r.js) 实际上能够解决 AMD 模块中的循环依赖关系,我会使用该选项。但它不是!所以我尝试了 SystemJS,它声称能够解决“注册”格式的循环依赖。但我遇到了类似的问题,因为打字稿编译器为每个类发出一个 __extend 函数。难道不能只有一个工具将整个库放入一个文件中,删除所有包/依赖项吗? :(
    • @Niabot 如果您将.tsconfig 文件定位为使用模块系统none,它将删除所有包/依赖项,不是吗?
    • 是的,但是我不能再导出类了,这使得不可能有一个包这样的结构。我想从许多文件中创建一个库,其中一些类和方法作为模块的一部分公开。但我不希望该模块的每个部分在内部都是模块本身。它更像是将多个小模块组合成一个大模块,消除了模块定义的所有开销,同时仍然能够承受循环依赖。 java(原文如此!)编译器会永远这样做,这对于这种情况来说是完美的。
    【解决方案3】:

    将 --outFile 与 --module amd 或 --module 一起指定 系统会将编译中的所有模块连接成一个 包含多个模块闭包的输出文件。

    outfile + amd

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-11
      • 2016-07-29
      • 1970-01-01
      • 1970-01-01
      • 2013-04-30
      相关资源
      最近更新 更多