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

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

主要內容

什麼是模塊化為什麼使用模塊化模塊嵌套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前端知識!

相關焦點

  • 如何在JavaScript中實現模塊化
    今天我和大家談談如何在JavaScript中實現模塊化。那麼如何解決這些問題呢?早期JavaScript採取自執行函數來封裝代碼,但是又會出現文件依賴的問題,所以就是一大堆的問題。JavaScript模塊化就是來解決重名、作用域、文件依賴這些問題的。什麼才是JavaScript的模塊化?
  • 模塊化ups是什麼?哪個牌子的ups最好?
    但是隨著技術的發展,傳統ups已經難以為數據中心帶來穩定的電源供應,模塊化ups憑藉著各種優勢,已經逐漸取代了傳統ups的地位。可能很多人不了解,模塊化ups是什麼,在此我們一起了解一下。這就不得不提華為數字能源推出的模塊化ups產品。作為模塊化ups領域銷量全球領先的品牌,華為數字能源緊貼數據用戶對模塊化ups產品的需求,針對傳統ups產品所存在的痛點,依託自身在電源方面的豐富經驗與領先技術,推出了全系列,可適應於各種場景的模塊化ups解決方案。
  • JavaScript 模塊化的歷史進程
    比如你要搜 「JavaScript 有哪些模塊化方案?它們有什麼區別?」,能得到一萬個有用的結果;但要想知道 「為什麼 JavaScript 有這麼多模塊化方案?它們是誰創建的?」,卻幾乎不可能。因此,這一系列文章內會儘可能的不涉及具體代碼,只談歷史故事。但會在文末提供包含部分代碼的參考連結,以供感興趣的朋友自行閱讀。
  • ES6 常用知識匯總,ES6模塊化如何使用,開發環境如何打包?
    ES6模塊化如何使用,開發環境如何打包?1.模塊化的基本語法/* export 語法 */// 默認導出export default {a: '我是默認導出的',}fn1()fn2()2.開發環境配置BabelES6新語法需要進行編譯,即轉換為ES5或者更早版本的語法,這個時候就需要Babel來進行轉換Babel是什麼
  • 為什麼選擇模塊化建築?
    Jesus Granada Dennis Lo模塊化建築到底是什麼模塊化建築研究所是這一主題的最重要的資源,根據該研究所的說法:「模塊化建築是一個過程,在這一過程中,建築是在非現場且受控的工廠條件下建造的,使用相同的材料,並按照與傳統建築設施相同的規範和標準進行設計,但只需一半的時間」。模塊化建築也有點像一個總稱,它包括了幾種不同類型的建築。
  • 「模塊化面試-2」模塊化是軍事人才測評的主要方式
    中國解放軍陸軍步兵學院教授、紅師教育創始人範進忠首次提出模塊化面試的理論,並將軍隊文職面試屬於模塊化面試。並將其定義概括為:模塊化面試是根據招聘崗位知識和技能需求,將面試標準拆分為多個模塊,建立題庫,制定標準和規範。面試時隨機抽取相關模塊題目進行組合,考生在規定時間內作答。
  • 模塊化組裝多種玩法形態!Airblock模塊化無人機體驗
    模塊化組裝多種玩法形態!前段時間,筆者收到了一款Airblock模塊化無人機,這兩天剛好有時間,於是趕緊拿出來體驗了一番,下面就和大家分享下個人的體驗感受吧。Airblock模塊化無人機  天貓旗艦店售價1199元>>購買連結
  • 何為模塊化?軍隊文職模塊化面試的特色、題型和評分標準
    中國解放軍陸軍步兵學院教授、紅師教育創始人範進忠首次提出模塊化面試的理論,並將軍隊文職面試屬於模塊化面試。並將其定義概括為:模塊化面試是根據招聘崗位知識和技能需求,將面試標準拆分為多個模塊,建立題庫,制定標準和規範。面試時隨機抽取相關模塊題目進行組合,考生在規定時間內作答。
  • 為什麼文職面試是模塊化面試?模塊化面試與結構化面試有什麼不同
    中國解放軍陸軍步兵學院教授、紅師教育創始人範進忠首次提出模塊化面試的理論,並將軍隊文職面試屬於模塊化面試。並將其定義概括為:模塊化面試是根據招聘崗位知識和技能需求,將面試標準拆分為多個模塊,建立題庫,制定標準和規範。面試時隨機抽取相關模塊題目進行組合,考生在規定時間內作答。
  • POS終端智能化發展趨勢研究 模塊化能解決什麼?
    隨著智能作業系統在個人手機與平板電腦上的應用,POS終端同樣可使用定製的智能作業系統,支持靈活的操作界面,能夠與可信安全的外部設備相連。另一方面,智能化還體現在POS將提供唯一的身份標識,並在安全上具備主動風險識別與管理的能力。最後,智能化POS將提供以往不具備或者不足的數據服務。
  • 模塊化面試-9丨模塊化面試&結構化面試的優點及缺陷
    中國解放軍陸軍步兵學院教授、紅師教育創始人範進忠首次提出模塊化面試的理論,並將軍隊文職面試屬於模塊化面試。並將其定義概括為:模塊化面試是根據招聘崗位知識和技能需求,將面試標準拆分為多個模塊,建立題庫,制定標準和規範。面試時隨機抽取相關模塊題目進行組合,考生在規定時間內作答。
  • 模塊化設備是真的可行還是炒作概念?
    我們都知道,模塊化技術能夠讓我們通過給設備更換模塊來滿足自己各個方面的不同需求。通常情況下,電子設備推出新版本之後,消費者都會考慮是否應該購買,但是,模塊化設備並不存在這樣的問題,想要體驗什麼新功能都可以通過相應的模塊來實現。
  • 模塊化面試-13丨軍隊文職全新的模塊化面試概念,該如何應對?
    中國解放軍陸軍步兵學院教授、紅師教育創始人範進忠首次提出模塊化面試的理論,並將軍隊文職面試屬於模塊化面試。並將其定義概括為:模塊化面試是根據招聘崗位知識和技能需求,將面試標準拆分為多個模塊,建立題庫,制定標準和規範。面試時隨機抽取相關模塊題目進行組合,考生在規定時間內作答。評委根據答題情況跟進提問,對人崗匹配度做出準確、客觀的評價。
  • FB收購模塊化電子產品公司 谷歌放棄模塊化手機
    北京時間9月20日上午消息,Facebook已經收購了模塊化消費電子產品初創公司NascentObjects,以加快其秘密的硬體實驗室Building8的生產進程。該消息已得到NascentObjects和Building8主管雷吉納·杜甘(ReginaDugan)的證實。
  • 什麼是工業4.0模塊化加工生產線?
    在2016年漢諾瓦工業博覽會上,Bosch Rexroth公司讓參展觀眾真實目睹了聯網生產解決方案的靈活和高效,該公司藉助一條由5個獨立工作站組成的生產線演示了如何通過製造執行系統SAP-ME實現加工控制。怎樣保持企業未來的活力?如何才能從數位化中獲得實實在在的好處?
  • 模塊化面試-12丨軍隊文職模塊化面試的高分關鍵
    中國解放軍陸軍步兵學院教授、紅師教育創始人範進忠首次提出模塊化面試的理論,並將軍隊文職面試屬於模塊化面試。並將其定義概括為:模塊化面試是根據招聘崗位知識和技能需求,將面試標準拆分為多個模塊,建立題庫,制定標準和規範。面試時隨機抽取相關模塊題目進行組合,考生在規定時間內作答。評委根據答題情況跟進提問,對人崗匹配度做出準確、客觀的評價。
  • Blocks 模塊化智能手錶
    前言Blocks 是由英國的一家可穿戴設備初創公司提出的一款和Google 的模塊化手機 Project Ara 概念類似的模塊化手錶,你可以根據自己的需求,選擇相應的模塊來定製它,可以說是一款完全 Freedom of Choice 的手錶。
  • 從步槍到航母甚至部隊改造,現在流行的「模塊化」究竟是什麼意思
    【軍武次位面】作者:liutang2020如今,我們經常在各種軍事消息中看到「模塊化」這個詞。什麼是模塊化?模塊化在軍事領域有哪些應用?這就是我們本次討論的內容了。1962年,美國管理學大師赫伯特·西蒙首次提出了「模塊化」(modularity)的概念。
  • 掙脫束縛 百諾獵鷹MK1模塊化攝影組合套裝
    WB1腰帶作為百諾獵鷹MK1模塊化攝影組合套裝的基礎型配件設計有WB1S、WB1L兩款尺寸用來滿足不同身材使用者的需求。WB1S長度81-101cm、WB1L長度為101-122cm。WB1腰帶,利用模塊化的構造,有效的緩解了背部的受力,把重力分散在腰部。加寬加厚的設計,配合優質的EVA及海綿填充物,使您即使在帶齊全套器材出行,仍能感到輕便,舒適。腰帶上均使用UTX優質扣具,以確保器材的安全。
  • 模塊化手機圖賞 MOTO Z與LG G5誰才是模塊化之王?
    智慧型手機模塊化之路走著並不平坦,看看MOTO Z跟LG G5究竟誰才是模塊化之王?LG G5可拆卸電池是一大亮點,奈何電池容量太小,加上2K屏幕,續航簡直尿崩,而MOTO Z則是更加內置電池,可是它有個電池模塊可增加,這一點MOTO Z略勝。