JS模組化

冰大墩發表於2022-12-04

程式碼:https://github.com/zhengyeye/JS-modularity

什麼是模組、模組化?

將一個複雜的程式依據一定的規則(規範)封裝成幾個塊(檔案), 並進行組合在一起;

塊的內部資料/實現是私有的, 只是向外部暴露一些介面(方法)與外部其它模組通訊。

為什麼要模組化?

當專案功能越來越多,程式碼量便也會越來越多,後期的維護難度會增大,此時在JS方面就會考慮使用模組化規範去管理,想要什麼功能,就載入什麼模組,但前提是大家在編寫程式碼時需要使用同一規範。
現在最流行的模組化規範有:CommonJs,、AMD、CMD、以及ES6。

模組化的好處:

1.避免命名衝突(減少名稱空間汙染);

2.更好的分離, 按需載入;

3.更高複用性;

4.高可維護性。

CommonJS規範

1.在伺服器端: 模組的載入是執行時同步載入的;

2.在瀏覽器端: 模組需要提前編譯打包處理;

CommonJS是Node.js使用的模組化標準。在CommonJS中,有一個全域性性方法require(),用於載入模組。

基本語法:

暴露模組:(本質都是暴露exports這個物件,module.exprots={}就是一個空物件)

①module.exports = value;

②exports.xxx = value;

引入模組:

1 require(xxx);  //第三方模組:xxx為模組名
2                     //自定義模組: xxx為模組檔案路徑
1 //檔案A
2 module.exports = {...}  
3  ....
4       
5 //檔案B
6 var a = require('./foo/bar')

實現方式:

①伺服器端:Node.js

app.js為主入口檔案,使用命令列:node app.js便可啟起服務,看到控制檯列印的資料;

②瀏覽器端:Browserify(也稱為CommonJS的瀏覽器端的打包工具);

兩者區別:①Node.js執行時動態載入模組(同步);②Browserify是在轉譯(編譯)時就會載入打包(合併)require的模組。

index.html為主入口檔案,在瀏覽器中開啟此頁面,正常執行便可看到控制檯列印的資料;但是,這樣去報錯了:

Uncaught ReferenceError: require is not defined
    at app.js:9

瀏覽器並不認識app.js中的方法,因此便需要將app.js編譯打包處理成為它所能識別的檔案,於是在專案根目錄下使用命令列:

browserify js/src/app.js -o js/dist/bundle.js

這句話的意思就是找到js/src/app.js檔案,並將它-o:output 輸出為 js/dist/bundle.js,這樣再在index.html中引入bundle.js檔案後,便可(dist資料夾可以為空,也可以讓其自行建立)。

AMD規範(Asynchronous Module Definition(非同步模組定義))

1.AMD:專門用於瀏覽器端, 模組的載入是非同步的;

基本語法:

①定義暴露模組

1 //定義沒有依賴的模組
2 define(function(){
3     return 模組
4 })
1 //定義有依賴的模組
2 define(['module1', 'module2'], function(m1, m2){
3     return 模組
4 })

②引入使用模組:

1 require(['module1', 'module2'], function(m1, m2){
2     使用m1/m2
3 })

實現方式:

瀏覽器端:Require.js

CMD規範( Common Module Definition(通用模組定義))

1.CMD:專門用於瀏覽器端, 模組的載入是非同步的;

2.專門用於瀏覽器端, 模組的載入是非同步的 ;

3.模組使用時才會載入執行;

4.較其他使用次數少。

基本語法:

①定義暴露模組:類似於CommonJS

1 //定義沒有依賴的模組
2 define(function(require, exports, module){
3     exports.xxx = value
4     module.exports = value
5 })
 1 //定義有依賴的模組
 2 define(function(require, exports, module){
 3     //引入依賴模組(同步)
 4     var module2 = require('./module2')
 5     //引入依賴模組(非同步)
 6       require.async('./module3', function (m3) {
 7         
 8       })
 9     //暴露模組
10     exports.xxx = value
11 })

②引入使用模組

1 define(function (require) {
2     var m1 = require('./module1')
3     var m4 = require('./module4')
4     m1.show()
5     m4.show()
6 })

實現方式:

瀏覽器端:Sea.js

CMD:不嚴謹的講,其實就是集合commonjs+AMD的特點。

ES6

目前主流規範。AMD與CMD均比較commonjs繁瑣,而es6最簡潔。

1.ES6

2.依賴模組需要編譯打包處理(部分瀏覽器不支援);

語法:

①匯出模組: export

②引入模組: import

實現方式:

瀏覽器端:

①使用Babel將ES6編譯為ES5程式碼;

②使用Browserify編譯打包js。

在index.html中使用(在html中引入的js檔案必須為編譯過後的檔案):

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <!-- <script type="text/javascript" src="js/src/app.js"></script> -->
 9     <script type="text/javascript" src="js/lib/bundle.js"></script>
10 </body>
11 </html>

 

相關文章