1

当前端应用越来越复杂时,我们想要将代码分割成不同的模块,便于复用、按需加载等。

require 和 import 分别是不同模块化规范下引入模块的语句,下文将介绍这两种方式的不同之处。

1. 出现的时间、地点不同

年份 出处
require/exports 2009 CommonJS
import/export 2015 ECMAScript2015(ES6)

CommonJS 模块化方案 require/exports 是为服务器端开发设计的。服务器模块系统同步读取模块文件内容,编译执行后得到模块接口。(Node.js 是 CommonJS 规范的实现)

在浏览器端,因为其异步加载脚本文件的特性,CommonJS 规范无法正常加载。所以出现了 RequireJS、SeaJS(兼容 CommonJS )为浏览器设计的模块化方案。直到 2015 年,ES6 官方发布了模块化方案 import/export。

2. require/exports 是运行时动态加载,import/export 是静态编译

CommonJS 加载的是一个对象(即 module.exports 属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。- 阮一峰

3. require/exports 输出的是一个值的拷贝,import/export 模块输出的是值的引用

若两个文件同时引用一个模块,改变模块内的值时,require引入的模块内的值不会改变,而import引入的模块内的值会改变。

4. 用法不一致

require/exports 的用法:

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

import/export 的写法:
import fs from 'fs'

import {default as fs} from 'fs'
import * as fs from 'fs'
import {readFile} from 'fs'
import {readFile as read} from 'fs'
import fs, {readFile} from 'fs'

export default fs
export const fs
export function readFile
export {readFile, read}
export * from 'fs'

5. require 和 import 支持情况

require/exports import/export
Node.js 所有版本 Node 9.0+(启动需加上 flag --experimental-modules)
Node 13.2+(直接启动) 如何使用?
Chrome 不支持 61+
Firefox 不支持 60+
Safari 不支持 10.1+
Edge 不支持 16+
  • 原生浏览器不支持 require/imports,可使用支持 CommonJS 模块规范的打包工具 Browsersify、webpack 等打包代码。
  • import/export 在浏览器中无法直接使用,我们需要在引入模块的 <script> 元素上添加type="module属性。
  • 即使 Node.js 13.2+ 已经支持 import/export,Node.js官方不建议在正式环境使用,目前可以使用 babel 将 ES6 的模块系统编译成 CommonJS 规范(注意:语法一样,但具体实现还 是require/exports)。

6. 参考资料


秦圆圆
27 声望1 粉丝

热爱生活的平凡人