Node.js 模块化
CommonJS 规范
CommonJS 是 Node.js 默认的模块系统,同步加载。
- 一个 JS 文件就是一个模块,拥有单独的作用域
- 通过
require加载模块 - 通过
exports和module.exports暴露模块内容
暴露模块
js
// 单个暴露
exports.fn = function() {}
exports.obj = {}
// 整体暴露
module.exports = {
fn: function() {},
obj: {}
}// 单个暴露
exports.fn = function() {}
exports.obj = {}
// 整体暴露
module.exports = {
fn: function() {},
obj: {}
}加载模块
js
const fs = require('fs') // 核心模块
const lodash = require('lodash') // 第三方模块
const utils = require('./utils') // 本地模块const fs = require('fs') // 核心模块
const lodash = require('lodash') // 第三方模块
const utils = require('./utils') // 本地模块模块加载机制
- 模块加载一次后会被缓存,多次加载读取缓存
- 模块按顺序同步加载
require返回的是module.exports的对象
ES Module
ES Module 是 ECMAScript 官方标准,静态编译时加载。
暴露模块
js
// 单个暴露
export let m = 1
export function fn() {}
// 整体暴露
const m = 1
function fn() {}
export { m, fn }
// 默认暴露
export default x = 1// 单个暴露
export let m = 1
export function fn() {}
// 整体暴露
const m = 1
function fn() {}
export { m, fn }
// 默认暴露
export default x = 1导入模块
js
// 普通导入(需要花括号)
import { m, fn } from './module.js'
// 默认导入(不需要花括号)
import utils from './module.js'
// 全部导入
import * as all from './module.js'// 普通导入(需要花括号)
import { m, fn } from './module.js'
// 默认导入(不需要花括号)
import utils from './module.js'
// 全部导入
import * as all from './module.js'CommonJS vs ESM
| 特性 | CommonJS | ES Module |
|---|---|---|
| 加载方式 | 运行时同步加载 | 编译时异步加载 |
| 值是否可修改 | 可以修改 | 只读 |
| Tree Shaking | 不支持 | 支持 |
| 顶层 this | 指向模块本身 | 指向 undefined |
| 文件后缀 | .js / .cjs | .mjs / .js(package.json 配置 type: "module") |
浏览器中使用 Node 模块
使用 Browserify 打包供浏览器使用:
bash
npm install -g browserify
browserify ./src/app.js -o ./dist/bundle.jsnpm install -g browserify
browserify ./src/app.js -o ./dist/bundle.js
Cao Note