自从 ES6 被推出后,很多小伙伴的项目里都或多或少地出现了 import、export default 的身影,当然,应该也还存在着 require、exports 。在最初学习js的时候,一直搞不懂这几个的区别,以及使用场景。直到某一天业务中真实需要使用,就好好摸索了一番。
一、区别
(1)require
require 是 CommonJS 的规范,而 node 是由模块组成的,基于 commonJS 规范。
- node 使用 require/exports
// count.js
exports.count = 0
// test.js
const {count} = require('./counter')
console.log(count); // 0
const count = require('./counter')
console.log(count); // { count: 0 }
- 使用:require/module.exports
// count.js
let count = 0
module.exports = count;
// test.js
const count = require('./counter')
console.log(count); // 0
(2)import/export
import/export
是 ES6 正式标准下的产物,使用起来比上面的更复杂。
- 普通使用
// user.js 一个文件可以这样 export 多个
export const getPermission = { xxx }
export const getAcl = { xxx }
// test.js
import { getPermission, getAcl } from './user.js'
- 默认导出
// user.js 一个文件只能 export default 一次
export default generate
// test.js
import generate from './user.js'
-
export 和 export default 区别:
- 在一个文件或模块中,export、import可以有多个,export default仅有一个
- 通过export方式导出,在导入时要加{ },export default 则不需要
- export能直接导出变量表达式,export default 不行。
(3)require/exports 和 import/export 区别
ES6的模块化已经不是规范了,而是JS语言的特性。随着ES6的推出,AMD和CMD也随之成为了历史。ES6模块与模块化规范相比,有两大特点:
- 模块化规范输出的是一个值的拷贝,ES6 模块输出的是值的引用。
- 模块化规范是运行时加载(同步),ES6 模块是编译时输出接口。
- require可以写在任意位置,import只能写在文件的最顶端且不可在条件语句或函数作用域中使用。
- require通过module.exports导出的值就不能再变化,import通过export导出的值可以改变。
- require通过module.exports导出的是exports对象,import通过export导出是指定输出的代码。
- require运行时才引入模块的属性所以性能相对较低,import编译时引入模块的属性所所以性能稍高。
模块化规范输出的是一个对象,该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,ES6 module 是一个多对象输出,多对象加载的模型。从原理上来说,模块化规范是匿名函数自调用的封装,而ES6 module则是用匿名函数自调用去调用输出的成员。
二、使用场景
require的使用非常简单,它相当于module.exports的传送门,module.exports后面的内容是什么,require的结果就是什么,对象、数字、字符串、函数……再把require的结果赋值给某个变量,相当于把require和module.exports进行平行空间的位置重叠。而且require理论上可以运用在代码的任何地方,甚至不需要赋值给某个变量之后再使用,比如:
require('./count')(); // count模块是一个函数,引入后立即执行该函数
let data = require('./count').data; // count导出的是一个对象
let arr = require('./count')[0]; // count导出的是一个数组
import则是编译时运行,必须放在文件开头,而且使用格式也是确定的。它不会将整个模块运行后赋值给某个变量,而是只选择import的接口进行编译,这样在性能上比require好很多。
注意:在项目中,npm 引入
第三方模块,通常使用 require/exports。