好程式設計師web前端教程分享js中的模組化一
好程式設計師web 前端教程分享 js 中的模組化一:我們知道最常見的模組化方案有 CommonJS 、 AMD 、 CMD 、 ES6 , AMD 規範一般用於瀏覽器,非同步的,因為模組載入是非同步的, js 解釋是同步的,所以有時候導致依賴還沒載入完畢,同步的程式碼執行結束; CommonJS 規範一般用於服務端,同步的,因為在伺服器端所有檔案都儲存在本地的硬碟上,傳輸速率快而且穩定。
1.script 標籤引入
最開始的時候,多個script 標籤引入 js 檔案。但是,這種弊端也很明顯,很多個 js 檔案合併起來,也是相當於一個 script ,造成變數汙染。專案大了,不想變數汙染也是很難或者不容易做到,開發和維護成本高。 而且對於標籤的順序,也是需要考慮一陣,還有載入的時候同步,更加是一種災難,幸好後來有了渲染完執行的 defer 和下載完執行的 async ,進入新的時代了。
接著,就有各種各樣的動態建立script 標籤的方法,最終發展到了上面的幾種方案。
2.AMD 與 CMD
2.1AMD
非同步模組定義,提供定義模組及非同步載入該模組依賴的機制。AMD 遵循依賴前置,程式碼在一旦執行到需要依賴的地方,就馬上知道依賴是什麼。而無需遍歷整個函式體找到它的依賴,因此效能有所提升。但是開發者必須先前知道依賴具體有什麼,並且顯式指明依賴,使得開發工作量變大。而且,不能保證模組載入的時候的順序。 典型代表 requirejs 。 require.js 在宣告依賴的模組時會立刻載入並執行模組內的程式碼。 require 函式讓你能夠隨時去依賴一個模組,即取得模組的引用,從而即使模組沒有作為引數定義,也能夠被使用。他的風格是依賴注入,比如:
/api.js
define('myMoudle',['foo','bar'],function(foo,bar){
// 引入了 foo 和 bar ,利用 foo 、 bar 來做一些事情
return {
baz:function(){return 'api'}
}
});
require(['api'],function(api) {
console.log(api.baz())
})
複製程式碼
然後你可以在中間隨時引用模組,但是模組第一次初始化的時間比較長。這就像開始的時候很拼搏很辛苦,到最後是美滋滋。
2.2CMD
通用模組定義,提供模組定義及按需執行模組。遵循依賴就近,程式碼在執行時,最開始的時候是不知道依賴的,需要遍歷所有的require 關鍵字,找出後面的依賴。一個常見的做法是將 function toString 後,用正則匹配出 require 關鍵字後面的依賴。 CMD 裡,每個 API 都簡單純粹。可以讓瀏覽器的模組程式碼像 node 一樣,因為同步所以引入的順序是能控制的。 對於典型代表 seajs ,一般是這樣子:
define(function(require,exports,module){
//... 很多程式碼略過
var a = require('./a');
// 要用到 a ,於是引入了 a
// 做一些和模組 a 有關的事情
});
複製程式碼
對於b.js 依賴 a.js
//a.js
define(function(require, exports) {
exports.a = function(){// 也可以把他暴露出去
// 很多程式碼
};
});
//b.js
define(function(require,exports){
// 前面幹了很多事情,突然想要引用 a 了
var fun = require('./a');
console.log(fun.a()); // 就可以呼叫到及執行 a 函式了。
})
// 或者可以 use
seajs.use(['a.js'], function(a){
// 做一些事情
});
複製程式碼
AMD 和 CMD 對比: AMD 推崇依賴前置、提前執行, CMD 推崇依賴就近、延遲執行。
AMD 需要先列出清單,後面使用的時候隨便使用(依賴前置),非同步,特別適合瀏覽器環境下使用(底層其實就是動態建立 script 標籤)。而且 API 預設是一個當多個用。
CMD 不需要知道依賴是什麼,到了改需要的時候才引入,而且是同步的,就像臨時抱佛腳一樣。
對於客戶端的瀏覽器,一說到下載、載入,肯定就是和非同步脫不了關係了,註定瀏覽器一般用AMD 更好了。但是, CMD 的 api 都是有區分的,區域性的 require 和全域性的 require 不一樣。
3.CommonJS 與 ES6
3.1 ES6
ES6 模組的 script 標籤有點不同,需要加上 type='module'
<script src='./a.js' type='module'>...</script>
複製程式碼
對於這種標籤都是非同步載入,而且是相當於帶上defer 屬性的 script 標籤,不會阻塞頁面,渲染完執行。但是你也可以手動加上 defer 或者 async ,實現期望的效果。 ES6 模組的檔案字尾是 mjs ,透過 import 引入和 export 匯出。我們一般是這樣子:
//a.mjs
import b from 'b.js'
//b.mjs
export default b
複製程式碼
ES6 畢竟是 ES6 ,模組內自帶嚴格模式,而且只在自身作用域內執行。在 ES6 模組內引入其他模組就要用 import 引入,暴露也要用 export 暴露。另外,一個模組只會被執行一次。 import 是 ES6 新語法,可靜態分析,提前編譯。他最終會被 js 引擎編譯,也就是可以實現編譯後就引入了模組,所以 ES6 模組載入是靜態化的,可以在編譯的時候確定模組的依賴關係以及輸入輸出的變數。 ES6 可以做到編譯前分析,而 CMD 和 AMD 都只能在執行時確定具體依賴是什麼。
3.2CommonJS
一般服務端的檔案都在本地的硬碟上面。對於客戶,他們用的瀏覽器是要從這裡下載檔案的,在服務端一般讀取檔案非常快,所以同步是不會有太大的問題。require 的時候,馬上將 require 的檔案程式碼執行
代表就是nodejs 了。用得最多的,大概就是:
//app.js
var route = require('./route.js')// 讀取控制路由的 js 檔案
//route.js
var route = {......}
module.exports = route
複製程式碼
require 第一次載入指令碼就會馬上執行指令碼,生成一個物件
區別: CommonJS 執行時載入,輸出的是值的複製,是一個物件(都是由 module.export 暴露出去的),可以直接拿去用了,不用再回頭找。所以,當 module.export 的原始檔裡面一些原始型別值發生變化, require 這邊不會隨著這個變化而變化的,因為被快取了。但是有一種常規的操作,寫一個返回那個值的函式。就像 angular 裡面 $watch 陣列裡面的每一個物件,舊值是直接寫死,新值是寫一個返回新值的函式,這樣子就不會寫死。 module.export 輸出一個取值的函式,呼叫的時候就可以拿到變化的值。
ES6 是編譯時輸出介面,輸出的是值的引用,對外的介面只是一種靜態的概念,在靜態解釋後已經形成。當指令碼執行時,根據這個引用去原本的模組內取值。所以不存在快取的情況, import 的檔案變了,誰發出 import 的也是拿到這個變的值。模組裡面的變數繫結著他所在的模組。另外,透過 import 引入的這個變數是隻讀的,試圖進行對他賦值將會報錯。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2661415/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 好程式設計師web前端教程分享js中的模組化二程式設計師Web前端JS
- 好程式設計師web前端教程分享js閉包程式設計師Web前端JS
- 好程式設計師web前端教程分享js模板模式程式設計師Web前端JS模式
- 好程式設計師web前端教程之前端模組化開發程式設計師Web前端
- 好程式設計師web前端教程分享js reduce方法使用教程程式設計師Web前端JS
- 好程式設計師web前端教程分享JS基礎知識程式設計師Web前端JS
- 好程式設計師web前端教程分享CSS技巧!程式設計師Web前端CSS
- 好程式設計師web前端教程分享web中CSS絕對定位程式設計師Web前端CSS
- 好程式設計師web前端教程分享Vue.js面試題程式設計師Web前端Vue.js面試題
- 好程式設計師web前端分享web測試之Js中的變數程式設計師Web前端JS變數
- 好程式設計師web前端教程分享web前端基礎知識程式設計師Web前端
- 好程式設計師web前端教程分享js檔案引用編碼方式程式設計師Web前端JS
- 好程式設計師web前端培訓分享CSS定位的教程程式設計師Web前端CSS
- 好程式設計師分享Web前端效能最佳化程式設計師Web前端
- 好程式設計師web前端分享Nodejs學習筆記之Stream模組程式設計師Web前端NodeJS筆記
- 好程式設計師web前端教程分享javascript 練習題程式設計師Web前端JavaScript
- 好程式設計師web前端教程分享JavaScript面試題程式設計師Web前端JavaScript面試題
- 好程式設計師web前端教程分享JavaScript簡寫方法程式設計師Web前端JavaScript
- 好程式設計師Web前端教程分享JavaScript開發技巧程式設計師Web前端JavaScript
- 好程式設計師Web前端教程分享Vue學習心得程式設計師Web前端Vue
- 好程式設計師web前端教程之Node.Js流程程式設計師Web前端Node.js
- 好程式設計師web前端分享js剪下板Clipboard.js 使用程式設計師Web前端JS
- 好程式設計師web前端教程:字串程式設計師Web前端字串
- 好程式設計師web前端分享:如何理解web語義化?程式設計師Web前端
- 好程式設計師web前端教程分享前端javascript練習題二程式設計師Web前端JavaScript
- 好程式設計師web前端教程分享前端javascript練習題三程式設計師Web前端JavaScript
- 好程式設計師web前端教程分享前端 javascript 練習題二程式設計師Web前端JavaScript
- 好程式設計師web前端教程分享web前端入門基礎知識程式設計師Web前端
- 好程式設計師Web前端分享前端CSS篇程式設計師Web前端CSS
- 好程式設計師web前端分享JS引擎的執行機制程式設計師Web前端JS
- 好程式設計師web前端分享js實現實戰案例程式設計師Web前端JS
- 好程式設計師web前端教程分享JavaScript的執行機制!程式設計師Web前端JavaScript
- 好程式設計師web前端分享css初始化程式碼程式設計師Web前端CSS
- 好程式設計師web前端教程分享JavaScript Math(算數)物件程式設計師Web前端JavaScript物件
- 好程式設計師web前端學習教程之Node Js流程程式設計師Web前端JS
- 好程式設計師web前端分享前端javascript練習題一程式設計師Web前端JavaScript
- 好程式設計師web前端教程分享前端javascript練習題之promise程式設計師Web前端JavaScriptPromise
- 好程式設計師Web前端分享程式的三大結構(一)程式設計師Web前端