學(xué)習(xí)vue和react和webpack的時候,經(jīng)常看到在js文件中出現(xiàn)require,還有import,這兩個都是為了JS模塊化編程使用。CSS的是@import
ES6標(biāo)準(zhǔn)發(fā)布后,module成為標(biāo)準(zhǔn),標(biāo)準(zhǔn)的使用是以export指令導(dǎo)出接口,以import引入模塊,但是在我們一貫的node模塊中,我們采用的是CommonJS規(guī)范,使用require引入模塊,使用module.exports導(dǎo)出接口.
首先我們先直觀的看一下具體用法的區(qū)別,再來理清理論知識:
require
a.js

b.js

require的核心概念:在導(dǎo)出的文件中定義module.exports,導(dǎo)出的對象類型不予限定(可為任意類型)。在導(dǎo)入的文件中使用require()引入即可使用。本質(zhì)上,是將要導(dǎo)出的對象,賦值給module這個對象的exports屬性,在其他文件中通過require這個方法來訪問exports這個屬性。上面b.js中,require(./a.js) = exports 這個對象,然后使用es6取值方式從exports對象中取出test的值。
import
import是es6為js模塊化提出的新的語法,import (導(dǎo)入)要與export(導(dǎo)出)結(jié)合使用。用法:
a.js

b.js

遵循規(guī)范
require?是 AMD規(guī)范引入方式
import是es6的一個語法標(biāo)準(zhǔn),如果要兼容瀏覽器的話必須轉(zhuǎn)化成es5的語法
調(diào)用時間
require是運(yùn)行時調(diào)用,所以require理論上可以運(yùn)用在代碼的任何地方
import是編譯時調(diào)用,所以必須放在文件開頭
本質(zhì)
require是賦值過程,其實require的結(jié)果就是對象、數(shù)字、字符串、函數(shù)等,再把require的結(jié)果賦值給某個變量
import是解構(gòu)過程,但是目前所有的引擎都還沒有實現(xiàn)import,我們在node中使用babel支持ES6,也僅僅是將ES6轉(zhuǎn)碼為ES5再執(zhí)行,import語法會被轉(zhuǎn)碼為require
require / exports :
遵循 CommonJS/AMD,只能在運(yùn)行時確定模塊的依賴關(guān)系及輸入/輸出的變量,無法進(jìn)行靜態(tài)優(yōu)化。
用法只有以下三種簡單的寫法:
const fs = require('fs')
exports.fs = fs
module.exports = fs
import / export:
遵循 ES6 規(guī)范,支持編譯時靜態(tài)分析,便于JS引入宏和類型檢驗。動態(tài)綁定。
寫法就比較多種多樣:
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引入基礎(chǔ)數(shù)據(jù)類型時,屬于復(fù)制該變量。
通過require引入復(fù)雜數(shù)據(jù)類型時,數(shù)據(jù)淺拷貝該對象。
出現(xiàn)模塊之間的循環(huán)引用時,會輸出已經(jīng)執(zhí)行的模塊,而未執(zhí)行的模塊不輸出(比較復(fù)雜)
CommonJS模塊默認(rèn)export的是一個對象,即使導(dǎo)出的是基礎(chǔ)數(shù)據(jù)類型