精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

僅需一篇,搞定前端模塊化

原創
開發 前端
本文內容主要有理解模塊化,為什么要模塊化,模塊化的優缺點以及模塊化規范,并且介紹下開發中最流行的CommonJS, AMD, ES6、CMD規范。本文試圖站在小白的角度,用通俗易懂的筆調介紹這些枯燥無味的概念,希望諸君閱讀后,對模塊化編程有個全新的認識和理解!

【51CTO.com原創稿件】前言

在JavaScript發展初期就是為了實現簡單的頁面交互邏輯,寥寥數語即可;如今CPU、瀏覽器性能得到了極大的提升,很多頁面邏輯遷移到了客戶端(表單驗證等),隨著web2.0時代的到來,Ajax技術得到廣泛應用,jQuery等前端庫層出不窮,前端代碼日益膨脹,此時在JS方面就會考慮使用模塊化規范去管理。

本文內容主要有理解模塊化,為什么要模塊化,模塊化的優缺點以及模塊化規范,并且介紹下開發中***的CommonJS, AMD, ES6、CMD規范。本文試圖站在小白的角度,用通俗易懂的筆調介紹這些枯燥無味的概念,希望諸君閱讀后,對模塊化編程有個全新的認識和理解!

如需本文的源代碼,請猛戳源代碼

僅需一篇,搞定前端模塊化 

一、模塊化的理解

1.什么是模塊?

  • 將一個復雜的程序依據一定的規則(規范)封裝成幾個塊(文件), 并進行組合在一起
  • 塊的內部數據與實現是私有的, 只是向外部暴露一些接口(方法)與外部其它模塊通信

2.模塊化的進化過程

  • 全局function模式 : 將不同的功能封裝成不同的全局函數
    • 編碼: 將不同的功能封裝成不同的全局函數
    • 問題: 污染全局命名空間, 容易引起命名沖突或數據不安全,而且模塊成員之間看不出直接關系 
  1. function m1(){  
  2. //...  
  3.  
  4. function m2(){  
  5. //...  
  6.  
  • namespace模式 : 簡單對象封裝
    • 作用: 減少了全局變量,解決命名沖突
    • 問題: 數據不安全(外部可以直接修改模塊內部的數據) 
  1. let myModule = {  
  2. data: 'www.baidu.com' 
  3. foo() {  
  4. console.log(`foo() ${this.data}`)  
  5. },  
  6. bar() {  
  7. console.log(`bar() ${this.data}`)  
  8.  
  9. myModule.data = 'other data' //能直接修改模塊內部的數據
  10. myModule.foo() // foo() other data

這樣的寫法會暴露所有模塊成員,內部狀態可以被外部改寫。

  • IIFE模式:匿名函數自調用(閉包)
    • 作用: 數據是私有的, 外部只能通過暴露的方法操作
    • 編碼: 將數據和行為封裝到一個函數內部, 通過給window添加屬性來向外暴露接口
    • 問題: 如果當前這個模塊依賴另一個模塊怎么辦? 
  1. // index.html文件 
  2. <script type="text/javascript" src="module.js"></script> 
  3. <script type="text/javascript"
  4.     myModule.foo() 
  5.     myModule.bar() 
  6.     console.log(myModule.data) //undefined 不能訪問模塊內部數據 
  7.     myModule.data = 'xxxx' //不是修改的模塊內部的data 
  8.     myModule.foo() //沒有改變 
  9. </script>  
  1. // module.js文件 
  2. (function(window) { 
  3.   let data = 'www.baidu.com' 
  4.   //操作數據的函數 
  5.   function foo() { 
  6.     //用于暴露有函數 
  7.     console.log(`foo() ${data}`) 
  8.   } 
  9.   function bar() { 
  10.     //用于暴露有函數 
  11.     console.log(`bar() ${data}`) 
  12.     otherFun() //內部調用 
  13.   } 
  14.   function otherFun() { 
  15.     //內部私有的函數 
  16.     console.log('otherFun()'
  17.   } 
  18.   //暴露行為 
  19.   window.myModule = { foo, bar } //ES6寫法 
  20. })(window)  

***得到的結果: 

 

  • IIFE模式增強 : 引入依賴

這就是現代模塊實現的基石。

  1. // module.js文件 
  2. (function(window, $) { 
  3.   let data = 'www.baidu.com' 
  4.   //操作數據的函數 
  5.   function foo() { 
  6.     //用于暴露有函數 
  7.     console.log(`foo() ${data}`) 
  8.     $('body').css('background', 'red') 
  9.   } 
  10.   function bar() { 
  11.     //用于暴露有函數 
  12.     console.log(`bar() ${data}`) 
  13.     otherFun() //內部調用 
  14.   } 
  15.   function otherFun() { 
  16.     //內部私有的函數 
  17.     console.log('otherFun()') 
  18.   } 
  19.   //暴露行為 
  20.   window.myModule = { foo, bar } 
  21. })(window, jQuery)  
  1. // index.html文件 
  2.  <!-- 引入的js必須有一定順序 --> 
  3.  <script type="text/javascript" src="jquery-1.10.1.js"></script> 
  4.  <script type="text/javascript" src="module.js"></script> 
  5.  <script type="text/javascript"
  6.    myModule.foo() 
  7.  </script>  

上例子通過jquery方法將頁面的背景顏色改成紅色,所以必須先引入jQuery庫,就把這個庫當作參數傳入。這樣做除了保證模塊的獨立性,還使得模塊之間的依賴關系變得明顯。

3. 模塊化的好處

  • 避免命名沖突(減少命名空間污染)
  • 更好的分離, 按需加載
  • 更高復用性
  • 高可維護性

4. 引入<script>多個后出現問題

  • 請求過多

首先我們要依賴多個模塊,那樣就會發送多個請求,導致請求過多

  • 依賴模糊

我們不知道他們的具體依賴關系是什么,也就是說很容易因為不了解他們之間的依賴關系導致加載先后順序出錯。

  • 難以維護

以上兩種原因就導致了很難維護,很可能出現牽一發而動全身的情況導致項目出現嚴重的問題。  

模塊化固然有多個好處,然而一個頁面需要引入多個js文件,就會出現以上這些問題。而這些問題可以通過模塊化規范來解決,下面介紹開發中***的commonjs, AMD, ES6, CMD規范。

二、模塊化規范

1.CommonJS

(1)概述

Node 應用由模塊組成,采用 CommonJS 模塊規范。每個文件就是一個模塊,有自己的作用域。在一個文件里面定義的變量、函數、類,都是私有的,對其他文件不可見。在服務器端,模塊的加載是運行時同步加載的;在瀏覽器端,模塊需要提前編譯打包處理。

(2)特點

  • 所有代碼都運行在模塊作用域,不會污染全局作用域。
  • 模塊可以多次加載,但是只會在***次加載時運行一次,然后運行結果就被緩存了,以后再加載,就直接讀取緩存結果。要想讓模塊再次運行,必須清除緩存。
  • 模塊加載的順序,按照其在代碼中出現的順序。

(3)基本語法

  • 暴露模塊:module.exports = value或exports.xxx = value
  • 引入模塊:require(xxx),如果是第三方模塊,xxx為模塊名;如果是自定義模塊,xxx為模塊文件路徑

此處我們有個疑問:CommonJS暴露的模塊到底是什么? CommonJS規范規定,每個模塊內部,module變量代表當前模塊。這個變量是一個對象,它的exports屬性(即module.exports)是對外的接口。加載某個模塊,其實是加載該模塊的module.exports屬性。 

  1. // example.js 
  2. var x = 5; 
  3. var addX = function (value) { 
  4.   return value + x; 
  5. }; 
  6. module.exports.x = x; 
  7. module.exports.addX = addX;  

上面代碼通過module.exports輸出變量x和函數addX。 

  1. var example = require('./example.js');//如果參數字符串以“./”開頭,則表示加載的是一個位于相對路徑  
  2. console.log(example.x); // 5  
  3. console.log(example.addX(1)); // 6  

require命令用于加載模塊文件。require命令的基本功能是,讀入并執行一個JavaScript文件,然后返回該模塊的exports對象。如果沒有發現指定模塊,會報錯。

(4)模塊的加載機制

CommonJS模塊的加載機制是,輸入的是被輸出的值的拷貝。也就是說,一旦輸出一個值,模塊內部的變化就影響不到這個值。這點與ES6模塊化有重大差異(下文會介紹),請看下面這個例子: 

  1. // lib.js  
  2. var counter = 3;  
  3. function incCounter() {  
  4. counter++;  
  5.  
  6. module.exports = {  
  7. counter: counter,  
  8. incCounter: incCounter,  
  9. }; 

上面代碼輸出內部變量counter和改寫這個變量的內部方法incCounter。 

  1. // main.js  
  2. var counter = require('./lib').counter;  
  3. var incCounter = require('./lib').incCounter; ​  
  4. console.log(counter); // 3  
  5. incCounter();  
  6. console.log(counter); // 3  

上面代碼說明,counter輸出以后,lib.js模塊內部的變化就影響不到counter了。這是因為counter是一個原始類型的值,會被緩存。除非寫成一個函數,才能得到內部變動后的值。

(5)服務器端實現

①下載安裝node.js

②創建項目結構

注意:用npm init 自動生成package.json時,package name(包名)不能有中文和大寫。

  1. |-modules 
  2.  
  3. |-module1.js 
  4.  
  5. |-module2.js 
  6.  
  7. |-module3.js 
  8.  
  9. |-app.js 
  10.  
  11. |-package.json 
  12.  
  13.  
  14. "name""commonJS-node"
  15.  
  16. "version""1.0.0" 
  17.  
  18.  

③下載第三方模塊 

  1. npm install uniq --save // 用于數組去重 

④定義模塊代碼 

  1. //module1.js  
  2. module.exports = {  
  3. msg: 'module1' 
  4. foo() {  
  5. console.log(this.msg)  
  6.  
  7.  
  8. //module2.js  
  9. module.exports = function() {  
  10. console.log('module2' 
  11.  
  12. //module3.js  
  13. exports.foo = function() {  
  14. console.log('foo() module3' 
  15.  
  16. exports.arr = [1, 2, 3, 3, 2]  
  17. // app.js文件  
  18. // 引入第三方庫,應該放置在最前面  
  19. let uniq = require('uniq' 
  20. let module1 = require('./modules/module1' 
  21. let module2 = require('./modules/module2' 
  22. let module3 = require('./modules/module3' ​ 
  23.  
  24. module1.foo() //module1  
  25. module2() //module2  
  26. module3.foo() //foo() module3  
  27. console.log(uniq(module3.arr)) //[ 1, 2, 3 ]  

⑤通過node運行app.js

命令行輸入node app.js,運行JS文件

(6)瀏覽器端實現(借助Browserify)

①創建項目結構 

  1. |-js  
  2. |-dist //打包生成文件的目錄  
  3. |-src //源碼所在的目錄  
  4. |-module1.js  
  5. |-module2.js  
  6. |-module3.js  
  7. |-app.js //應用主源文件  
  8. |-index.html //運行于瀏覽器上  
  9. |-package.json  
  10.  
  11. "name""browserify-test" 
  12. "version""1.0.0"  
  13.  

②下載browserify

  • 全局: npm install browserify -g
  • 局部: npm install browserify --save-dev

③定義模塊代碼(同服務器端)

注意:index.html文件要運行在瀏覽器上,需要借助browserify將app.js文件打包編譯,如果直接在index.html引入app.js就會報錯!

④打包處理js

根目錄下運行browserify js/src/app.js -o js/dist/bundle.js

⑤頁面使用引入 

在index.html文件中引入  

2.AMD

CommonJS規范加載模塊是同步的,也就是說,只有加載完成,才能執行后面的操作。AMD規范則是非同步加載模塊,允許指定回調函數。由于Node.js主要用于服務器編程,模塊文件一般都已經存在于本地硬盤,所以加載起來比較快,不用考慮非同步加載的方式,所以CommonJS規范比較適用。但是,如果是瀏覽器環境,要從服務器端加載模塊,這時就必須采用非同步模式,因此瀏覽器端一般采用AMD規范。此外AMD規范比CommonJS規范在瀏覽器端實現要來著早。

(1)AMD規范基本語法

定義暴露模塊: 

  1. //定義沒有依賴的模塊  
  2. define(function(){ 
  3. return 模塊  
  4. })  
  5.  
  6. //定義有依賴的模塊  
  7. define(['module1''module2'], function(m1, m2){  
  8. return 模塊  
  9. })  

引入使用模塊:

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

(2)未使用AMD規范與使用require.js

通過比較兩者的實現方法,來說明使用AMD規范的好處。

未使用AMD規范 

  1. // alerter.js文件  
  2. (function (window) {  
  3. let msg = 'www.baidu.com'  
  4. function getMsg() {  
  5. return msg.toUpperCase()  
  6.  
  7. window.dataService = {getMsg}  
  8. })(window)  
  1. // dataService.js文件  
  2. (function (window, dataService) {  
  3. let name = 'Tom'  
  4. function showMsg() {  
  5. alert(dataService.getMsg() + ', ' + name 
  6.  
  7. window.alerter = {showMsg}  
  8. })(window, dataService)  
  1. // main.js文件  
  2. (function (alerter) {  
  3. alerter.showMsg()  
  4. })(alerter)  
  5. // index.html文件  
  1. // index.html文件 
  2. <div><h1>Modular Demo 1: 未使用AMD(require.js)</h1></div> 
  3. <script type="text/javascript" src="js/modules/dataService.js"></script> 
  4. <script type="text/javascript" src="js/modules/alerter.js"></script> 
  5. <script type="text/javascript" src="js/main.js"></script> 

***得到如下結果:

這種方式缺點很明顯:首先會發送多個請求,其次引入的js文件順序不能搞錯,否則會報錯!

  • 使用require.js

RequireJS是一個工具庫,主要用于客戶端的模塊管理。它的模塊管理遵守AMD規范,RequireJS的基本思想是,通過define方法,將代碼定義為模塊;通過require方法,實現代碼的模塊加載。

接下來介紹AMD規范在瀏覽器實現的步驟:

①下載require.js, 并引入

  • 官網: http://www.requirejs.cn/
  • github : https://github.com/requirejs/requirejs

然后將require.js導入項目: js/libs/require.js 

②創建項目結構

  1. |-js   
  2.     |-libs   
  3.       |-require.js   
  4.     |-modules   
  5.       |-alerter.js   
  6.       |-dataService.js   
  7.     |-main.js   
  8.   |-index.html  

③定義require.js的模塊代碼

  1. // dataService.js文件 
  2. // 定義沒有依賴的模塊 
  3. define(function() { 
  4.   let msg = 'www.baidu.com' 
  5.   function getMsg() { 
  6.     return msg.toUpperCase() 
  7.   } 
  8.   return { getMsg } // 暴露模塊 
  9. })  
  1. //alerter.js文件 
  2. // 定義有依賴的模塊 
  3. define(['dataService'], function(dataService) { 
  4.   let name = 'Tom' 
  5.   function showMsg() { 
  6.     alert(dataService.getMsg() + ', ' + name
  7.   } 
  8.   // 暴露模塊 
  9.   return { showMsg } 
  10. })  
  1. // main.js文件 
  2. (function() { 
  3.   require.config({ 
  4.     baseUrl: 'js/', //基本路徑 出發點在根目錄下 
  5.     paths: { 
  6.       //映射: 模塊標識名: 路徑 
  7.       alerter: './modules/alerter', //此處不能寫成alerter.js,會報錯 
  8.       dataService: './modules/dataService' 
  9.     } 
  10.   }) 
  11.   require(['alerter'], function(alerter) { 
  12.     alerter.showMsg() 
  13.   }) 
  14. })()  
  1. // index.html文件 
  2. <!DOCTYPE html> 
  3. <html> 
  4.   <head> 
  5.     <title>Modular Demo</title> 
  6.   </head> 
  7.   <body> 
  8.     <!-- 引入require.js并指定js主文件的入口 --> 
  9.     <script data-main="js/main" src="js/libs/require.js"></script> 
  10.   </body> 
  11. </html> 

④頁面引入require.js模塊:

在index.html引入 

此外在項目中如何引入第三方庫?只需在上面代碼的基礎稍作修改:

  1. // alerter.js文件 
  2. define(['dataService''jquery'], function(dataService, $) { 
  3.   let name = 'Tom' 
  4.   function showMsg() { 
  5.     alert(dataService.getMsg() + ', ' + name
  6.   } 
  7.   $('body').css('background''green'
  8.   // 暴露模塊 
  9.   return { showMsg } 
  10. })  
  1. // main.js文件 
  2. (function() { 
  3.   require.config({ 
  4.     baseUrl: 'js/', //基本路徑 出發點在根目錄下 
  5.     paths: { 
  6.       //自定義模塊 
  7.       alerter: './modules/alerter', //此處不能寫成alerter.js,會報錯 
  8.       dataService: './modules/dataService'
  9.       // 第三方庫模塊 
  10.       jquery: './libs/jquery-1.10.1' //注意:寫成jQuery會報錯 
  11.     } 
  12.   }) 
  13.   require(['alerter'], function(alerter) { 
  14.     alerter.showMsg() 
  15.   }) 
  16. })() 

上例是在alerter.js文件中引入jQuery第三方庫,main.js文件也要有相應的路徑配置。

小結:通過兩者的比較,可以得出AMD模塊定義的方法非常清晰,不會污染全局環境,能夠清楚地顯示依賴關系。AMD模式可以用于瀏覽器環境,并且允許非同步加載模塊,也可以根據需要動態加載模塊。

3.CMD

CMD規范專門用于瀏覽器端,模塊的加載是異步的,模塊使用時才會加載執行。CMD規范整合了CommonJS和AMD規范的特點。在 Sea.js 中,所有 JavaScript 模塊都遵循 CMD模塊定義規范。

(1)CMD規范基本語法 

定義暴露模塊:

  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.   exports.xxx = value 
  10. }) 

引入使用模塊:

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

(2)sea.js簡單使用教程

①下載sea.js, 并引入

  • 官網: http://seajs.org/
  • github : https://github.com/seajs/seajs

然后將sea.js導入項目: js/libs/sea.js 

②創建項目結構

  1. |-js  
  2.    |-libs   
  3.      |-sea.js   
  4.    |-modules   
  5.      |-module1.js   
  6.      |-module2.js   
  7.      |-module3.js   
  8.      |-module4.js   
  9.      |-main.js   
  10.  |-index.html  

③定義sea.js的模塊代碼

  1. // module1.js文件 
  2. define(function (require, exports, module) { 
  3.   //內部變量數據 
  4.   var data = 'atguigu.com' 
  5.   //內部函數 
  6.   function show() { 
  7.     console.log('module1 show() ' + data) 
  8.   } 
  9.   //向外暴露 
  10.   exports.show = show 
  11. }) 
  1. // module2.js文件 
  2. define(function (require, exports, module) { 
  3.   module.exports = { 
  4.     msg: 'I Will Back' 
  5.   } 
  6. }) 
  1. // module3.js文件 
  2. define(function(require, exports, module) { 
  3.   const API_KEY = 'abc123' 
  4.   exports.API_KEY = API_KEY 
  5. }) 
  1. // module4.js文件 
  2. define(function (require, exports, module) { 
  3.   //引入依賴模塊(同步) 
  4.   var module2 = require('./module2'
  5.   function show() { 
  6.     console.log('module4 show() ' + module2.msg) 
  7.   } 
  8.   exports.show = show 
  9.   //引入依賴模塊(異步) 
  10.   require.async('./module3'function (m3) { 
  11.     console.log('異步引入依賴模塊3  ' + m3.API_KEY) 
  12.   }) 
  13. }) 
  1. // main.js文件 
  2. define(function (require) { 
  3.   var m1 = require('./module1'
  4.   var m4 = require('./module4'
  5.   m1.show() 
  6.   m4.show() 
  7. }) 

④在index.html中引入

  1. <script type="text/javascript" src="js/libs/sea.js"></script> 
  2. <script type="text/javascript"
  3.   seajs.use('./js/modules/main'
  4. </script> 

***得到結果如下:

4.ES6模塊化

ES6 模塊的設計思想是盡量的靜態化,使得編譯時就能確定模塊的依賴關系,以及輸入和輸出的變量。CommonJS 和 AMD 模塊,都只能在運行時確定這些東西。比如,CommonJS 模塊就是對象,輸入時必須查找對象屬性。

(1)ES6模塊化語法 

export命令用于規定模塊的對外接口,import命令用于輸入其他模塊提供的功能。

  1. /** 定義模塊 math.js **/ 
  2. var basicNum = 0; 
  3. var add = function (a, b) { 
  4.     return a + b; 
  5. }; 
  6. export { basicNum, add }; 
  7. /** 引用模塊 **/ 
  8. import { basicNum, add } from './math'
  9. function test(ele) { 
  10.     ele.textContent = add(99 + basicNum); 

如上例所示,使用import命令的時候,用戶需要知道所要加載的變量名或函數名,否則無法加載。為了給用戶提供方便,讓他們不用閱讀文檔就能加載模塊,就要用到export default命令,為模塊指定默認輸出。

  1. // export-default.js 
  2. export default function () { 
  3.   console.log('foo'); 
  1. // import-default.js 
  2. import customName from './export-default'
  3. customName(); // 'foo' 

模塊默認輸出, 其他模塊加載該模塊時,import命令可以為該匿名函數指定任意名字。

(2)ES6 模塊與 CommonJS 模塊的差異

它們有兩個重大差異:

① CommonJS 模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的引用。

② CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出接口。

第二個差異是因為 CommonJS 加載的是一個對象(即module.exports屬性),該對象只有在腳本運行完才會生成。而 ES6 模塊不是對象,它的對外接口只是一種靜態定義,在代碼靜態解析階段就會生成。 

下面重點解釋***個差異,我們還是舉上面那個CommonJS模塊的加載機制例子:

  1. // lib.js 
  2. export let counter = 3; 
  3. export function incCounter() { 
  4.   counter++; 
  5. // main.js 
  6. import { counter, incCounter } from './lib'
  7. console.log(counter); // 3 
  8. incCounter(); 
  9. console.log(counter); // 4 

ES6 模塊的運行機制與 CommonJS 不一樣。ES6 模塊是動態引用,并且不會緩存值,模塊里面的變量綁定其所在的模塊。

(3) ES6-Babel-Browserify使用教程

簡單來說就一句話:使用Babel將ES6編譯為ES5代碼,使用Browserify編譯打包js。 

①定義package.json文件

  1. {   
  2.     "name" : "es6-babel-browserify",   
  3.     "version" : "1.0.0"   
  4.   }  

②安裝babel-cli, babel-preset-es2015和browserify

  • npm install babel-cli browserify -g
    • npm install babel-preset-es2015 --save-dev
    • preset 預設(將es6轉換成es5的所有插件打包) 

③定義.babelrc文件

  1.     "presets": ["es2015"
  2.   } 

④定義模塊代碼

  1. //module1.js文件 
  2. // 分別暴露 
  3. export function foo() { 
  4.   console.log('foo() module1'
  5. export function bar() { 
  6.   console.log('bar() module1'
  1. //module2.js文件 
  2. // 統一暴露 
  3. function fun1() { 
  4.   console.log('fun1() module2'
  5. function fun2() { 
  6.   console.log('fun2() module2'
  7. export { fun1, fun2 } 
  1. //module3.js文件 
  2. // 默認暴露 可以暴露任意數據類項,暴露什么數據,接收到就是什么數據 
  3. export default () => { 
  4.   console.log('默認暴露'
  1. // app.js文件 
  2. import { foo, bar } from './module1' 
  3. import { fun1, fun2 } from './module2' 
  4. import module3 from './module3' 
  5. foo() 
  6. bar() 
  7. fun1() 
  8. fun2() 
  9. module3() 

⑤ 編譯并在index.html中引入

  • 使用Babel將ES6編譯為ES5代碼(但包含CommonJS語法) : babel js/src -d js/lib
  • 使用Browserify編譯js : browserify js/lib/app.js -o js/lib/bundle.js 

然后在index.html文件中引入:

  1. <script type="text/javascript" src="js/lib/bundle.js"></script>  

***得到如下結果:

此外第三方庫(以jQuery為例)如何引入呢?

首先安裝依賴npm install jquery@1 

然后在app.js文件中引入:

  1. //app.js文件 
  2. import { foo, bar } from './module1' 
  3. import { fun1, fun2 } from './module2' 
  4. import module3 from './module3' 
  5. import $ from 'jquery' 
  6.  
  7. foo() 
  8. bar() 
  9. fun1() 
  10. fun2() 
  11. module3() 
  12. $('body').css('background''green'

三、總結

  • CommonJS規范主要用于服務端編程,加載模塊是同步的,這并不適合在瀏覽器環境,因為同步意味著阻塞加載,瀏覽器資源是異步加載的,因此有了AMD CMD解決方案。
  • AMD規范在瀏覽器環境中異步加載模塊,而且可以并行加載多個模塊。不過,AMD規范開發成本高,代碼的閱讀和書寫比較困難,模塊定義方式的語義不順暢。
  • CMD規范與AMD規范很相似,都用于瀏覽器編程,依賴就近,延遲執行,可以很容易在Node.js中運行。不過,依賴SPM 打包,模塊的加載邏輯偏重
  • ES6 在語言標準的層面上,實現了模塊功能,而且實現得相當簡單,完全可以取代 CommonJS 和 AMD 規范,成為瀏覽器和服務器通用的模塊解決方案。

參考文章 

作者:浪里行舟,慕課網認證作者,前端愛好者,立志往全棧工程師發展,從事前端一年多,目前技術棧有vue全家桶、ES6以及less等,樂于分享,最近一年寫了五六十篇原創技術文章,得到諸多好評!

【51CTO原創稿件,合作站點轉載請注明原文作者和出處為51CTO.com】

責任編輯:龐桂玉 來源: 51CTO
相關推薦

2021-04-06 10:19:36

Go語言基礎技術

2018-12-06 09:41:12

持續集成軟件

2018-10-16 09:43:26

負載均衡TCPHTTP

2020-09-17 10:30:21

前端模塊化組件

2013-08-20 15:31:18

前端模塊化

2022-03-11 13:01:27

前端模塊

2020-09-18 09:02:32

前端模塊化

2021-11-10 09:19:41

PythonShutil模塊

2021-11-17 10:11:08

PythonLogging模塊

2020-03-20 08:30:56

手機移動端適配

2022-09-05 09:01:13

前端模塊化

2019-12-02 16:05:10

前端模塊化JavaScript

2023-05-24 10:35:11

Node.jsES模塊

2014-04-27 10:16:31

QCon北京2014Andrew Bett

2020-08-11 09:06:42

監控系統選型

2020-02-28 11:29:00

ElasticSear概念類比

2022-10-21 08:29:50

監控CMDB架構

2019-07-22 08:35:32

Java垃圾回收

2019-08-28 16:18:39

JavaScriptJS前端

2018-05-17 11:23:06

智能化
點贊
收藏

51CTO技術棧公眾號

在线视频一区二区三区| 成人国产精品免费网站| 久久精品视频播放| 欧美激情 亚洲| 台湾成人免费视频| 亚洲男人天堂av网| 欧美一区二区在线| 99久久精品无免国产免费| 欧美日韩在线精品一区二区三区激情综 | 欧美美女视频在线观看| 欧洲精品在线播放| 成人免费在线电影| 成人午夜av影视| 国产精品久久久久久久久借妻 | 国产+高潮+白浆+无码| 日日av拍夜夜添久久免费| 1024成人网色www| 欧美另类一区| 丰满人妻妇伦又伦精品国产| 日韩电影一区二区三区| 欧美激情视频免费观看| 国产精品视频在| 欧美色资源站| 欧美va亚洲va| 欧洲在线免费视频| 992tv国产精品成人影院| 亚欧色一区w666天堂| 亚洲日本理论电影| 国产小视频免费在线网址| 国产精品99久久久久久久vr| 国产精品电影观看| 天天爽夜夜爽夜夜爽精品| 欧美精品首页| 日韩少妇与小伙激情| 亚洲 小说 欧美 激情 另类| 成人av地址| 日韩天堂在线观看| 91网址在线观看精品| 另类一区二区| 欧美午夜电影网| 国产天堂在线播放| 欧美自拍电影| 在线免费视频一区二区| 欧美成人高潮一二区在线看| a级毛片免费观看在线| 1024成人网色www| 一区二区三区四区视频在线 | 国产精品男女| 精品嫩草影院久久| 动漫美女无遮挡免费| 亚洲欧洲国产精品一区| 欧美一级免费大片| 亚洲精品无码久久久久久久| 人人九九精品视频| 日韩午夜av电影| 国产精品99精品无码视亚| 国色天香久久精品国产一区| 7777精品伊人久久久大香线蕉| 8x8x最新地址| 亚洲欧美在线人成swag| 宅男在线国产精品| 麻豆精品国产传媒| 成人激情自拍| 亚洲欧美日韩一区二区在线 | 青青草国产精品一区二区| 国产成人无码精品| 久久精品盗摄| 国产精品视频999| 国产又粗又猛又爽又黄91| 精东粉嫩av免费一区二区三区| 91在线色戒在线| 亚洲国产精品一| 99久久久精品免费观看国产蜜| 国内精品久久国产| 国产在线一二| 中文字幕中文字幕在线一区 | 欧美日韩在线精品| 1024国产在线| 亚洲一区免费在线观看| 亚洲 欧美 日韩 国产综合 在线| 樱桃视频成人在线观看| 欧美亚洲动漫精品| 一个人看的视频www| 精品自拍偷拍| 色偷偷噜噜噜亚洲男人的天堂 | 色婷婷综合久久久中文一区二区 | 素人啪啪色综合| 91精品国产综合久久久蜜臀图片| 国产成人精品一区二区三区在线观看| 久久综合另类图片小说| 伊人久久精品视频| 久久久久久久久久久97| 久久蜜桃精品| 91文字幕巨乱亚洲香蕉| 欧美女同网站| 尤物在线观看一区| 日韩中文字幕二区| 欧美国产亚洲精品| 亚洲色图25p| 久久精品www| 日韩精品亚洲专区| 国产aⅴ精品一区二区三区黄| 免费一级毛片在线观看| 亚洲人成小说网站色在线| 欧美亚洲精品一区二区| 国产麻豆精品| 国产亚洲视频在线观看| 国产一级视频在线观看| 麻豆精品一区二区av白丝在线| 国产福利久久精品| 欧美日本一道| 色哟哟精品一区| jjzzjjzz欧美69巨大| 日韩伦理一区| 2024亚洲男人天堂| 精品人妻av一区二区三区| 国产婷婷精品av在线| 青草视频在线观看视频| 亚洲影视资源| 伊人久久五月天| 国产一级精品视频| www.一区二区| 4444亚洲人成无码网在线观看| 成人精品国产亚洲| 亚洲欧美日韩精品| av资源免费观看| 国产精品亚洲午夜一区二区三区 | 欧美日韩一区二区欧美激情| 一二三不卡视频| 亚洲二区视频| 成人欧美一区二区三区黑人免费| а√天堂官网中文在线| 欧美日韩国产高清一区| 一区二区三区伦理片| 亚洲激情影院| 国产精品我不卡| 懂色av一区| 精品美女在线播放| 久久久久噜噜噜亚洲熟女综合| 另类专区欧美蜜桃臀第一页| 欧洲av一区| 中文字幕av一区二区三区佐山爱| 亚洲国产欧美在线成人app | 九七久久人人| 3d成人h动漫网站入口| av最新在线观看| 国产自产视频一区二区三区| 亚洲一区二区三区四区中文| 99riav视频一区二区| 国产亚洲精品美女久久久久| 波多野结衣人妻| 日本一区二区免费在线观看视频 | 伊人再见免费在线观看高清版| 粉嫩一区二区三区在线观看| zzjj国产精品一区二区| 91中文字幕在线播放| 国产精品乱码一区二三区小蝌蚪| 免费涩涩18网站入口| 久久美女视频| 3d蒂法精品啪啪一区二区免费| 毛片激情在线观看| 91精品久久久久久久91蜜桃| 午夜爱爱毛片xxxx视频免费看| 国产主播一区二区三区| 久久这里只有精品8| 果冻天美麻豆一区二区国产| 91大神福利视频在线| 国产午夜视频在线观看| 欧美高清视频一二三区| 久草国产在线视频| 97国产一区二区| 国产第一页视频| 久久综合成人| 国产欧美日本在线| 天天综合网天天| 精品国内自产拍在线观看| 亚洲产国偷v产偷v自拍涩爱| 午夜欧美2019年伦理| 亚洲成人网在线播放| 精品一区二区在线免费观看| 欧美大黑帍在线播放| 一本色道久久综合狠狠躁的番外| 国产精品久久视频| 香蕉成人app免费看片| 日韩精品欧美激情| 一卡二卡在线视频| 亚洲aⅴ怡春院| 成人信息集中地| 99精品视频免费在线观看| xxxx一级片| 亚洲国产精品一区制服丝袜| 日韩三级在线播放| 北条麻妃一区二区三区在线观看 | 国产精品视频麻豆| 亚洲色偷偷色噜噜狠狠99网| 日韩av中文字幕一区二区| 日本天堂免费a| 九九精品久久| 国产精品国模大尺度私拍| 国精产品一区二区三区有限公司| 欧美成人免费网| 成人在线免费电影| 亚洲国产高清福利视频| 中文字幕在线网站| 欧美视频精品一区| 欧美黑人一级片| 国产精品欧美久久久久一区二区| 久久久久国产免费| 久久99国产乱子伦精品免费| 99精品在线免费视频| 亚洲国产精品久久久天堂| 免费精品视频一区| 91精品入口| 91久久久在线| 欧美性www| 国产精品96久久久久久| 538在线观看| 欧美另类交人妖| 日本不卡在线| 在线免费看av不卡| 青青国产在线| 亚洲激情第一页| 亚洲AV午夜精品| 5858s免费视频成人| 羞羞色院91蜜桃| 在线这里只有精品| 精品免费囯产一区二区三区| 亚洲一区二区精品视频| 中文字幕手机在线观看| 国产精品电影一区二区三区| 亚洲天堂岛国片| 久久色.com| 精品成人av一区二区三区| 99久久亚洲一区二区三区青草| 韩国三级hd两男一女| 国产91丝袜在线播放0| 天天干天天曰天天操| 日本网站在线观看一区二区三区 | 日本学生初尝黑人巨免费视频| 一区二区视频在线看| 国产成人免费在线观看视频| 中文一区一区三区高中清不卡| 日本成人午夜影院| 中文字幕欧美国产| 性生交大片免费全黄| 亚洲欧洲日韩在线| 欧美做爰爽爽爽爽爽爽| 亚洲精品日产精品乱码不卡| 69av.com| 亚洲电影第三页| 香蕉免费毛片视频| 五月婷婷激情综合| 800av免费在线观看| 色综合一个色综合亚洲| 337p粉嫩色噜噜噜大肥臀| 91黄色免费网站| 在线视频1卡二卡三卡| 欧美日韩日日夜夜| av男人天堂av| 精品国产乱码久久久久久影片| 日本人亚洲人jjzzjjz| 亚洲视频自拍| 91免费综合在线| 免费观看亚洲天堂| 成人激情av| 欧洲亚洲一区二区三区| 欧美精品123| 欧美一区二区三区高清视频| 午夜一区二区三区| 亚洲一本二本| 成熟丰满熟妇高潮xxxxx视频| 欧美亚洲视频| 激情五月俺来也| 国产精品小仙女| 成人手机在线免费视频| 国产欧美日韩在线视频| 五月天av网站| 日韩欧美在线视频观看| 在线免费观看中文字幕| 日韩免费高清av| 嫩草精品影院| 免费av一区二区| 625成人欧美午夜电影| 国产在线a不卡| 果冻天美麻豆一区二区国产| 欧美一区国产一区| 欧美国产高清| 精品一区二区中文字幕| 精品一区二区三区在线观看| 国产大学生视频| 国产精品久久久久影院色老大 | 男女爽爽爽视频| 国产九九视频一区二区三区| 国产在线观看无码免费视频| 亚洲欧洲色图综合| www.国产色| 欧美一级夜夜爽| 国产中文在线观看| 久久人人看视频| 日韩一级特黄| 欧美专区一二三 | 亚洲欧洲成人av每日更新| 日韩欧美亚洲国产| 欧美日韩aaaaa| 精品欧美不卡一区二区在线观看| 色综合91久久精品中文字幕| 日韩一级二级| 美媛馆国产精品一区二区| 欧美啪啪一区| 污视频网址在线观看| 久久久午夜精品理论片中文字幕| 久青草免费视频| 欧美一区二区三区免费在线看| 国产精品影院在线| 热久久免费国产视频| 东京久久高清| 337p亚洲精品色噜噜狠狠p| 蜜桃视频在线一区| 中文字幕在线1| 高潮白浆女日韩av免费看| 亚洲国产一二三区| 欧美成人激情图片网| 日韩成人综合网站| 亚洲国产一区二区精品视频| 久久国产毛片| 午夜理伦三级做爰电影| 午夜国产不卡在线观看视频| 亚洲第一视频在线| 欧美另类高清videos| 秋霞午夜一区二区三区视频| 一区二区三区观看| 卡一卡二国产精品 | 欧美在线免费| 久久久久xxxx| 中文字幕亚洲欧美在线不卡| 日韩欧美国产另类| 一区二区福利视频| 制服诱惑亚洲| 日韩视频精品| 毛片av一区二区| 三级av在线免费观看| 欧美人牲a欧美精品| 午夜视频在线观看免费视频| 国产精品偷伦免费视频观看的| 秋霞欧美视频| 成人不卡免费视频| 亚洲蜜臀av乱码久久精品| av男人天堂av| 国内精品久久久久影院 日本资源| 国产成人夜色高潮福利影视 | 免费成人在线观看视频| 日本综合在线观看| 8x8x8国产精品| 日本高清在线观看| 国产精品一区二区欧美| 99国产精品久久久久久久成人热| 日本黄色免费观看| 一本大道久久a久久综合| 黄色毛片在线看| 国产日韩在线视频| 欧美激情一级片一区二区| 催眠调教后宫乱淫校园| 欧美日韩美女在线观看| 国产在线免费观看| 成人有码视频在线播放| 欧美特黄一级| 国产ts丝袜人妖系列视频| 欧美午夜在线一二页| 操你啦视频在线| 国产一区精品视频| 老牛影视一区二区三区| 欧美肥妇bbwbbw| 精品国产麻豆免费人成网站| 免费成人直播| 国产日产欧美一区二区| 99综合电影在线视频| 国产精品xxxxxx| 久久777国产线看观看精品| 欧美自拍一区| 狠狠干狠狠操视频| 亚洲一卡二卡三卡四卡| 国产爆初菊在线观看免费视频网站 | 国产精品热久久| 97国产在线观看| 国产韩日影视精品| 插吧插吧综合网| 91精品国产91热久久久做人人| brazzers在线观看| 一区二区三区电影| 97久久精品人人做人人爽| 一级黄色片在线播放| 97国产精品人人爽人人做| 欧美电影免费观看高清| 性囗交免费视频观看| 欧美日韩在线直播| 岛国av在线播放| gogogo免费高清日本写真| 久久久久久久久97黄色工厂| 亚洲精品国产av| 成人黄色网免费|