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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。