【问题标题】:Creating a single CommonJS module from several TypeScript classes从多个 TypeScript 类创建单个 CommonJS 模块
【发布时间】:2014-12-25 02:20:42
【问题描述】:

我正在尝试找出将我的应用程序拆分为几个可供其他应用程序使用的 CommonJS 模块的最佳方法。

我有 5 个 TS 类,我想将它们捆绑为一个 CommonJS 模块。然后我打算将此模块发布到私有 NPM 存储库,以便其他应用程序可以使用它。理想情况下,我想将相关的 *.d.ts 定义文件打包。

最好的方法是什么?我正在使用外部 TS 模块,但这些模块会为每个 TS 类生成一个单独的 CommonJS 模块。

【问题讨论】:

    标签: node.js typescript commonjs grunt-ts


    【解决方案1】:

    据我所知,typescript 还不支持组合外部模块。来自他们在 codeplex 上的 wiki:

    TypeScript 在外部模块源文件和它们发出的 JS 文件之间具有一一对应的关系。这样做的一个影响是无法使用 --out 编译器开关将多个外部模块源文件连接到单个 JavaScript 文件中。

    但是,您可以通过在 typescript 中使用 internal modules 来做一个技巧,因为 tsc 编译器能够将它们编译成单个文件,然后您可以再添加一个文件整个命名空间的module.exports 指令使其成为 CommonJS 模块。

    这里是一步一步的例子。假设您将以下内部模块拆分为三个文件:

    Validation.ts

    module Validation {
        export interface StringValidator {
            isAcceptable(s: string): boolean;
        }
    }
    

    ZipCodeValidator.ts

    /// <reference path="Validation.ts" />
    module Validation {
        var numberRegexp = /^[0-9]+$/;
        export class ZipCodeValidator implements StringValidator {
            isAcceptable(s: string) {
                return s.length === 5 && numberRegexp.test(s);
            }
        }
    }
    

    LettersOnlyValidator.ts

    /// <reference path="Validation.ts" />
    module Validation {
        var lettersRegexp = /^[A-Za-z]+$/;
        export class LettersOnlyValidator implements StringValidator {
            isAcceptable(s: string) {
                return lettersRegexp.test(s);
            }
        }
    }
    

    如果您使用 tsc compiler 中的 --out 参数编译这些文件,您可以将它们合并到一个文件中。但是,这并不能使它们成为 CommonJS 模块。要导出它们,您可以使用一个技巧添加一个名为 ValidationExport.ts 的 ts 文件,其中包含命名空间的导出指令:

    var module: any = <any>module;
    module.exports = Validation;
    

    然后您可以运行 tsc 命令将所有内容编译到一个名为“validationmodule.js”的文件中:

    tsc --out validationmodule.js Validation.ts ZipCodeValidator.ts LettersOnlyValidator.ts ValidationExport.ts
    

    输出是一个可以在 Node.js 中使用的 CommonJS 模块:

    var Validation = require("./validationmodule");
    
    var zipCodeValidator = new Validation.ZipCodeValidator();
    var lettersOnylValidator = new Validation.LettersOnlyValidator();
    
    console.log(zipCodeValidator.isAcceptable("16211"));
    console.log(lettersOnylValidator.isAcceptable("5555"));
    

    【讨论】:

    • 谢谢,很好的回应。我想这会引出我的问题:使用内部模块的缺点是什么?不久前我停止使用它们,因为管理脚本依赖项是一件小事。
    • 内部模块只是命名空间。它们不应该对您的代码构成任何限制。在我上面的示例中,您有脚本依赖项并且它工作正常。如果您有一个更复杂的依赖场景不起作用,您可以将其作为问题发布;)
    • 我在实施此解决方案时遇到了麻烦。具体来说,当我运行tsc --out validationmodule.js Validation.ts [...] ValidationExport.ts 行时,tsc 在尝试处理ValidationExport.ts 时会引发错误TS2304: Cannot find name 'module'.
    • 谢谢!我正要使用此声明 declare var module; 发布类似的修复程序,但您比我早了几秒钟...
    • 您先生,这篇文章让我很开心。我一直在尝试只能部分解决我的问题的解决方案,但这个想法已经做到了 100%。谢谢! :*
    【解决方案2】:

    每个文件有一个单独的 CommonJS 模块是完全合适的。 TypeScript 中的所有 require 调用都将转换为 JavaScript 中的 CommonJS require 调用,并且.d.ts 文件将在此过程中被拾取。 (如果你在源目录之外做一些愚蠢的事情,比如requireing classes...停止。)

    如果您打算在其他应用程序中使用此 NPM 包,则只需要考虑打包步骤,在这种情况下请查看 Browserify

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      • 2010-12-09
      • 1970-01-01
      • 1970-01-01
      • 2016-08-03
      相关资源
      最近更新 更多