module.exports、exports、export、export default之間的關係和區別

對於module.exports、exports和export、export default之間的關係以及他們的區別一直處於懵逼狀態的小夥伴,本篇文章帶你走進新大陸。

首先咱們要明白一個前提,CommonJS模塊規範和ES6模塊規範徹底是兩種不一樣的概念。此處會產生一個疑問,爲何會出現模塊化這種東西,模塊化規範又是指的什麼?

:好久之前,開發網頁要經過命名空間的方式來組織代碼,例如 jQuery 庫將它的 API 都放在了 window.$ 下,在加載完 jQuery 後,其餘模塊再經過 window.$ 去使用 jQuery。這樣作有不少問題,其中包括:

一、命名空間衝突,兩個庫可能會使用同一個名稱,例如 Zepto(http://zepto.com) 也是放在 window.$ 下
二、沒法合理地管理項目的依賴和版本
三、沒法方便地控制依賴的加載順序

當項目變大,這種方式將變得難以維護,須要用模塊化的思想來組織代碼。

模塊化的特色:

一、提高開發效率:代碼方便重用,別人開發的模塊直接拿過來就可使用,不須要重複開發法相似的功能。
二、方便後期維護:代碼方便重用,別人開發的模塊直接拿過來就可使用,不須要重複開發法相似的功能。

模塊化的規範:

 服務器端規範主要是CommonJS,node.js用的就是CommonJS規範。

 客戶端規範主要有:AMD(異步模塊定義,推崇依賴前置)、CMD(通用模塊定義,推崇依賴就近)。AMD規範的實現主要有RequireJS,CMD規範的主要實現有SeaJS。可是SeaJS已經中止維護了,由於在ES6中已經有了模塊化的實現,隨着ES6的普及,第三方的模塊化實現將會慢慢的淘汰。

本文主要介紹的也是CommonJS和ES6,因此其餘的規範請容許我無恥的忽略了,下面進入正題:

1、CommonJS模塊規範
CommonJS的核心思想是經過require方法來同步加載依賴的其餘模塊,經過module.exports處處須要暴露的接口。根據這個規範,每一個文件就是一個模塊,有本身的做用域。在一個文件裏面定義的變量、函數、類,都是私有的,對其餘文件不可見。

module.exports:

// utils.js
let appid = '123456'
let bar = function (id) {
    return `編號:${id}` 
}
// 經過module.exports將appid與bar暴露出去
module.exports = {
    appid , bar
}

----------------------------------------------------

 let utils = require('./utils') // 經過require引入utils
 console.log(utils.appid) // 12345
 console.log(utils.bar(2)) // 編號:2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
exports:

爲了方便,Node爲每一個模塊提供一個exports變量,指向module.exports。這等同在每一個模塊頭部,有一行這樣的命令。

let exports = module.exports;

!!! 這裏要注意:

不能直接將exports變量指向一個值,由於這樣等於切斷了exports與module.exports的聯繫。

let exports = module.exports
let appid = '123456'
// 錯誤寫法
exports = {
    appid
}
// 正確寫法
exports.appid = appid
1
2
3
4
5
6
7
8
2、ES6模塊規範
不一樣於CommonJS,ES6使用 export 和 import 來導出、導入模塊。

export:

// utils.js
export const appid = '123234'
export function getAppid() {
  return '123456'
}

-------------------------------------------------
// 導出的幾種方式:
import { appid , getAppid } from './utils' // 導入多個導出
import * as utils from 'utils' // 做爲命名空間導入整個模塊
console.log(appid) // 123234
console.log(getAppid ()) // 123456
1
2
3
4
5
6
7
8
9
10
11
12
export default:

使用export default命令,爲模塊指定默認輸出,這裏要注意錯誤的一種寫法:

// 錯誤寫法
export default const appid = '123456'
// 正確寫法
const appid = '123456'
export default appid

----------------------------------------------------

import utils from './utils' // 導入默認值
console.log(utils) // 123456
1
2
3
4
5
6
7
8
9
10
順便介紹一下import經常使用的幾種寫法:

import { foo, bar } from ‘./utils’ // 導入多個導出
import * as utils from ‘utils’ // 做爲命名空間導入整個模塊
import utils from ‘utils’ // 導入默認值
import utils , { foo , bar } from ‘./utils’ // 導入多個導出與默認導出
import { foo , bar } , * as utils from ‘utils’ // 導入命名空間整個模塊與多個導出
import(’./utils’).then (res) => { // do something} // import動態導入函數,當使用它的時候,會返回一個promise。
let module = await import(’./utils’) // 支持await關鍵字

3、相關文檔
CommonJS規範,http://javascript.ruanyifeng.com/nodejs/module.html
ES6 Module 的語法,http://es6.ruanyifeng.com/#docs/module
Import用法介紹,https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/import

本月開始學習小程序,會總結小程序專欄文章
相關文章
相關標籤/搜索