当前端应用越来越复杂时,我们想要将代码分割成不同的模块,便于复用、按需加载等。
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)。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。