JavaScript 在ES6之前没有给出官方模块的定义,因此社区自己搞了两个模块加载方案:

  • CommonJS (node)
  • AMD (browser) 本文略

CommonJS规范

module定义:

每个文件就是一个模块,文件有自己的私有内部作用域。module对象代表当前模块,module.exports 是对外暴露的接口。加载模块,实际上是加载 module.exports.

exportsmodule.exports 的引用,其实质是 node 提供的语法糖, 本质类似于每个模块开头都include了下面的代码。

如修改exports对象的属性,等价于修改了module.exports。虽然这样提供了方便,但是直接改变exports对象的指向是个不好的实践。

引入的时候,require 导入的是 module.exports 指向的一个对象。

ES6 规范

export命令

export 命令定义了模块的输出、其值可以是 value,variable、function、class,

import命令

import大括号内的变量名必须与export一致。(在webstrom等IDE中会帮你静态检查的)

module命令

module 是个语法糖。有时候,需要import所有的接口

可以写成

export default 命令

export default命令定义了模块导出的默认值,引入默认值时不用加大括号。这个命令其实也是语法糖:

把导出值封装到了一个default对象,再在引入时解构这个default对象。因为有一个对象来承接中间的值,所以在import时可以用任意key指定被引入的值

Babel

在ES6出来之前社区上已经有许多CommonJS的module,托Babel的福,可以直接使用ES6的新语法来引入这些只支持CommonJS标准的库。

Babel 做了一层翻译,把ES6的import、export语法变成了兼容CommonJS规范的require、exports。

1. export babel翻译:

上面可以看到export default 和普通的export foo一样,都是给exports对象添加属性。

2. import babel翻译:

==========>

export default 和 import 的使用要结合一起看:

上面的export default翻译为了exports.default

import命令则要先判断:对经过了 babel 翻译后export的module直接返回对象,否则先用对象包装一层,并把export值赋值给default属性;最终在代码中使用时,统一使用moduleName.default 引用。

普通的非default import语法就简单了,和require一模一样,导入时需要添加{}

===========>

参考

  1. http://es6.ruanyifeng.com/#docs/module
  2. http://babeljs.io/repl/
05-28 22:45