exports、module.exports、export 和 export default 的案例和原理解析
1 案例
构建如下几个主要文件用于测试。
1 | ├── src |
为便于比较,他们的结构大致相同:
exports.js
1 | var printMsg = function printMsg() { |
module-exports.js
1 | var printMsg = function printMsg() { |
ES6-export.js
1 | var printMsg = function printMsg() { |
ES6-export-default.js
1 | var printMsg = function printMsg() { |
index.js
1 | import React from "react"; |
执行后,控制台输出结果如下:
1 | Object { printMsg: printMsg() } |
CommonJS 是 NodeJs 服务器端模块的规范,ES Module 是在 ES5 中推出的,基于 CommonJS 规范,而 export 和 export default 是 ES6 中的模块化加载语法。在这之前,必须了解 ES6 模块与 CommonJS 模块完全不同。它们有两个重大差异:
- CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
- CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
第二个差异是因为 CommonJS 加载的是一个对象(即 module.exports 属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。
2 ES5 中 exports 和 module.exports 的区别
- module.exports 才是真正的接口,exports 是它的一个辅助工具。
- nodejs 只会导出 module.exports 的指向,最终返回给调用者的是 module.exports,而不是 exports。
- 所有的 exports 收集到的属性和方法,都赋值给了 module.exports。但前提是 module.exports 本身不具备任何属性和方法。如果 module.exports 已经具备一些属性和方法,那么从 exports 收集来的属性和方法将被忽略。
从输出结果来看,也印证了这一点,在 module-exports.js 中的 console.log(exports);
输出的对象没有属性;而 exports.js 的两个输出是具有相同属性的对象。
3 ES6 中 export 和 export default 区别
- export 与 export default 均可用于导出常量、函数、文件、模块等。在一个文件或模块中 export、import 可以有多个,export default 仅有一个
- export 方式只能具名导入,在导入时要加{ }
- export default 则只能匿名导入
- export 能直接导出变量表达式,export default 不行。