require 和 import的区别

308 阅读2分钟

它们有三个重大差异。

  • CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
  • CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
  • CommonJS 模块的require()是同步加载模块,ES6 模块的import命令是异步加载,有一个独立的模块依赖的解析阶段。

遵循的规范不一样

  • require/exports 是CommonJS的一部分
  • import/export 是ES6规范

出现时间不同

CommonJS 作为Node.js的规范,一直沿用至今。npm上使用CommonJS的库众多,因此node无法至今兼容ES6。所以现阶段,require/exports仍然是必要的。

书写方式不同

require/exports 用法:

const fs = require('fs');
-------------------------
 exports.fs = fs;
 module.exports = fs;

import/export 写法多样:

mport fs from 'fs';
import {default as fs} from 'fs';
import * as fs from 'fs';
-----------------------------
export default fs;
export const fs;
export * from 'fs';

本质上不同

  • 1:无论CommonJS还是ES6 Module 输出都可以看成是一个具备多个属性或者方法的对象;
  • 2: CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用,CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值

针对对上面第二条,代码示例:

// counter.js
exports.count = 0
setTimeout(function () {
  console.log('increase count to', ++exports.count, 'in counter.js after 500ms')
}, 500)

// commonjs.js
const {count} = require('./counter')
setTimeout(function () {
  console.log('read count after 1000ms in commonjs is', count)
}, 1000)

//es6.js
import {count} from './counter'
setTimeout(function () {
  console.log('read count after 1000ms in es6 is', count)
}, 1000)

运行结果:

test node commonjs.js
increase count to 1 in counter.js after 500ms
read count after 1000ms in commonjs is 0
➜  test babel-node es6.js
increase count to 1 in counter.js after 500ms
read count after 1000ms in es6 is 1

  • CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。

import静态编译,import的地址不能通过计算

require就可以,例如 const url = "a" + "b";

Import url 直接报错了

require(url)不会报错

所以require都会用在动态加载的时候

参考文章:www.zhihu.com/question/56…

阮一峰