[TOC]

JavaScript 模块有两种:CommonJS和ES6模块化规范12

1. CommonJS 模块规范

node.js的默认方式,使用exports(aka. global.module.exports) 对象导出,使用require 函数导入,下面是一个简单的示例(上面是模块,下面是调用):

// circle.js
const PI = 3.1415
function area(r) {
    return PI * r * r
}
// exports
exports.PI = PI
exports.area = area
// 也可以写成下面的方式: exports.PI = 3.14;exports.area=(r)=> PI * r * r
// 或者:exports = {PI, area}
// main.js
const circle = require("./circle.js")// 就是上面模块的exports对象。
console.log(circle.PI)
console.log(circle.area(5))

// 或者,结合对象解构赋值写成
const {area,PI} = require('./circle') // 可省略.js
console.log(PI)
console.log(area(5))

2 ES6模块规范

​ ES6新增export、import 关键字用于支持模块化。注意前后台都可以使用ES6模块,有一些细微的不同。

2.1 nodejs使用

​ nodejs的ES6模块文件后缀使用mjs,上述例子改成:

// circle.mjs
export default PI = 3.1415 // 导出 default
export function area(r) {
    return PI * r * r
}
// 或者 export {area,xx as yy}; 
// export default PI;// 默认值,唯一!
// main.js
import PI from "./circle.mjs"; // 导入 default
import {area} from "./circle.mjs";// import {default as PI, area as Area} from...

2.2 浏览器中使用

<script type="module">
    import {default as PI, area} from './circle.mjs' // js也可以,因为浏览器只支持es6模块。
    // dynamic import:
    import('./circle.mjs').then((module) => {
        // 执行默认方法
        module.default // pi~
    }
</script>

3 总结

模块方式 导出 导入 对象 异步
CommonJS:exports对象/require函数 module.exports = {xx} const {xx}=require(‘a.js’) CommonJS 模块输出的是一个值的拷贝 可动态调用require实现
ES6:export/import 关键字 export const xx=..; export default a; import a from “a.mjs”; import {xx as yy} from ‘a.mjs’; import * from ‘a.mjs’ ES6 模块输出的是值的引用。 使用import("a.js").then((module) => {});
  • 两种模块规范都含有缓存。

  • ES6的 export和import必须在模块顶层使用,不能在函数里使用。require可以做成动态加载的。

  • ES6的模块导出的值是引用,在某些需要每次导入都是新对象的地方,可以把导出一个闭包函数,每次导入后调用一次该函数生成新的对象。


  1. JavaScript 模块 - JavaScript | MDN (mozilla.org) ↩︎

  2. 深入学习CommonJS和ES6模块化规范 (zhihu.com) ↩︎