【问题标题】:Export TypeScript Class to Browser Window and Node.js without bundler (browserify or webpack)将 TypeScript 类导出到浏览器窗口和 Node.js,无需捆绑器(浏览器或 webpack)
【发布时间】:2017-07-12 14:50:26
【问题描述】:

我在 TypeScript 中有以下示例类:

export default class Greeter {
    greeting: string;

    constructor(message: string) {
        this.greeting = message;
    }

    greet() {
        return "Hello, " + this.greeting;
    }
}

使用以下 tsconfig.json:

{
    "compilerOptions": {
        "module": "umd",
        "target": "es5",
        "noImplicitAny": true,
        "removeComments": false,
        "preserveConstEnums": true,
        "suppressImplicitAnyIndexErrors": true
    },
    "files" :[
        "example.ts"
    ]
}

使用转译器,它会生成以下 JavaScript:

(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var Greeter = (function () {
        function Greeter(message) {
            this.greeting = message;
        }
        Greeter.prototype.greet = function () {
            return "Hello, " + this.greeting;
        };
        return Greeter;
    }());
    exports.Greeter = Greeter;
});

我已经用不同的模块(umd,commonjs)测试了很多东西,但是我无法使该类在 Node.js 和浏览器中同时使用相同的代码(使用 require 可以工作使用 Angular、React 和在浏览器的 Window 对象中)。我正在尝试实现以下目标:

// With Node.js, Angular, React etc

let Greeter = require("Greeter");
let instanceGreeter = new Greeter("My Name");
instanceGreeter.greet();

// And that works in the browser too with the same codebase

var instanceGreeter = new Greeter("My Browser Name");
instanceGreeter.greet();

这是否可以通过遵循任何标准或者我必须用我自己的代码导出它(不使用模块选项)?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    经过大量研究,我找不到任何符合我需求的东西。我最终创建了 2 个tsconfig.json 文件(每个类型一个,例如模块和窗口),它们将生成 2 个 JavaScripts 文件。一个用于在浏览器中使用,而不使用任何类型的捆绑器,如 Webpack、Browserify 等,第二个适用于(或至少应该)与 import、require 等一起使用。

    这种方法的缺点是,如果你想编译成窗口版本,你需要在你的类中删除 export default 关键字,例如:

    // If willing to export to window remove `export default` e.g 
    // class Greeter {
    // instead of 
    // export default class Greeter {
    export default class Greeter {
        greeting: string;
    
        constructor(message: string) {
            this.greeting = message;
        }
    
        greet() {
            return "Hello, " + this.greeting;
        }
    }   
    

    由于每个目录只能有一个 tsconfig.json 文件,我创建了 build-instructions 文件夹,里面有 2 个文件夹,即 commonjs 和 window:

    build-instructions
    ├───commonjs
    |   └── tsconfig.json
    ├───window
        └── tsconfig.json
    

    commonjs/tsconfig.json(适用于 require、import 等模块)看起来像:

    {
        "compilerOptions": {
            "module": "commonjs",
            "target": "es5",
            "outDir":"../../build"
        },
        "files" :[
            "../yourtypescriptfile.ts"
        ]
    }
    

    窗口(在浏览器中工作)看起来像:

    {
        "compilerOptions": {
            "module": "none",
            "target": "es5",
            "outFile":"../../build/yourlibrary.window.js"
        },
        "files" :[
            "../yourtypescriptfile.ts"
        ]
    }
    

    在项目的根文件夹中执行 npm 命令时(转译 TypeScript):

    # For CommonJS
    tsc --p ./path-to-folder/commonjs
    
    # For Window
    tsc --p ./path-to-folder/window
    

    它们都会为每种类型的浏览器创建一个兼容的 JavaScript 文件,结果如下:

    var Greeter = (function () {
        function Greeter(message) {
            this.greeting = message;
        }
        Greeter.prototype.greet = function () {
            return "Hello, " + this.greeting;
        };
        return Greeter;
    }());
    

    对于模块(根据您使用的模块,如 umd、commonjs 或 amd):

    define(["require", "exports"], function (require, exports) {
        "use strict";
        Object.defineProperty(exports, "__esModule", { value: true });
        // If willing to export to window remove `export default` e.g 
        // class Greeter {
        // instead of 
        // export default class Greeter {
        var Greeter = (function () {
            function Greeter(message) {
                this.greeting = message;
            }
            Greeter.prototype.greet = function () {
                return "Hello, " + this.greeting;
            };
            return Greeter;
        }());
        exports.default = Greeter;
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多