JS 模块 CJS AMD UMD ESM 的区别
2023-12-13 04:31:13
CommonJS
CommonJS 使用关键字 require 和 exports,require 是一个函数,用来导入其他模块的函数,exports 是一个变量,它指向的函数会被导出:
// store/customer.js
exports = function() { // 导出
return customers.get('store');
}
// payments.js
var customerStore = require('store/customer'); // 导入
Node.js 的模块系统参考了 CommonJS 的规范,主要区别是 Node.js 用 module.exports 作为被导出的对象:
// store/customer.js
function customerStore() {
return customers.get('store');
}
modules.exports = customerStore;
// payments.js
var customerStore = require('store/customer'); // 导入
这种模块系统主要是为服务器端开发而设计,文件导入是同步的,导入完一个才能导入下一个
由于服务器端导入文件是从本地读取,没有网络延迟,所以导入速度还比较快
但是如果在浏览器端,等待模块导入的时间由网络速度决定,慢的话会阻塞浏览器加载,所以采用异步的导入会更好
如果要在浏览器端使用 CommonJS 的话,需要先转译打包
Asynchronous Module Definition (AMD)
由于 CommonJS 不适合在浏览器使用,AMD 出现了,这是一个支持异步(Asynchronous)的模块系统。
// 定义模块(同时也导入模块)
define('module1', ['dep1', 'dep2'], function(dep1, dep2) {
return {
hello: function(){...}
}
});
// or
define(function (require) {
var dep1 = require('dep1');
var dep2 = require('dep2');
return {
hello: function(){...}
}
});
define(id?, dependencies?, factory) 函数的第一个参数是模块名,第二个是依赖模块的数组,被异步加载。只有在所有依赖模块完成加载后,factory 函数才会执行
AMD 是为浏览器端设计的。在运行时,AMD 加载器知道整个应用的依赖树,所以可以同时加载不互相依赖的模块/库,这样首次加载的速度会更快,用户体验也就更好
AMD 中也可以使用 require 和 exports
比较有名的实现是 require.js 和 Dojo
Universal Module Definition (UMD)
UMD 既可以在前端也可以在后端使用,UMD 同时支持 CommonJS 和 AMD,也支持老式的全局变量规范。
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define(["jquery", "underscore"], factory); // AMD
} else if (typeof exports === "object") {
module.exports = factory(require("jquery"), require("underscore")); // CommonJS
} else {
global.Requester = factory(global.$, global._); // 全局变量 ($: jquery, _: underscore)
}
}(this, function ($, _) {
// 模块
var Requester = { /* ...*/ };
return Requester;
});
- UMD 更像是一种模式,用来兼容多种模块系统。
ES Modules (ESM)
上面的几中都不是原生 JS 支持的,但是 ESM 是 ES6 开始提供的导入和导出模式,同时支持同步和异步操作。
// lib.js
export const foo = "foo";
export const bar = () => {}
// main.js
import { foo, bar } from 'lib';
- ESM 支持 Tree-shaking,对代码做静态分析,清除不需要的代码。
- ESM 也支持动态导入 import()。
- 不是所有的浏览器都支持,可能会需要用 Babel 转译。
- import 和 export 的更多用法和细节可以看文档
文章来源:https://blog.csdn.net/weixin_46787337/article/details/134910090
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!