ES6的模塊化: import
export default
node
common.js的模塊化: require
module.exports
node.js使用該規範webpack
理想狀況下,開發者只須要實現核心的業務邏輯,其餘均可以加載別人已經寫好的模塊。es6
可是,Javascript不是一種模塊化編程語言,在es6之前,它是不支持」類」(class),因此也就沒有」模塊」(module)了。同時之前也沒有webpack這樣的工具,可使用node去操做文件,讀取文件內容, 而後達到引入文件內容的目的.(也就是模塊化)--在不一樣的文件中放着不一樣的功能模塊web
首先須要明白的在node中每一個文件都是一個自執行函數(只不過咱們肉眼凡胎看不出來,哈啊哈)編程
(function (exports, require, module, __filename, __dirname) {
module.exports = exports = this
return module.exports
})()
複製代碼
爲了說明module.exports = exports = this
請看下面例子element-ui
a.jsbabel
this.a = 123 // 第一種
exports.a = 123 //第二種
module.exports.a = 123 // 第三種
複製代碼
b.js框架
let a = require('./a')
console.log(a)
複製代碼
效果: 編程語言
import/export模塊化
export default
和 export
的區別export
能夠有多個,但 export default
僅有一個1.export
//a.js
export const str = "小生方勤";
//b.js
import { str } from 'a'; // 導入的時候須要花括號
2.export default
//a.js
const str = "小生方勤";
export default str;
//b.js
import str from 'a'; // 導入的時候無需花括號
複製代碼
export default const a = 1;
這樣寫是會報錯的喲。
es6 的導出模塊寫法有
export default 123;
export const a = 123;
const b = 3;
const c = 4;
export { b, c };
複製代碼
雖然咱們通常在像Vue一些框架中均可以使用Es6的語法進行導入導出,可是babel 會將這些通通轉換成 commonjs 的 exports。
exports.default = 123;
exports.a = 123;
exports.b = 3;
exports.c = 4;
exports.__esModule = true;
複製代碼
babel 轉換 es6 的模塊輸出邏輯很是簡單,即將全部輸出都賦值給 exports,並帶上一個標誌 __esModule
代表這是個由 es6 轉換來的 commonjs 輸出。
babel將模塊的導出轉換爲commonjs規範後,也會將引入 import 也轉換爲 commonjs 規範。即採用 require 去引用模塊,再加以必定的處理,符合es6的使用意圖。
也就是全部最後經過webpack打包後都將轉化爲common.js的規範
對於最多見的
import a from './a.js';
複製代碼
在es6中 import a from './a.js' 的本意是想去引入一個 es6 模塊中的 default 輸出。
經過babel轉換後獲得 var a = require(./a.js) 獲得的對象倒是整個對象,確定不是 es6 語句的本意,因此須要對 a 作些改變。
咱們在導出提到,default 輸出會賦值給導出對象的default屬性。
exports.default = 123;
複製代碼
因此這裏最後的 a 變量就是 require 的值的 default 屬性。若是原先就是commonjs規範的模塊,那麼就是那個模塊的導出對象。
咱們使用 import * as a from './a.js'
es6語法的本意是想將 es6 模塊的全部命名輸出以及defalut輸出打包成一個對象賦值給a變量。
已知以 commonjs 規範導出:
exports.default = 123;
exports.a = 123;
exports.b = 3;
exports.__esModule = true;
複製代碼
那麼對於 es6 轉換來的輸出經過 var a = require('./a.js') 導入這個對象就已經符合意圖。
import { a } from './a.js'
直接轉換成 require('./a.js').a
便可。
通過上面的轉換分析,咱們得知即便咱們使用了 es6 的模塊系統,若是藉助 babel 的轉換,es6 的模塊系統最終仍是會轉換成 commonjs 的規範。因此咱們若是是使用 babel 轉換 es6 模塊,混合使用 es6 的模塊和 commonjs 的規範是沒有問題的,由於最終都會轉換成 commonjs。
爲什麼有的地方使用 require 去引用一個模塊時須要加上 default?
require('xx').default
咱們在上文 babel 對導出模塊的轉換提到,es6 的 export default 都會被轉換成 exports.default,即便這個模塊只有這一個輸出。
咱們常常會使用 es6 的 export default 來輸出模塊,並且這個輸出是這個模塊的惟一輸出,咱們會誤覺得這種寫法輸出的是模塊的默認輸出。
// a.js
export default 123;
複製代碼
// b.js 錯誤
var foo = require('./a.js')
複製代碼
在使用 require 進行引用時,咱們也會誤覺得引入的是a文件的默認輸出。
結果這裏須要改爲 var foo = require('./a.js').default
這個場景在寫 webpack 代碼分割邏輯時常常會遇到。
require.ensure([], (require) => {
callback(null, [
require('./src/pages/profitList').default,
]);
});
複製代碼
咱們在使用各大 UI 組件庫時都會被介紹到爲了不引入所有文件,請使用 babel-plugin-component
等babel 插件。
import { Button, Select } from 'element-ui'
複製代碼
由前文可知 import 會先轉換爲 commonjs, 即
var a = require('element-ui');
var Button = a.Button;
var Select = a.Select;
複製代碼
var a = require('element-ui');
這個過程就會將全部組件都引入進來了。
因此 babel-plugin-component
就作了一件事,將 import { Button, Select } from 'element-ui'
轉換成了
import Button from 'element-ui/lib/button'
import Select from 'element-ui/lib/select'
複製代碼
即便轉換成了 commonjs 規範,也只是引入本身這個組件的js,將引入量減小到最低。
因此咱們會看到幾乎全部的UI組件庫的目錄形式都是
|-lib
||--component1
||--component2
||--component3
|-index.common.js
複製代碼
index.common.js
給 import element from 'element-ui'
這種形式調用所有組件
給個element的連接去看看吧 :element.eleme.cn/#/zh-CN/com…