談一下_前端模組化

Module 前端模組化

感謝 七月的雨lizhik猿出道

前端模組化從來都是前端人員關注的問題,首先出現的有Common.js方案(CMD)、require.js方案(AMD)等等,以及最後收場的ES6 Module

Common.js

common.js順應了JavaScript在node上的發展,使用的是同步載入的方式,可以用在伺服器端。當用在前端上,就會影響頁面的渲染(載入一個模組就是一次網路請求對吧),需要選擇非同步載入的其它方案

特性:1、模組可以多次載入,但是只會在第一次載入時運行一次,然後運行結果就被快取了,以後再載入,就直接讀取快取結果。要想讓模組再次運行,必須清除快取。

2、所有程式碼都運行在模組作用域,不會污染全局作用域

3、CommonJS模組輸出的是一個值的拷貝。

4、CommonJS模組是運行時載入。(與ES6Module相比)

AMD方案

模組化的浪潮吹到了瀏覽器端,但因為Commonjs是同步載入的,就催生出了require.js、sea.js等方案。

講一下require.js(作用:1、防止全局污染,2、非同步載入模組)

<!--先導入require.js,使用defer async就可以不影響頁面渲染(或者直接在body最後導入)-->
<script src="js/require.js" defer async="true" ></script>

require.js 用法與分析 不錯的文章

require.js 兼容性強,又易學

ES6 Module

能夠統一模組化標準的,一定有它無可比擬的長處

1、它是編譯時載入的(這與AMD、CMD以及CommonJS有著明顯不同,ES6Module明顯效率更高)

2、ES6 Module 輸出的是值的引用,不會快取值

3、ESModule 可以直接導入Commonjs模組,

module.exports => export default
exports.xxx => export xxx
import * as xxx from 'xxx' // 全適應

對比CommonJS : CommonJS 載入的是一個對象(即module.exports屬性),該對象只有在腳本運行完才會生成。而 ES6 模組不是對象,它的對外介面只是一種靜態定義,在程式碼靜態解析階段就會生成。ES6 模組之中,頂層的this指向undefined;CommonJS 模組的頂層this指向當前模組

缺點:由於是編譯時載入,所以無論怎樣,對應的運行時不支援,就無法時候用。通常的做法是轉化為其他方案:目前瀏覽器對ES6 Module兼容還不太好,我們平時在webpack中使用的export/import,會被打包為exports/require最終文件中的模組實現是基於webpack自己實現的webpack_require(es5程式碼)

UMD模組

其實就是通用模組寫法,集合了CommonJS、AMD和CMD,以及可以直接引用的global對象

(function(root, factory) {
 // 全局變數 module,識別方案
 if (typeof module === 'object' && typeof module.exports === 'object') {
     console.log('是commonjs模組規範,nodejs環境')
     var depModule = require('./umd-module-depended')
     // 模組自身的依賴 。。。
     module.exports = factory(depModule);
 } else if (typeof define === 'function' && define.amd) {
     console.log('是AMD模組規範,如require.js')
      // 模組自身的依賴 。。。
     define(['depModule'], factory)
 } else if (typeof define === 'function' && define.cmd) {
     console.log('是CMD模組規範,如sea.js')
     define(function(require, exports, module) {
         var depModule = require('depModule')
          // 模組自身的依賴 。。。
         module.exports = factory(depModule)
     })
 } else {
     console.log('沒有模組環境,直接掛載在全局對象上')
      // 模組自身的依賴 。。。
     root.umdModule = factory(root.depModule);
 }
}(this, function(depModule) {
 console.log('我調用了依賴模組', depModule)
 // ...省略了一些程式碼,去程式碼倉庫看吧
 return {
     name: '我自己是一個umd模組'
 }
}))
Tags: