Skip to content

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 ​

特性CommonJSES 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.js
npm install -g browserify
browserify ./src/app.js -o ./dist/bundle.js