js模块化概述: CJS \AMD\UMD\ESM
模块化的优点:1. 避免全局变量被污染 2. 便于代码编写和维护
CommonJS(CJS)
每个文件就是一个模块,有自己的作用域,文件内的变量、函数、类都是私有的,对其他文件不可见。模块内部,module
变量代表当前模块,这个变量是一个对象,它的 exports
属性(即 module.exports
)是对外的接口。加载某个模块,其实是加载该模块的 module.exports
属性。
例如:
module.exports.x = x;
module.exports.addX = addX;
// 或者
module.exports={x,addX}
如果某个变量或者函数想要被成公共变量,能够在其他文件中获取,就需要挂在 global
上。(这么写并不推荐)
例如:
global.warning = true;
CJS 是同步导入模块,可以从 modules 中引入一个库或者从本地目录引入一个文件,使用 require
方法用于加载模块
当 CJS 导入时,它会给你一个导入对象的副本。
const { sequelize } = require("../../core/db");
CJS 不能在浏览器中工作,必须经过转换和打包。
node.js 就是使用 commonJs 的模块规范,可以在 js 文件中直接使用。
特点
- 所有代码都运行在模块作用域,不会污染全局作用域。
- 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
- 模块加载的顺序,按照其在代码中出现的顺序。
ESM ES 模块
这是 Javascript 提出的实现一个标准模块系统的方案,在很多现代浏览器可以使用.
可以在 HTML 中调用,但是需要在 script
标签上添加属性 type=‘module’
。
<script type="module">
import {func1} from 'my-lib';
func1();
</script>
可以导入本地的文件、库或者远程模块。(静态)
import { createStore } from "https://unpkg.com/redux@4.0.5/es/redux.mjs";
import * as myModule from './util.js';
除了能够静态导入,还可以动态导入。ES模块实际上是JavaScript对象:我们可以解构它们的属性以及调用它们的任何公开方法。
例如:
btn.addEventListener("click", () => {
// loads named export
import("./util.js").then(({ funcA }) => {
funcA();
});
});
或
const loadUtil = () => import("./util.js");
// 返回的是一个 promise。所以也可以使用可以使用 `async/await`
btn.addEventListener("click", () => {
loadUtil().then(module => {
module.funcA();
module.default();
})
})
// 使用 async/await 的写法
btn.addEventListener("click", async () => {
const utilsModule = await loadUtil();
utilsModule.funcA();
utilsModule.default();
})
使用动态导入可以拆分代码,只在适当的时候加载重要的代码。在 JavaScript 引入动态导入之前,这种模式是webpack(模块绑定器)独有的。
像 React
和 Vue
通过动态导入代码拆分来加载响应事件的代码块,比如用户交互或路由更改。
当导入的json文件时,导出的直接是json文件中的数据
优点
具有 CJS 的简单语法和 AMD 的异步,ESM 允许像 Rollup 这样的打包器,删除不必要的代码,减少代码包可以获得更快的加载。
参考: https://blog.csdn.net/hpc_kiven/article/details/108483784
AMD 异步模块定义
AMD 是为前端而做的(而 CJS 是后端),AMD 的语法不如 CJS 直观。
示例:
define(['dep1', 'dep2'], function (dep1, dep2) {
//Define the module value by returning a value.
return function () {};
});
// "simplified CommonJS wrapping" https://requirejs.org/docs/whyamd.html
define(function (require) {
var dep1 = require('dep1'),
dep2 = require('dep2');
return function () {};
});
UMD 通用模块定义(Universal Module Definition)
在前端和后端都适用,与 CJS 或 AMD 不同,UMD 更像是一种配置多个模块系统的模式,当使用 Rollup/Webpack 之类的打包器时,UMD 通常用作备用模块
(function (root, factory) {
if (typeof define === "function" && define.amd) {
define(["jquery", "underscore"], factory);
} else if (typeof exports === "object") {
module.exports = factory(require("jquery"), require("underscore"));
} else {
root.Requester = factory(root.$, root._);
}
}(this, function ($, _) {
// this is where I defined my module implementation
var Requester = { // ... };
return Requester;
}));
标题:js模块化概述: CJS \AMD\UMD\ESM
作者:limanting
地址:https://blog.manxiaozhi.com/articles/2021/08/06/1628225877419.html