module.exports、exports、export有什么區(qū)別?

一、module.exports、exports、export有什么區(qū)別?

這三個東西其實是兩個概念的區(qū)分: 先來看一個表格:

image.png

這樣看其實還是挺清晰的,不同規(guī)范使用的關(guān)鍵詞和特性不同而已,我們在使用這些關(guān)鍵詞的時候區(qū)分自己是什么環(huán)境下寫的代碼。

  • nodejs(webpack,babel)->commonjs,
  • 瀏覽器(vuescript標(biāo)簽 或 html中帶type="module"script標(biāo)簽中)-> esm。
  1. module.exports、exports是一伙的,他們都是基于commonjs規(guī)范來的。
  2. export是基于es6esm(ECMA Script Modules)規(guī)范來的。

二、commonjs規(guī)范:

CommonJS 規(guī)范是為了解決 JavaScript的作用域問題而定義的模塊形式,可以使每個模塊它自身的命名空間中執(zhí)行。該規(guī)范的主要內(nèi)容是,模塊必須通過 module.exports 導(dǎo)出對外的變量或接口,通過 require()來導(dǎo)入其他模塊的輸出到當(dāng)前模塊作用域中。

2.1. 列子:

// moduleA.js
module.exports.double = function( value ){
    return value * 2;
}
// moduleB.js
var { double } = require('./moduleA');
var res = double(4);
console.log(res) //8

為了方便,某些情況下·module.exports·可以簡寫為·exports·。其實一開始exports就是module.exports的引用。

module.exports===exports //true

所以上面的moduleA.js,可以這樣省略掉module

// moduleA.js
exports.double = function (value) {
    return value * 2;
}
// moduleB.js
var { double } = require('./moduleA');
var res = double(4);
console.log(res) //8

2.2. 注意

當(dāng) module.exports后面跟著賦值語句時,不能省略module.,為什么?我們接著看

一開始 module.exports全等于 exports 我們可以看成在文件開頭有這樣的代碼:

module.exports = {};//方便理解 一開始是空對象
let exports = module.exports;
console.log(module.exports===exports)//true

所以在exports對象{}上添加任何的新屬性,其實就是在module.exports上添加屬性,因為我們知道node中對象也是引用類型的。

exports.double = function (value) {
    return value * 2;
}

exports.PAI = 3.1415926535897932384626 //233,我可以背這么多位~
exports.add = function (a, b) {
    return a + b;
}

危!直接給exports賦值就不行了

module.exports = {};//方便理解 一開始是空對象
let exports = module.exports;

//給exports 賦值會切斷和 module.exports 的聯(lián)系

//這樣 不要這樣做~!
exports = {
    name: 'zhangsan'
}
//或這樣  不要這樣做~!
exports = function name(a) {}
//或這樣  不要這樣做~!
exports = 3.1415926535897932384626
console.log(module.exports); // 打印:{} 回到初始{}值
console.log(exports);  // 打?。?.1415926535897932384626

console.log(module.exports === exports); //false 你走的獨木橋 我走我的陽關(guān)道 已經(jīng)莫得關(guān)系了

如果要使用賦值來導(dǎo)出,可以這樣導(dǎo)出一個對象:

// moduleA.js
module.exports = {
    name:'法外狂徒張三',
    age:'19',
    wife:'隔壁小紅'
}

// moduleB.js
let { name, wife } = require('./moduleA');
console.log(name,age) //法外狂徒張三 隔壁小紅

這樣module.exports就能保證獲取到值。

2.4. 如何重命名

commonjs中重命名導(dǎo)出的變量用(:)符號:

let { name, wife: girlfriend } = require('./moduleA');

三、esm(ECMA Script Modules)規(guī)范

現(xiàn)在來說我們在編寫vue或者react項目中熟悉的es6 module規(guī)范。

esm 是將 javascript 程序拆分成多個單獨模塊,并能按需導(dǎo)入的標(biāo)準(zhǔn)。和webpack,babel不同的是,esmjavascript的標(biāo)準(zhǔn)功能,在瀏覽器端和 nodejs 中都已得到實現(xiàn)。使用 esm 的好處是瀏覽器可以最優(yōu)化加載模塊,比使用庫更有效率。通過import, export語法實現(xiàn)模塊變量的導(dǎo)入和導(dǎo)出
劃重點:commonjs中使用requiremodelue.exports實現(xiàn)模塊的導(dǎo)入導(dǎo)出,esm 使用 import, export導(dǎo)入導(dǎo)出。

3.1. export

esmexport支持:let、var、const、function、class等 以下都是正確的導(dǎo)出方式:

var person = {
    name: '貓小白',
    text: a,
}
export {
    person,
}
export function showAge() {
    console.log(person.age);
}
export let city = '成都'
export const PAI = '3.141592653'

注意:export命令規(guī)定的是對外的接口,必須與模塊內(nèi)部的變量建立一一對應(yīng)關(guān)系。

// 錯誤1
export 3.14;

這種寫法都是錯誤的,因為export后面直接跟了一個具體的,外部無法通過一個特定的標(biāo)識(變量)來獲取這個值。

export導(dǎo)出的數(shù)據(jù)如何重命名?

import { wife as girlfrend } from "./moduleA.js";

想要導(dǎo)出所有方法或變量為指定的一個變量時,可以用 import * as mod from "xxxx"

import * as tool from "./moduleA.js";
console.log(tool.API) //3.141592

3.2. export default 默認(rèn)導(dǎo)出

commonjs規(guī)范先進一點的是 esm 提供了一種默認(rèn)導(dǎo)出的方式。export default后面可以直接跟隨:變量、具體值、function、calss。

//正確
let a = '張三';

export default a
//正確
export default 3.14

export default function (a) {
    return a * a
}
//正確
let sum = function (a, b) {
    return a + b
}
export default sum
//正確
function calc(a, b) {
    return a + b
}
export default calc

3.3. ESM模塊規(guī)范規(guī)定,在html中 script標(biāo)簽設(shè)置type='module'可以書寫ESM模塊代碼,包括導(dǎo)入功能:

<script type="module">
    import { name,wife } from "./es6/moduleA.js"
    console.log(name,wife); //法外狂徒張三 小紅
    //...其它代碼
</script>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容