什麼是模塊化?如何使用模塊化?

2020-12-27 尚學堂前端學院

主要內容

什麼是模塊化為什麼使用模塊化模塊嵌套Requirejs使用學習目標

第一節 什麼是模塊化

1.1 模塊化產生

模塊化發展歷程

js一開始並沒有模塊化的概念,直到ajax被提出,前端能夠像後端請求數據,前端邏輯越來越複雜,就出現了許多問題:全局變量,函數名衝突,依賴關係不好處理。當時使用子執行函數來解決這些問題,比如經典的jquery就使用了匿名自執行函數封裝代碼,將他們全都掛載到全局變量jquery下邊

在js出現的時候,js一般只是用來實現一些簡單的交互,後來js開始得到重視,用來實現越來越複雜的功能,而為了維護的方便,我們也把不同功能的js抽取出來當做一個js文件,但是當項目變的複雜的時候,一個html頁面可能需要加載好多個js文件,而這個時候就會出現各種命名衝突,如果js也可以像java一樣,把不同功能的文件放在不同的package中,需要引用某個函數或功能的時候,import下相關的包,這樣可以很好的解決命名衝突等各種問題,但是js中沒有模塊的概念,又怎麼實現模塊化呢

模塊化開發是一種管理方式,是一種生產方式,一種解決問題的方案,一個模塊就是實現特定功能的文件,有了模塊,我們就可以更方便地使用別人的代碼,想要什麼功能,就加載什麼模塊,但是模塊開發需要遵循一定的規範,否則就都亂套了,因此,才有了後來大家熟悉的AMD規範,CMD規範

1.2為什麼使用模塊化

使用模塊化可以給我們帶來以下好處

解決命名衝突提供復用性提高代碼可維護性靈活架構,焦點分離,方便模塊間組合、分解 多人協作互不幹擾 1.3 js作用域

Js的作用域是函數作用域

代碼:var name='zhangsan';//全局function demo(){var name='lisi';//局部}for(var i=0;i<100;i++){var age=10;//全局}//下面代碼執行的結果?var arr=[10,20,30,40,50];for(var i=0;i<arr.length;i++){arr[i]=function(){console.log(i);}}arr[2]();//列印結果?

結果分析:

怎麼獲取當前的下標對應的數據

//閉包解決 變量作用域問題---var arr=[10,20,30,40,50];for(var i=0;i<arr.length;i++){arr[i]=(function(i){return function(){console.log(i);}})(i);}arr[3]();//列印結果?

本章作業

1.什麼是模塊化

2.為什麼使用模塊化

3.js作用域問題怎麼解決

第二節 模塊化實現

2.1 模塊的出現

//對象問題var obj={name:'lilei',age:20}//需求:我要修改對象的值obj.name='zhaos' //思考這樣修改方式合理嗎???

如果這是一個公共類,公共的屬性和方法,大家都去修改,誰想修改就去修改,這樣就亂了,這樣不合理,我們應該統一修改。

一個公共類我應該是統一修改 或者是統一不修改

2.1.1初步優化方案

思路:把這個對象 封裝一個方法

//寫一個函數 自執行函數 外部不能訪問我的內部內容--創建一個自執行函數(function(){var obj={name:'lisi',age:20}})();console.log(obj);

這樣我們就不能訪問了,但是也不可能寫了方法 不再外部使用,再次優化,我們給外部提供一個修改方案

2.1.2再次優化

//提供外部訪問方式var module=(function(){var obj={name:"lilei",age:20}function setName(value){obj.name=value;console.log(obj.name)}return setName;})();//注意:這是自執行函數,進入直接執行,沒有辦法調用,所以呢我們可以給一個名字// 然後去調用return的結果module('zhangsan');

2.1.3 優化

//上面調用 不好看 不直接 不知道修改的什麼var module=(function(){var obj={name:"lilei",age:20}function setName(value){obj.name=value;console.log(obj.name)}return {setName:setName};})();module.setName('huahua');

2.1.4修改和獲取

var module=(function(){var obj={name:"lilei",age:20}function setName(value){obj.name=value;}function getName(){return obj.name;}return {setName:setName,getName:getName};})();console.log(module.getName());console.log('---------------------');module.setName('huahua');console.log(module.getName());

這時候就有統一標準,誰調用或者修改這個代碼就可以看到,調用這個方法知道那個方法。

總結:這樣比隨便修改這個值要好很多,我們寫的代碼就被為模塊

我們通過模塊把我們的代碼整理和隔離,這樣我們以後寫的功能 公共的使用的方法或者模塊就可以這樣寫,對代碼進行隔離,模塊之前這樣不能直接互相通信,實現隔離

2.1.5 模塊和模塊化區別?

模塊:是用於在項目中劃分相對獨立的功能,模塊更偏重邏輯上區分

模塊化:是從代碼邏輯的角度進行劃分的,方便代碼分層開發,保證每個公能模塊的職能單一

2.2 模塊實現

<!-- 獲取元素---設置元素--用模塊寫 --><div id="box"></div><script>var moduleDOM=(function(){//1.獲取內容function getElement(id){return document.getElementById(id);}//2.設置function setElement(id,value){getElement(id).innerHTML=value;}return {getElement:getElement,setElement:setElement}})();//獲取元素console.log(moduleDOM.getElement('box'));moduleDOM.setElement('box','hello');var content='<h2>我是一個測試數據</h2>';moduleDOM.setElement('box',content);</script>

2.3 模塊的嵌套

如果一個模塊很大,必須分成幾個部分,或者一個模塊需要繼承另一個模塊,這時就有必要採用"放大模式"(augmentation)

/*模塊的嵌套 模塊之前是獨立的 不能直接相互訪問*/var domElement=(function(){function getElement(id){return document.getElementById(id);}return {getElement:getElement}})();var divMoudle=(function(domElement){function setName(id,value){return domElement.getElement(id).innerHTML=value;}return {setName:setName}})(domElement);divMoudle.setName('root','hello!!');

【代碼演示】

模塊的嵌套 實現在當前的模塊使用其他模塊裡面的方法---傳遞進入//傳遞一個jquery 比如下面使用jquery對象var domElement=(function(){function getElement(id){return document.getElementById(id);}return {getElement:getElement}})();var divMoudle=(function(domElement,$){function setName(id,value){return domElement.getElement(id).innerHTML=value;}console.log($);return {setName:setName}})(domElement,$);//jQuerydivMoudle.setName('root','hello!!');

2.4 模塊的放大模式

在瀏覽器環境中,模塊的各個部分通常都是從網上獲取的,有時無法知道哪個部分會先加載。如果採用上一節的寫法,第一個執行的部分有可能加載一個不存在空對象,這時就要採用"寬放大模式",這樣一個比較完整的模塊也就出來了

如果這時候有個人把 獲取元素的模塊置空了,domElement=null;

//模塊的放大模式 模塊的寬大模式 容錯處理var domElement=(function(){function getElement(id){return document.getElementById(id);}return {getElement:getElement}})();domElement=null;var divMoudle=(function(domElement,$){//判斷domElement是否存在if(domElement){function setName(id,value){return domElement.getElement(id).innerHTML=value;}console.log($);return {setName:setName}}else{console.log('domElement對象不存在')}})(domElement,$);//jQuerydivMoudle.setName('root','hello!!');

上面咱們寫的模塊化是很古老的一種寫法

現在我們寫模塊化,藉助於requirejs

Requirejs給大家演示使用方案,在前幾年很多人用的,這2年隨著vue react的框架層出不窮,而且越來越好,現在requrejs的現在使用的人在逐漸減少,但是他的思維方式和寫代碼的方式方法,還是很值得大家思考的。

有個好的詞彙:組件化和模塊化 多模塊化思想(組件化就是vue 模塊化就是requirejs給我們提供的一種思想,其實這兩個沒有太大區別)

本章作業

1.模塊化實現獲取和設置本地元素

2.模塊化的放大模式

第三節requirejs

3.1 模塊化規範的產生

在模塊化規範形成之前,JS開發者使用Module設計模式來解決JS全局作用域的汙染問題。Module模式最初被定義為一種在傳統軟體工程中為類提供私有和公有封裝的方法。在JavaScript中,Module模式使用匿名函數自調用 (閉包)來封裝,通過自定義暴露行為來區分私有成員和公有成員。

var myModule = (function (window) {var moduleName = 'module' // private// publicfunction setModuleName(name) {moduleName = name}function getModuleName() {return moduleName}return { setModuleName, getModuleName } // 暴露行為})(window)

上面例子是Module模式的一種寫法,它通過閉包的特性打開了一個新的作用域,緩解了全局作用域命名衝突和安全性的問題。但是,開發者並不能夠用它來組織和拆分代碼,於是乎便出現了以此為基石的模塊化規範。

RequireJS是一個JavaScript文件或者模塊的加載器。它可以提高JavaScript文件的加載速度,避免不必要的堵塞。它針對於在瀏覽器環境中使用做過專門的優化,但它也可以在其他的JavaScript環境中使用,像Node.js一樣可以在伺服器上運行

3.2為什麼要用require.js

最早的時候,所有Javascript代碼都寫在一個文件裡面,只要加載這一個文件就夠了。後來,代碼越來越多,一個文件不夠了,必須分成多個文件,依次加載。下面的網頁代碼,相信很多人都見過。

<script src="1.js"></script>  <script src="2.js"></script>  <script src="3.js"></script>  <script src="4.js"></script>  <script src="5.js"></script>  <script src="6.js"></script>

這段代碼依次加載多個js文件。

這樣的寫法有很大的缺點。首先,加載的時候,瀏覽器會停止網頁渲染,加載文件越多,網頁失去響應的時間就會越長;其次,由於js文件之間存在依賴關係,因此必須嚴格保證加載順序(比如上例的1.js要在2.js的前面),依賴性最大的模塊一定要放到最後加載,當依賴關係很複雜的時候,代碼的編寫和維護都會變得困難。

require.js的誕生,就是為了解決這兩個問題:

(1)實現js文件的異步加載,避免網頁失去響應;

(2)管理模塊之間的依賴性,便於代碼的編寫和維護

(3)命名衝突

3.3 requrejs官網

其實用requirejs就是推薦我們在寫代碼的時候,推薦我們使用模塊化的方式去寫我們的js

目錄解構

js

apps:index.js … 自己定義的js文件

libs:requirejs文件

main.js 配置文件路徑 入口函數

index.html

3.4 使用步驟

1.引入 requirejs

<scrpt data-main=』js/main.js』 src=』js/libs/rrquire.js』></script>

2.創建入口文件:main.js

requirejs.config({baseUrl:』js/』,//基礎路徑配置 paths:{ 「index」:」apps/index」, 「demo」:」apps/demo」}})requirejs([「index」,」demo」,function(index,demo){}]);

代碼效果:

3.引入jquery文件

文件加載效果

注意:創建的文件需要main.js加載 否則不能使用

本章作業

1.理解模塊化的由來

2.requirejs使用的好處

3.如何使用requirejs步驟

第四節 實例

4.1 Requirejs模塊

Js中文件與文件之前是不隔離的,可以相互訪問的,但是我們希望文件是隔離的,不能隨意訪問的,提供訪問方案

4.1.1 定義模塊 簡單名稱/價值對

如果模塊沒有任何依賴關係,並且它只是一個名稱/值對的集合,那麼只需將對象文字傳遞給define():

define({color: "black",size: "unisize"});

4.1.2定義函數

define(function() {return {color: "black",size: "unisize"}});

4.1.3 具有依賴關係的定義函數

如果模塊具有依賴關係,則第一個參數應該是一個依賴關係名稱數組,第二個參數應該是一個定義函數。一旦所有依賴關係被加載,該函數將被調用來定義模塊。該函數應該返回一個定義模塊的對象。依賴關係將被傳遞給定義函數作為函數參數,其順序與依賴關係數組中的順序相同

define(['data'],function(data){console.log(data)})

注意:依賴注入 (想使用data文件 注入data裡面就好了,哪裡使用注入就好了) 依賴前置

4.1.4 定義與簡體CommonJS的包裝一個模塊

如果您希望重用一些以傳統CommonJS模塊格式編寫的代碼,可能難以重新使用上面所使用的依賴關係數組,並且您可能希望將依賴項名稱直接對齊到用於該方法的本地變量依賴(nodejs的模塊化)

define(function(require,exports,module){var data=require("data"); console.log(data)})

這是什麼時候使用什麼時候引用 (依賴就近)

其他的定義模塊使用我們不再去看 我們常用這四種定義方式

4.1.5 獲取dom元素

創建一個DOMElement.js:

define(['jquery'],function(){//定義函數 function setHtml(className,value){ $("."+className).html(value); } return { setHtml:setHtml }})

Index.js

define(["data",'DOMElement'], function(data,DOMElement) {console.log(data); DOMElement.setHtml('box','hello world'); });

4.2 requirejs網易雲音樂

實現 網易雲音樂數據列表展示,點擊音樂播放

步驟

1. 目錄結構創建

2. main.js入口文件

3.http.js

4.index.js

5.config文件

6.view.js顯示視圖

7.點擊音樂列表音樂播放 view.js

4.3 Requirejs的shim

Requirejs所有文件都是define() ,引入第三種也是這種寫法?不是

為什麼jquery可以,Requirejs支持jquery的使用,但是很多第三方插件不支持,使用shim

實例:swiper第三方使用

代碼:

目錄結構:

Index.js

Main.js

Index.js

Index.html

4.4 模塊化規範

AMD 是 RequireJS 在推廣過程中對模塊定義的規範化產出CMD是SeaJS在推廣過程中對模塊化定義的規範化產出區別:

對於依賴的模塊,AMD是提前執行,CMD是延遲執行。不過RequireJS從2.0開始,也改成了可以延遲執行(根據寫法不同,執行的方式不同)CMD推崇就近依賴,AMD推崇依賴前置。看代碼//CMD的方式define(function(require,exprots,module){var a = require('./a');a.dosmting();//省略1W行var b = require('./b');b.dosmting();})

//AMD的方式define(['./a','./b'],function(a,b){a.dosmting();//省略1W行b.dosmting();})

以上AMD的寫法是官方推崇的方式,但是同時也支持CMD的寫法

AMD和CMD最明顯的區別就是在模塊定義時對依賴的處理不同AMD推崇依賴前置,在定義模塊的時候就要聲明其依賴的模塊CMD推崇就近依賴,只有在用到某個模塊的時候再去require

本章作業

1.requirejs的定義方式

2.requirejs網易雲實例

3.requirejs導入第三方插件

本文由尚學堂前端學院原創,歡迎關注,帶你一起學習Web前端知識!

相關焦點

  • 為什麼選擇模塊化建築?
    Jesus Granada Dennis Lo模塊化建築到底是什麼模塊化建築研究所是這一主題的最重要的資源,根據該研究所的說法:「模塊化建築是一個過程,在這一過程中,建築是在非現場且受控的工廠條件下建造的,使用相同的材料,並按照與傳統建築設施相同的規範和標準進行設計,但只需一半的時間」。模塊化建築也有點像一個總稱,它包括了幾種不同類型的建築。
  • 單片機模塊化編程的原則有哪些
    模塊化編程可解決這個問題,我們只要根據實際需要使用模塊化編程的思維將具有不同功能的程序封裝在不同模塊中,將各個不同模塊存放在不同的 c 文件中。 模塊化編程後的程序不但使整體的程序功能結構清晰明了,同時也提高程序代碼的利用率,有些模塊代碼我們可以直接進行移植或者經簡單修改就可另作他用,好比封裝好的函數。
  • 基於橋式起重機的電氣模塊化設計
    起重機電氣模塊化設計的理念源於模塊化設計的理念,起重機電氣設計涉及眾多元器件的選型、控制電路設計,容量校驗,控制櫃的設計等,應用模塊化的理念,將各部分進行模塊化設計,減少不必要的重複性設計工作,提高設計效率,而模塊化後形成標準產品,可縮短製造周期,降低製造費用。
  • Apple隱藏的模塊化手機
    已經形成一個隱藏的系列:——模塊化手機。5、5s、SE同時可以擁有2天重度使用的超長待機。如果你喜歡用手機看書還可以敗個InkCase i5的墨水屏後蓋。增強續航的同時,還保護眼睛。同樣是這兩天老媽幫收拾了雜物一時找不出來實拍。
  • LG G6曝光:不玩模塊化 配置強到發指
    模塊化手機谷歌在玩、LG在玩,聯想MOTO也在玩。LG是玩的最認真的,都拿旗艦來試水,結果G5市場叫聲很好,賣的很悲催。真是諾基亞太保守倒了,G5太激進扯d了。 LG G5配置是旗艦級的,高通驍龍820+4GB+32GB,5.3英寸2K屏幕,後置1600+800萬雙攝,最重要是G5的模塊化設計很有噱頭,號稱可以任意組合應用零件使用。然而沒有什麼人買帳,其一是零件成本太貴,其二是模塊化設計不完善,據使用報告,G5零件更換會經常接觸不良,其三手機是便捷的使用工具,不是我們把玩高貴藏品。目前G5行貨3000左右。
  • 單片機C語言模塊化編程方法
    像這些場合就要求程序必須模塊化。模塊化的好處是很多的,不僅僅是便於分工,它還有助於程序的調試,有利於程序結構的劃分,還能增加程序的可讀性和可移植性。初學者往往搞不懂如何模塊化編程,其實它是簡單易學,而且又是組織良好程序結構行之有效的方法之一.本文將先大概講一下模塊化的方法和注意事項,最後將以初學者使用最廣的keil c編譯器為例,給出模塊化編程的詳細步驟。
  • 模塊化鋰電池解決方案提高動力電池能量利用效率
    模塊化鋰電池解決方案提高動力電池能量利用效率。模塊化電池系統是驅動機構最為重要的組成部分,也是這項技術的基礎。模塊化鋰電池系統旨在提供動力電池的可擴展性和配置靈活性,模塊化電池系統能夠滿足商用車製造商的要求,即使是小批量生產,也是一款性價比很高的解決方案。
  • 前海打造可移動模塊化廚房
    可移動模塊化廚房可以保障工地工人「舌尖上的安全」。 【深圳商報訊】(記者 苑偉斌 實習記者 餘晴暉 文/圖)12月25日,前海二單元五街坊06、07、08地塊項目開工暨前海首批可移動模塊化廚房正式啟用,中建四局深圳總承包公司獲頒「可移動模塊化廚房」食品經營許可證。
  • 宏碁Revo Build模塊化PC首測
    它有各種各樣的造型,可能是航天飛船,可能是飛機大炮,也可能會是某個動畫人物,但是萬變不離其宗,它們都是一層一層疊加起來的,大家可能要疑問了,這明明是一個臺式機文章,怎麼成了樂高玩具專場!朋友們不要誤會,這與小編這次給大家介紹的模塊化臺式機很有關係,它就是宏碁Revo Build M1-601,也是像玩具一樣一層一層蓋起來。接下來就跟著小編一起來看看這個富有創意的新產品吧。
  • Pico System III評論:有趣且簡化的模塊化合成器入門
    在$ 529(用於桌面型)系統III不是一個衝動購買,但它是它是什麼合理實惠。而且,與Volca Modular或0-Coast一樣,它具有讓您能夠探索West Coast合成的附加好處,而入門價格也往往較高。值得注意的是,Erica Synths剝奪了System II的許多功能以達到這個價格。
  • 前海打造可移動模塊化廚房 保障「舌尖上的安全」
    讀創/深圳商報記者 苑偉斌 實習記者 餘晴暉 12月25日,前海二單元五街坊06、07、08地塊項目開工暨前海首批可移動模塊化廚房正式啟用,中建四局深圳總承包公司獲頒「可移動模塊化廚房」食品經營許可證。
  • 前海「可移動模塊化廚房」來了
    現場,前海首個「可移動模塊化廚房」宣布正式投入使用。深圳市委常委、前海蛇口自貿片區管委會主任黃敏等領導出席開工儀式。據悉,「可移動模塊化廚房」以貨櫃為基礎,內置標準化廚具構成洗菜、切配、加工、備餐等單功能或多功能模塊,可根據人數、場地大小靈活增減模塊,滿足不同的就餐場景需求。
  • Exyte聯合Univercells Technologies推出模塊化、集成式技術
    Exyte 提供了新型 ExyCell® 模塊化技術,可支持快速建設符合現行藥品生產管理規範(cGMP)的生物製藥設施。 德國斯圖加特和布魯塞爾2020年5月19日 /美通社/ --高科技設施領域設計和建造的全球先鋒企業 Exyte(益科德)和 Univercells Technologies 聯合宣布建立全球合作夥伴關係,將共同優化 GMP 標準疫苗生產設施的模塊化、標準化及靈活建造。
  • LG G6遭遇出師未捷,是誰給「模塊化手機」潑了冷水?
    LG計劃於明年CES大展上推出新一代旗艦機:LG G6,從目前曝光出的消息來看,G6將依然延續前代G5的模塊化設計,並支持無線充電和防水等「黑科技」加身。然而在外媒展開的用戶調查中,50.51%的用戶沒有意願購買採用模塊化設計的LG G6,僅有9.44%的用戶完全肯定了模塊化設計。看到這組數據,恐怕此時那些主打「模塊化」的廠商內心都是崩潰的。
  • 模塊化平臺讓造車成了「搭積木」,但為什麼罵「套娃臉」的少了?
    繼而又出現了更加簡單高效的生產模式——模塊化。而目前出現的「模塊化平臺」,比「平臺化」更進了一步。從福特的流水線生產到豐田的精益生產,最後發展到今天的模塊化概念,汽車的生產模式可以說經歷了三次大變革。簡單來說,多款車型共用一個框架,即是平臺化的概念;在此基礎上,如果能夠把各個功能形成總成,像「搭積木」一樣搭起來,這便是模塊化平臺了。話說回來,儘管平臺、模塊這些詞看起來高大上,但核心目的還是省錢和省時間(還是省錢)。
  • 小米模塊化相機專利曝光:後置鏡頭可秒變前置相機
    從專利圖可知,在手機的後置相機模組中採用了模塊化設計,通過磁力懸掛的方式進行連接,同時,後置攝像頭模塊還配有多個鏡頭。據悉,在正常模式下,該相機模塊安裝在手機背部,用於後置拍攝,當需要使用自拍或視頻通話功能時,用戶可將鏡頭模塊拆卸下來,安裝至手機頂端作為前置鏡頭使用。
  • 宏昌科技:形成模塊化組件,部件適配度高
    隨著家電企業對生產效率的愈發重視,模塊化組件研發創新和模塊化供貨模式逐漸成為家電配件行業發展方向之一,尤其是在洗衣機、淨水器等製造領域。  浙江宏昌電器科技股份有限公司是高新技術企業、國家智慧財產權優勢企業,宏昌科技的磁感控制器研究院於2019年被認定為省級企業研究院。
  • 新型火箭炮「亮劍」第74集團軍 模塊化全覆蓋「天火」烈焰
    近日,隸屬於南部戰區第74集團軍公眾號發布了2021年首訓的精彩圖集,其中作為背景的國產新型模塊化火箭炮無疑「搶」足風頭。這款代號為PHL-16的神秘武器自2019年閱兵上驚豔全球後便「銷聲匿跡」,這次「露面」是PHL-16的第二次亮相,也是首次官宣「入伍」列裝。
  • 宏都拉斯,羅阿坦島Próspera模塊化住宅
    扎哈團隊與AKT II合作,設計方法從全面了解當地供應鏈、物流和施工技術開始,以促進使用支持該地區經濟的當地材料、工藝和製造設施。通過將最先進的模塊化建築技術與可持續來源的當地材料相結合,這些第一批住宅的設計和規劃就是世界各地發展技術轉變的一個例子。
  • 一槽多用,廚房新寵兒,美仕傑模塊化集成水槽體驗!
    我也是在同事的介紹下,聽到美仕傑這款廚房模塊化集成水槽的,主要是它一槽多用就很心水,而且集洗碗機+淨水器+垃圾處理器於一身,那麼下單等待到貨給父母驚喜了!這就是美仕傑的模塊化集成水槽了,跟想像的差不多,顏值也很高。它的特點就是配備五大模塊集七大功能件,在購買一樣集成產品的情況下實現傳統幾樣甚至更多產品的功能使用。