模塊化開發

  1. 什么是模塊化?

模塊化就是講js文件按照功能分離,根據需求引入不同的文件中。源于服務器端。

js模塊化方案有AMD/CommonJS/ES6 Module等

使用webpack模塊的各種方式的依賴關系:

  • ES2015 import語句
  • CommonJS require()語句
  • AMD define 和 require語句
  • css/sass/less文件的 @import 語句
  • 樣式 (url(...)) 或 HTML文件(<img src=...>) 中的圖片鏈接(image url)

webpack的優勢

  • 支持CommonJS 和 AMD 模塊。
  • 支持模塊加載器和插件機制,可對模塊靈活定制。babel-loader支持ES6
  • 可以通過配置,打包成多個文件。有效的利用瀏覽器的緩存。
  • 將樣式文件和圖片等靜態資源視為模塊進行打包。配合loader加載器,對資源進行處理。

JavaScript模塊規范共有兩種:CommonJS 和 AMD。
為什么要有模塊?
有了模塊,我們就可以方便的使用別人的代碼,想要什么功能,就加載什么模塊。
一、CommonJS
用于服務端模塊化編程:
一個文件就是一個模塊,require方法用來加載模塊,該方法讀取一個文件并執行,最后返回文件內部的module.exports對象;
require是默認讀取 .js 文件,所以require(模塊名)可以不寫后綴;
同步加載,由于服務端加載的模塊一般在本地,所以可以這樣;但是客戶端如果一個模塊過大就會導致頁面“假死”;

node.js的項目,將JavaScript語言用于服務器編程,在瀏覽器環境下,沒有模塊也是可以的。但在服務器端,一定要有模塊,與操作系統和其他應用程序互動,否側就沒法編程。
node.js的模塊系統,就是參考CommonJS規范實現的。在CommonJS中,有一個全局性的方法require(),用于加載模塊。假定有一個數學math.js,就可以像下面這樣加載。

var math = require('math');
然后,就可以調用模塊提供的方法;

var math = require('math');
math.add(2,3); //5

module.exports屬性表示當前模塊對外輸出的接口,其他模塊文件加載該模塊,實際上就是讀取module.exports變量;為了方便用exports,exports指向module.exports;即exports = module.exports = {};
exports.xxx相當于在導出的對象上添加屬性,該屬性對調用模塊可見;
exports = 相當于給exports重新賦值,這樣就切斷了和module.exports的關聯,調用模塊就不能訪問exports的對象及其屬性。
在瀏覽器環境:
CommonJS不使用于瀏覽器環境。如果在瀏覽器中運行,會有一個大問題;

var math = require('math');
math.add(2,3)

在第二行math.add(2,3),在第一行require('math')之后運行,因此必須等math.js加載完畢。如果加載時間很長,整個應用就會停在這里。
這對服務器不是問題,因為所有的模塊都存在本地硬盤,可以同步加載完成,等待時間就是硬盤的讀取時間。但是,在瀏覽器,因為模塊都在服務器端,等待時間取決于網速的快慢,可能要等很長時間,瀏覽器處于“假死”狀態。
因此,瀏覽器端的模塊,不能采用“同步加載”,只能采用“異步加載”。這就是AMD的產生的背景。

二、AMD
AMD是“Asynchronous Module Definition”的縮寫,意思是“異步模塊定義”。它采用異步方式加載模塊,模塊的加載不影響它后面的語句的運行。所有依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成之后,這個回到函數才會運行。
AMD也采用require()語句加載模塊,但是不同于CommonJS,它要求兩個參數,
require([module],callback);
第一個參數[module],是一個數組,里面的成員就是要加載的模塊,第二個參數callback,則是加載成功之后的回調函數。如果將前面的代碼改寫成AMD形式,就是下面的形式:

require(['math'],function(math){
    math.add(2,3);
})

math.add()與math模塊加載不是同步的,瀏覽器不會發生‘假死’。所以AMD比較適合瀏覽器環境。

三、require.js的用法:
require.js(前端模塊化管理的工具庫)實現js文件的異步加載,避免網頁失去響應;管理模塊之間的依賴性,便于代碼的編寫和維護。
主模塊的寫法:
main.js稱為是“主模塊”,意思是整個網頁的入口代碼。所有的代碼都從這開始運行。主模塊依賴于其他模塊,這時就使用AMD規范定義的require()函數。

//main.js
require(['moduleA','moduleB','moduleC'],function(moduleA, moduleB, moduleC){
//some  code here
});

require()函數接受兩個參數。第一個參數是一個數組,表示所依賴的模塊,
上例就是['moduleA','moduleB','moduleC'],即主模塊依賴這三個模塊;
第二個參數是一個回調函數,當前面指定的模塊都加載成功后,它將被調用。
加載的模塊會以參數形式傳入該函數,從而在回調函數內部就可以使用這些模塊。
require()異步加載moduleA,moduleB和moduleC,瀏覽器不會失去響應;它指定的回調函數,只有前面的模塊都加載成功后,才會運行,解決了依賴的問題。
假定主模塊依賴jquery、underscore和backbone三個模塊,main.js就可以這樣寫:

require(['jquery','underscore','backbone'],function($,_,Backbone){

//some code here
})

require.js是先加載jQuery、underscore和backbone,然后在運行回調函數。主模塊的代碼就寫在回調函數中。

四、模塊的加載
主模塊的依賴模塊是['jquery','underscore','backbone']。默認情況下,require.js假定這三個模塊于main.js在同一個目錄,文件名分別是jquery.js、underscore和backbone.js,然后自動加載。
使用require.config()方法,我們可以對模塊的加載行為進行自定義。require.config()就寫在主模塊(main.js)的頭部。參數就是一個對象,
這個對象的paths屬性指定各個模塊的加載路徑。

require.config({
    paths:{
        "jquery":"jquery.min",
        "underscore":"underscore.min",
        "backbone":"backbone.min"
    }
});

上面的代碼路徑默認與main.js在同一個目錄(js子目錄)。如果這些模塊在
其他目錄,比如js/lib目錄,則有兩種寫法:
一種是逐一指定路徑。

require.config({
    paths:{
        "jquery":"lib/jquery.min",
        "underscore":"lib/underscore.min",
        "backbone":"lib/backbone.min"
    }
});

另一種則是直接改變基目錄(baseUrl)

require.config({
    baseUrl:"js/lib",
    paths:{
        "jquery":"jquery.min",
        "underscore":"underscore.min",
        "backbone":"backbone.min"
    }
});

如果某個模塊在另一臺主機上,也可以直接指定它的網址,比如,

    require.config({
        path:{
            "jquery":
            "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"
        }
    })

require.js要求,每一個模塊是一個單獨的js文件。這樣的話,如果加載多個
模塊,就會發出多次HTTP請求,會影響網頁的加載速度。因此,require.js提供一個優化工具,
當模塊部署完畢以后,可以用這個工具將多個模塊合并在一個文件中,減少http請求。

在前端開發中,最先出現在node.js中,common.js中(module.exports和require)隨著web應用的模塊化,在瀏覽器端頁是需要進行模塊化開發,早期AMD,CMD規范,代表Require.js和sea.js。在es6中,提出了原生模塊呼哈的解決方案,就是export和import但是瀏覽器并沒有完全支持,需要借助一些工具,--babel,實現這個轉換的有browserify和webpack。

在node.js中,模塊就是一個文件,通常js、json文件,包是多個模塊的集合,類似文件夾。
模塊化通俗點的理解就是這樣:就像我們小時候拼積木一樣。我們想拼一個房子出來,我們不是一下子從低到頂逐漸的拼出來。而是我們把一個橫條,豎條,圓圈等拼湊在一起,形成一個窗戶,一面墻,房頂等等部件。這些部件就如同是一個個模塊一樣。具備一定的功能,可以單獨分開使用。不同的框架和庫的模塊,有很多功能類似,可以理解為你的積木是塑料的,他的是木頭的,只要接口Api可以對的上,那么也可以通用。

  1. Node.js中的模塊:Angular.js中的模塊:React.js中的模塊:有何異同?

nodejs里的模塊,就是一個文件,通常js、json文件。

Angularjs里的模塊就是一系列配置和代碼塊的集合,它們是在啟動階段就附加到應用上的。一個最簡單的模塊由兩類代碼塊集合組成的:

配置代碼塊 - 在注入提供者注入和配置階段執行。只有注入提供者和常量可以被注入到配置塊中。這是為了防止服務在被配置好之前就被提前初始化。
運行代碼塊 - 在注入器被創建后執行,被用來啟動應用的。只有實例和常量能被注入到運行塊中。這是為了防止在運行后還出現對系統的配置。

Reactjs里的模塊/組件:就是將一段js、html、css組合在一起,形成有一定功能的代碼片段

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。