我正在创建一个与动画画布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;
}
答案 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)
某些模块可能无法导出任何内容,而只是对全局范围内的对象进行修改。尽管模块内的顶级变量,函数和类不会自动结束于全局范围,但这并不意味着模块无法访问全局范围。可以在模块内部访问内置对象(如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。