摘要:來源于阿賢博客模塊化今天給大家寫一篇關于前端模塊化開發知識點。前端模塊化開發那點歷史模塊化是指在解決某個復雜混雜問題時,依照一種分類的思維把問題進行系統性的分解以之處理。
來源于:阿賢博客
javascript模塊化今天給大家寫一篇關于前端模塊化開發知識點。
前端模塊化開發那點歷史
模塊化:
是指在解決某個復雜、混雜問題時,依照一種分類的思維把問題進行系統性的分解以之處理。模塊化是一種處理復雜系統分解為代碼結構更合理,可維護性更高的可管理的模塊的方式。
模塊化是軟件系統的屬性,這個系統被分解為一組高內聚,低耦合的模塊。那么在理想狀態下我們只需要完成自己部分的核心業務邏輯代碼,其他方面的依賴可以通過直接加載被人已經寫好模塊進行使用即可。
模塊化系統所必須的能力:
定義封裝的模塊。
定義新模塊對其他模塊的依賴。
可對其他模塊的引入支持。
好了,思想有了,那么總要有點什么來建立一個模塊化的規范制度吧,不然各式各樣的模塊加載方式只會將局攪得更為混亂。那么在JavaScript中出現了一些非傳統模塊開發方式的規范 CommonJS的模塊規范,AMD(Asynchronous Module Definition),CMD(Common Module Definition)等。
為了建立一個模塊化的規范制度、模塊加載方式。在JavaScript中出現了一些非傳統模塊開發方式的規范 CommonJS的模塊規范,AMD(Asynchronous Module Definition)、CMD(Common Module Definition)、ES6模塊誕生了。AMD規范(與Requirejs)
AMD(Asynchronous Module Definition)異步模塊定義,所有的模塊將被異步加載,模塊加載不影響后面語句運行。所有依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成之后,這個回調函數才會運行。
AMD規范定義了一個自由變量或者說是全局變量 define 的函數。
define( id?, dependencies?, factory );AMD規范
第一個參數 id 為字符串類型,表示了模塊標識,為可選參數。若不存在則模塊標識應該默認定義為在加載器中被請求腳本的標識。如果存在,那么模塊標識必須為頂層的或者一個絕對的標識。
第二個參數,dependencies ,是一個當前模塊依賴的,已被模塊定義的模塊標識的數組字面量。
第三個參數,factory,是一個需要進行實例化的函數或者一個對象。
define("alpha", [ "require", "exports", "beta" ], function( require, exports, beta ){ export.verb = function(){ return beta.verb(); // or: return require("beta").verb(); } });
define(["alpha"], function( alpha ){ return { verb : function(){ return alpha.verb() + 1 ; } } });
define( { add : function( x, y ){ return x + y ; } } );require();
require API
在 AMD 規范中的 require 函數與一般的 CommonJS中的 require 不同。由于動態檢測依賴關系使加載異步,對于基于回調的 require 需求強烈。
局部的 require 需要在AMD模式中的 define 工廠函數中傳入 require。
define( ["require"], function( require ){ // ... } ); or: define( function( require, exports, module ){ // ... } );
局部的 require 需要其他特定的 API 來實現。
全局的 require 函數是唯一全局作用域下的變量,像 define一樣。全局的 require 并不是規范要求的,但是如果實現全局的 require函數,那么其需要具有與局部 require 函數 一樣的以下的限定:
1. 模塊標識視為絕對的,而不是相對的對應另一個模塊標識。
2. 只有在異步情況下,require的回調方式才被用來作為交互操作使用。因為他不可能在同步的情況下通過 require(String) 從頂層加載模塊。
依賴相關的API會開始模塊加載。如果需要有互操作的多個加載器,那么全局的 reqiure 應該被加載頂層模塊來代替。
require(String) define( function( require ){ var a = require("a"); // 加載模塊a } ); require(Array, Function) define( function( require ){ require( ["a", "b"], function( a,b ){ // 加載模塊a b 使用 // 依賴 a b 模塊的運行代碼 } ); } ); require.toUrl( Url ) define( function( require ){ var temp = require.toUrl("./temp/a.html"); // 加載頁面 } );RequireJS
官網
API
API 中文
RequireJS 是一個前端的模塊化管理的工具庫,遵循AMD規范,它的作者就是AMD規范的創始人 James Burke。
頁面頂層
defined用于定義模塊,RequireJS要求每個模塊均放在獨立的文件之中。按照是否有依賴其他模塊的情況分為獨立模塊和非獨立模塊。
define({ method1: function(){}, method2: function(){} }); //等價于 define(function(){ return{ method1: function(){}, method2: function(){} } });
define([ "module1", "module2" ], function(m1, m2){ //代碼... }); //等價于 define( function( require ){ var m1 = require( "module1" ), m2 = require( "module2" ); //代碼... });
define 和 require 這兩個定義模塊,調用模塊的方法合稱為AMD模式,定義模塊清晰,不會污染全局變量,清楚的顯示依賴關系。AMD模式可以用于瀏覽器環境并且允許非同步加載模塊,也可以按需動態加載模塊。
/*** **** require方法調用模塊 **** 在加載 foo 與 bar 兩個模塊之后執行回調函數實現具體過程。 ***/ require( ["foo", "bar"], function( foo, bar ){ foo.func(); bar.func(); } ); /*** **** 在define定義模塊內部進行require調用模塊 ***/ define( function( require ){ var m1 = require( "module1" ), m2 = require( "module2" ); //代碼... });CMD規范(與Seajs)
在CMD中,一個模塊就是一個文件,格式為:define( factory );
[CMD模塊定義規范](https://github.com/seajs/seaj...)
全局函數define,用來定義模塊。
參數 factory 可以是一個函數,也可以為對象或者字符串。
當 factory 為對象、字符串時,表示模塊的接口就是該對象、字符串。
define({ "foo": "bar" });
define("this is {{data}}.");
//表示模塊的構造方法,執行構造方法便可以得到模塊向外提供的接口。 define( function(require, exports, module) { // 模塊代碼 });define( id?, deps?, factory );
define也可以接受兩個以上的參數,字符串id為模塊標識,數組deps為模塊依賴:
define( "module", ["module1", "module2"], function( require, exports, module ){ // 模塊代碼 } );
其與 AMD 規范用法不同。
require 是 factory 的第一個參數。
require( id );
接受模塊標識作為唯一的參數,用來獲取其他模塊提供的接口:
define(function( require, exports ){ var a = require("./a"); a.doSomething(); });require.async( id, callback? );
require是同步往下執行的,需要的異步加載模塊可以使用 require.async 來進行加載:
define( function(require, exports, module) { require.async(".a", function(a){ a.doSomething(); }); });require.resolve( id )
可以使用模塊內部的路徑機制來返回模塊路徑,不會加載模塊。
exports 是 factory 的第二個參數,用來向外提供模塊接口。define(function( require, exports ){ exports.foo = "bar"; // 向外提供的屬性 exports.do = function(){}; // 向外提供的方法 }); //使用 return 直接向外提供接口。 define(function( require, exports ){ return{ foo : "bar", // 向外提供的屬性 do : function(){} // 向外提供的方法 } }); //簡化為直接對象字面量的形式: define({ foo : "bar", // 向外提供的屬性 do : function(){} // 向外提供的方法 });module 是factory的第三個參數,為一個對象,上面存儲了一些與當前模塊相關聯的屬性與方法。
module.id 為模塊的唯一標識。
module.uri 根據模塊系統的路徑解析規則得到模塊的絕對路徑。
module.dependencies 表示模塊的依賴。
module.exports 當前模塊對外提供的接口。
官網文檔
倉庫代碼
SeaJS API快速參考
官網(http://seajs.org/)已經關閉。
其define 與 require 使用方式基本就是CMD規范中的示例。
sea.js 核心特征:
遵循CMD規范,與NodeJS般的書寫模塊代碼。
依賴自動加載,配置清晰簡潔。
兼容 Chrome 3+,Firefox 2+,Safari 3.2+,Opera 10+,IE 5.5+。
用來在頁面中加載一個或者多個模塊
// 加載一個模塊 seajs.use("./a"); // 加載模塊,加載完成時執行回調 seajs.use("./a",function(a){ a.doSomething(); }); // 加載多個模塊執行回調 seajs.use(["./a","./b"],function(a , b){ a.doSomething(); b.doSomething(); });AMD 與 CMD 區別
玉伯對于 AMD 與 CMD 區別的解釋:
AMD 是 RequireJS 在推廣過程中對模塊定義的規范化產出。
CMD 是 SeaJS 在推廣過程中對模塊定義的規范化產出。
類似的還有 CommonJS Modules/2.0 規范,是 BravoJS 在推廣過程中對模塊定義的規范化產出
對于依賴的模塊,AMD 是提前執行,CMD 是延遲執行。不過 RequireJS 從 2.0 開始,也改成可以延遲執行(根據寫法不同,處理方式不同)。
CMD 推崇依賴就近,AMD 推崇依賴前置。看代碼:
// CMD define(function(require, exports, module) { var a = require("./a"); a.doSomething(); // 此處略去 100 行 var b = require("./b"); // 依賴可以就近書寫 b.doSomething(); // 代碼... }) // AMD 默認推薦的是 define(["./a", "./b"], function(a, b) { // 依賴必須一開始就寫好 a.doSomething(); // 此處略去 100 行 b.doSomething(); // 代碼... })
雖然 AMD 也支持 CMD 的寫法,同時還支持將 require 作為依賴項傳遞,但 RequireJS 的作者默認是最喜歡上面的寫法,也是官方文檔里默認的模塊定義寫法。
AMD 的 API 默認是一個當多個用,CMD 的 API 嚴格區分,推崇職責單一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,沒有全局 require,而是根據模塊系統的完備性,提供 seajs.use 來實現模塊系統的加載啟動。CMD 里,每個 API 都簡單純粹。
還有一些細節差異,具體看這個規范的定義就好,就不多說了。
另外,SeaJS 和 RequireJS 的差異
UMDUMD
AMD、CMD、UMD 模塊
既然CommonJs和AMD風格一樣流行,似乎缺少一個統一的規范。所以人們產生了這樣的需求,希望有支持兩種風格的“通用”模式,于是通用模塊規范(UMD)誕生了。
(function (root, factory) { if (typeof define === "function" && define.amd) { // AMD define(["jquery"], factory); } else if (typeof exports === "object") { // Node, CommonJS之類的 module.exports = factory(require("jquery")); } else { // 瀏覽器全局變量(root 即 window) root.returnExports = factory(root.jQuery); } }(this, function ($) { // 方法 function myFunc(){}; // 暴露公共方法 return myFunc; })); //復雜、依賴了多個組件并且暴露多個方法 (function (root, factory) { if (typeof define === "function" && define.amd) { // AMD define(["jquery", "underscore"], factory); } else if (typeof exports === "object") { // Node, CommonJS之類的 module.exports = factory(require("jquery"), require("underscore")); } else { // 瀏覽器全局變量(root 即 window) root.returnExports = factory(root.jQuery, root._); } }(this, function ($, _) { // 方法 function a(){}; // 私有方法,因為它沒被返回 (見下面) function b(){}; // 公共方法,因為被返回了 function c(){}; // 公共方法,因為被返回了 // 暴露公共方法 return { b: b, c: c } }));ES6模塊
ES6
Module 的語法
ES6 模塊的設計思想,是盡量的靜態化,使得編譯時就能確定模塊的依賴關系,以及輸入和輸出的變量。CommonJS 和 AMD 模塊,都只能在運行時確定這些東西。比如,CommonJS 模塊就是對象,輸入時必須查找對象屬性。
// ES6模塊 import { stat, exists, readFile } from "fs";
上面代碼的實質是從fs模塊加載3個方法,其他方法不加載。這種加載稱為“編譯時加載”或者靜態加載,即 ES6 可以在編譯時就完成模塊加載。
ES6模塊好處不再需要UMD模塊格式了,將來服務器和瀏覽器都會支持 ES6 模塊格式。目前,通過各種工具庫,其實已經做到了這一點。
將來瀏覽器的新 API 就能用模塊格式提供,不再必須做成全局變量或者navigator對象的屬性。
不再需要對象作為命名空間(比如Math對象),未來這些功能可以通過模塊提供。
擴展閱讀:AMD規范文檔
amdjs 的 require 接口文檔
amdjs 的接口文檔
RequireJS官網接口文檔
模塊系統
前端模塊化開發的價值
前端模塊化開發那點歷史
CMD 模塊定義規范
SeaJS API快速參考
從 CommonJS 到 Sea.js
RequireJS和AMD規范
CommonJS規范
JavaScript模塊化開發 - CommonJS規范
JavaScript模塊化開發 - AMD規范
Javascript模塊化編程1
Javascript模塊化編程2
知乎 AMD 和 CMD 的區別有哪些?
與 RequireJS 的異同
模塊化設計
模塊化
ES6
Module 的語法
來源于:阿賢博客
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/103210.html
摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入匯總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應和斧正,會及時更新,平時業務工作時也會不定期更...
摘要:了解模塊化開發思想如果有軟件工程背景,那么這一思想就是你自身就應該掌握的。玉伯也發表過前端模塊化開發的價值了解目前技術,哪些和模塊化開發沾邊開發功能模塊的時候,可以采用的解決方案。 一、前言 現在javascript的流行,前端的代碼越來越復雜,所以我們需要軟件工程的思想來開發前端。模塊化是必不可少的,這樣不僅能夠提高代碼的可維護性、可擴展性以及魯棒性,更大的好處就是能夠提升整個團隊的...
摘要:我是這一期的主持人黃子毅本期精讀的文章是。模塊化需要保證全局變量盡量干凈,目前為止的模塊化方案都沒有很好的做到這一點。精讀本次提出獨到觀點的同學有流形,黃子毅,蘇里約,,楊森,淡蒼,留影,精讀由此歸納。 這次是前端精讀期刊與大家第一次正式碰面,我們每周會精讀并分析若干篇精品好文,試圖討論出結論性觀點。沒錯,我們試圖通過觀點的碰撞,爭做無主觀精品好文的意見領袖。 我是這一期的主持人 ——...
摘要:前端工程化的演化。前端較為流行的單元測試,等自動化測試自動化測試是軟件通過模擬瀏覽器,對頁面進行操作,判斷是否產生預想的效果。 前端工程化 ??前端工程化的概念在近些年來逐漸成為主流構建大型web應用不可或缺的一部分,在此我通過以下這三方面總結一下自己的理解。 為什么需要前端工程化。 前端工程化的演化。 怎么實現前端工程化。 為什么需要工程化 ??隨著近些年來前端技術的不斷發展,越...
閱讀 1436·2021-09-02 19:23
閱讀 1586·2021-08-11 11:19
閱讀 641·2019-08-30 15:55
閱讀 1652·2019-08-30 12:50
閱讀 2241·2019-08-30 11:23
閱讀 2180·2019-08-29 13:13
閱讀 1500·2019-08-28 18:13
閱讀 3344·2019-08-26 11:53