1 什麼是模組化程式設計
2 為什麼要模組化
3 AMD
4 CommonJS
5 總結
了解一個技術,首先要了解這個技術產生的背景及解決的問題,而不應該只是單純的知道該怎麼用。之前的狀態可能就是只是為了了解而了解,並不知道實際產生的原因及帶來的好處,所以今天就來總結一下。
來看百度百科的定義
模組化程式設計是指在進行程式設計時將一個大程式依照功能劃分為若干小程式模組,每個小程式模組完成一個確定的功能,並在這些模組之間建立必要的聯繫,透過模組的互相協作完成整個功能的程式設計方法。
例如 java 的 import,C# 的 using。我的理解是透過模組化編程,可以將不同的功能獨立出來,修改某個功能時不會對其他功能產生影響。
來看下面一個例子
// A.jsfunction sayWord(type){ if(type === 1){ console.log("hello"); }else if(type === 2){ console.log("world"); } }// B.jsfunction Hello(){ sayWord(1); }// C.jsHello()
假設上面三個文件,B.js 引用了A.js 裡面的內容,C.js又引用了B.js 裡面的內容,如果寫C.js 的人只知道引用了B.js,那他就不會引用A.js 就會導致程式出錯,而且檔案的引用順序也不能出錯。給整體程式碼的調試修改帶來不便。
還有個問題,上述程式碼暴露了兩個全域變量,容易造成全域變數的污染
AMD 即Asynchronous Module Definition(非同步模組定義) 。採取非同步載入的方式載入模組,模組的載入不會影響它後面的語句執行。
假設下面這種情況
// util.jsdefine(function(){ return { getFormatDate:function(date,type){ if(type === 1){ return '2018-08-9' } if(type === 2){ return '2018 年 8 月 9 日' } } } })// a-util.jsdefine(['./util.js'],function(util){ return { aGetFormatDate:function(date){ return util.getFormatDate(date,2) } } })// a.jsdefine(['./a-util.js'],function(aUtil){ return { printDate:function(date){ console.log(aUtil.aGetFormatDate(date)) } } })// main.jsrequire(['./a.js'],function(a){ var date = new Date() a.printDate(date) }) console.log(1);// 使用// <script src = "/require.min.js" data-main="./main.js"></script>
頁面上先列印 1
,然後才會列印 2018 年 8 月 9 日
。因此 AMD 的載入並不會影響後續的語句執行。
如果不是非同步載入會出現什麼情況呢
var a = require('a'); console.log(1)
後面的語句需要等待 a 載入完成才能執行,如果載入時間過長,整個程式都會卡在這。因此,瀏覽器不能同步載入資源,這也是 AMD 的產生背景。
AMD 是在瀏覽器端實作模組化開發的規格。由於該規範不是 JavaScript 原始支援的,使用 AMD 規範進行開發的時候需要引入第三方的函式庫函數,也就是 RequireJS。
RequireJS 主要解決的問題
使JS 非同步加載,避免頁面失去回應
// ? 代表该参数可选 define(id?, dependencies?, factory);
#factory:為模組初始化要執行的函數或物件。如果為函數,它應該只被執行一次。如果是對象,此對象應該為模組的輸出值。 具體的規格說明可以參考AMD (中文版)
define("alpha", ["require", "exports", "beta"], function (require, exports, beta) { exports.verb = function() { return beta.verb(); //Or: return require("beta").verb(); } });
define(["alpha"], function (alpha) { return { verb: function(){ return alpha.verb() + 2; } }; });
一個沒有依賴性的模組可以直接定義物件:
define({ add: function(x, y){ return x + y; } });
AMD 採用require 語句載入模組
require([module],callback);
module:是數組,裡面的成員是要載入的模組
callback:載入成功之後的回呼函數
例如
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">require([&#39;./a.js&#39;],function(a){
var date = new Date()
a.printDate(date)
})</pre><div class="contentsignin">登入後複製</div></div>
具體的使用方法如下
// util.jsdefine(function(){ return { getFormatDate:function(date,type){ if(type === 1){ return '2018-08-09' } if(type === 2){ return '2018 年 8 月 9 日' } } } })// a-util.jsdefine(['./util.js'],function(util){ return { aGetFormatDate:function(date){ return util.getFormatDate(date,2) } } })// a.jsdefine(['./a-util.js'],function(aUtil){ return { printDate:function(date){ console.log(aUtil.aGetFormatDate(date)) } } })// main.jsrequire(['./a.js'],function(a){ var date = new Date() a.printDate(date) })// 使用//
假設這裡有4 個文件,util.js,a- util.js 引用了util.js,a.js 引用了a-util.js,main.js 引用了a.js。
上例示範了一個主模組最簡單的寫法,預設情況下,require.js 假設依賴和主模組在同一個目錄。
使用
require.config()方法可以對模組的載入行為進行自訂。
require.config()就寫在主模組(main.js)的頭部,參數是一個對象,這個對象的paths 屬性指定各個模組的載入路徑
require.config({ paths:{ "a":"src/a.js", "b":"src/b.js" } })
還有一種方法是改變基礎目錄(baseUrl)
require.config({ baseUrl: "src", paths: { "a": "a.js", "b": "b.js", } });
4 CommonJS
commonJS 是nodejs 的模組化規範,現在被大量用在前端,由於建置工具的高度自動化,使得使用npm 的成本非常低。 commonJS 不會非同步載入JS,而是同步一次性載入出來
###在commonJS 中,有一個全域性的方法require(),用於載入模組,例如###const util = require('util');
const util = require('util');var date = new date(); util.getFormatDate(date,1);
// util.jsmodule.exports = { getFormatDate:function(date, type){ if(type === 1){ return '2017-06-15' } if(type === 2){ return '2017 年 6 月 15 日' } } }// a-util.jsconst util = require('util.js') module.exports = { aGetFormatDate:function(date){ return util.getFormatDate(date,2) } }
// foobar.js // 定义行为 function foobar(){ this.foo = function(){ console.log('Hello foo'); } this.bar = function(){ console.log('Hello bar'); } } // 把 foobar 暴露给其它模块 exports.foobar = foobar;// main.js//使用文件与模块文件在同一目录var foobar = require('./foobar').foobar, test = new foobar(); test.bar(); // 'Hello bar'
CommonJS 则采用了服务器优先的策略,使用同步方式加载模块,而 AMD 采用异步加载的方式。所以如果需要使用异步加载 js 的话建议使用 AMD,而当项目使用了 npm 的情况下建议使用 CommonJS。
相关推荐:
以上是什麼是模組化程式設計? js 模組化程式設計的總結的詳細內容。更多資訊請關注PHP中文網其他相關文章!