如果不需要或导入js lib,则公开js lib的最佳方法

时间:2016-09-16 16:09:12

标签: javascript ecmascript-6

我正在创建一个与动画画布lib一起使用的小型lib。大多数人都不使用requireJS,webpack或其中任何一个。

如果在html中直接引用该文件,那么公开全局的最佳方法是什么?

class MyLibClass {
    constructor() {
        // ...
    }
}

if (???) {
    // The user is importing or requiring it
    export default MyLibClass;
} else {
    // Expose to the global scope
     window.MyLibClass = MyLibClass;
}

2 个答案:

答案 0 :(得分:2)

这是一种方法,基本上我的想法是检测环境是否提供了导出库的任何方法,如果全部失败,则回退到单个全局变量。

(function (factory) {
    if (typeof define === "function" && define.amd) {
        define(factory);
    } else if (typeof module != "undefined" && typeof module.exports != "undefined") {
        module.exports = factory();
    } else if (typeof Package !== "undefined") {
        MyLib= factory();  // export for Meteor.js
    } else {
        /* jshint sub:true */
        window["MyLib"] = factory();
    }
}(function () {
    ...
    return myLib;
}));

请注意,它是用ES5编写的,而不是ES6,但它应该很容易回收,支持的导出方法是AMD,RequireJS(和ES6 +),Meteor.js和浏览器。

答案 1 :(得分:1)

ES6解决方案

导入无绑定

某些模块可能无法导出任何内容,而只是对全局范围内的对象进行修改。尽管模块内的顶级变量,函数和类不会自动结束于全局范围,但这并不意味着模块无法访问全局范围。可以在模块内部访问内置对象(如Array和Object)的共享定义,对这些对象的更改将反映在其他模块中。

例如,如果要将pushAll()方法添加到所有数组,可以定义如下模块:

// module code without exports or imports
Array.prototype.pushAll = function(items) {

    // items must be an array
    if (!Array.isArray(items)) {
        throw new TypeError("Argument must be an array.");
    }

    // use built-in push() and spread operator
    return this.push(...items);
};

即使没有导出或导入,这也是一个有效的模块。此代码既可以用作模块,也可以用作脚本。由于它不会导出任何内容,因此您可以使用简化的导入来执行模块代码,而无需导入任何绑定:

import "./example.js";

let colors = ["red", "green", "blue"];
let items = [];

items.pushAll(colors);

来源: Nicholas C. Zakas的一本很棒的书,了解ECMAScript 6。