模块化这个话题在 ES6 之前是不存在的,因此这也被诟病为早期 JavaScript 开发全局污染和依赖管理混乱问题的源头。
常见的模块化方案包含这几种:
CommonJS
AMD
CMD
UMD
ES Modules
CommonJS 比 ES Modules 规范早了几年。 它旨在解决 JavaScript 生态系统中缺乏对可重用模块的支持。 CommonJS 有一个 require() 函数,它根据提供的路径获取外部模块,并在运行时将其添加到作用域中。
运行时执行的特点
从 CommonJS 规范中吸取教训,ES Modules 标准采用 import/export 关键字对模块进行处理,且不依赖运行时执行结果
执行 require 后内存产物
{
id: '...',
exports: { ... },
loaded: true,
...
}
CommonJS 的引用方式多种多样
const foo = require('foo');
function demo() {
const foo = require('foo');
}
if (statement) {
const foo = require('foo');
}
switch (key) {
case value:
const foo = require('foo');
break;
default:
break;
}
// ...
ES Modules 标准的特点
一个函数是不是“纯”的?
const pure =
(a:number, b:number) => a + b
const impure =
(c:number) => window.foo.number + c
在 package.json 中标明
{
"name": "my-package",
"sideEffects": false
}
单独表明
var Button$1 =
/*#__PURE__*/ withAppProvider()(Button);
{
"name": "your-project",
"sideEffects": [
"./src/some-side-effectful-file.js",
"*.css"
]
}
在 webpack v4+ 开始
{
"mode":
process.env.NODE_ENV === 'production' ?
'production' : 'development'
}
在 webpack v3 及之前
// transform.js
import * as mylib from 'mylib';
export const someVar = mylib.transform({
// ...
});
export const someOtherVar = mylib.transform({
// ...
});
// -------------------------------------------
// index.js
import { someVar } from './transforms.js';
// Use `someVar`...
// before transformation
import { Row, Grid as MyGrid } from 'react-bootstrap';
import { merge } from 'lodash';
// after transformation
import Row from 'react-bootstrap/lib/Row';
import MyGrid from 'react-bootstrap/lib/Grid';
import merge from 'lodash/merge';
{
// ...
"type": "module",
"main": "./index-cjs.js",
"module": "./index-esm.js",
"exports": {
"require": "./index-cjs.js",
"import": "./index-esm.js"
}
// ...
}