遵循的模塊化規范不一樣
模塊化規范:即為 JavaScript 提供一種模塊編寫、模塊依賴和模塊運行的方案。誰讓最初的 JavaScript 是那么的裸奔呢——全局變量就是它的模塊化規范。
require/exports 出生在野生規范當中,什么叫做野生規范?即這些規范是 JavaScript 社區中的開發者自己草擬的規則,得到了大家的承認或者廣泛的應用。比如 CommonJS、AMD、CMD 等等。
import/export 則是名門正派。TC39 制定的新的 ECMAScript 版本,即 ES6(ES2015)中包含進來。
出現的時間不同
require/exports 相關的規范由於野生性質,在 2010 年前后出生。AMD、CMD 相對命比較短,到 2014 年基本上就搖搖欲墜了。一開始大家還比較喜歡在瀏覽器上采用這種異步小模塊的加載方式,但並不是銀彈。隨着 Node.js 流行和 Browsersify 的興起,運行時異步加載逐漸被構建時模塊合並分塊所替代。Wrapper 函數再也不需要了。 2014 年 Webpack 還是新玩意,現在已經是前端必備神器了。
Browsersify、Webpack 一開始的目的就是打包 CommonJS 模塊。
CommonJS 作為 Node.js 的規范,一直沿用至今。由於 npm 上 CommonJS 的類庫眾多,以及 CommonJS 和 ES6 之間的差異,Node.js 無法直接兼容 ES6。所以現階段 require/exports 任然是必要且實必須的。出自 ES6 的 import/export 相對就晚了許多。被大家所熟知和使用也是 2015 年之后的事了。 這其實要感謝 babel(原來項目名叫做 6to5,后更名為 babel) 這個神一般的項目。由於有了 babel 將還未被宿主環境(各瀏覽器、Node.js)直接支持的 ES6 Module 編譯為 ES5 的 CommonJS —— 也就是 require/exports 這種寫法 —— Webpack 插上 babel-loader 這個翅膀才開始高飛,大家也才可以稱 " 我在使用 ES6! "
這也就是為什么前面說 require/exports 是必要且必須的。因為事實是,目前你編寫的 import/export 最終都是編譯為 require/exports 來執行的。
require/exports 和 import/export 形式不一樣
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'
require/exports 和 import/export 本質上的差別
形式上看起來五花八門,但本質上:
CommonJS 還是 ES6 Module 輸出都可以看成是一個具備多個屬性或者方法的對象;
default 是 ES6 Module 所獨有的關鍵字,export default fs 輸出默認的接口對象,import fs from 'fs' 可直接導入這個對象;
ES6 Module 中導入模塊的屬性或者方法是強綁定的,包括基礎類型;而 CommonJS 則是普通的值傳遞或者引用傳遞。
1、2 相對比較好理解,3 需要看個例子:
// 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) 分別運行 commonjs.js 和 es6.js: ➜ 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
鏈接:https://www.zhihu.com/question/56820346/answer/150724784