js模塊化規範—概念和模塊化進化史以及模塊化的問題

模塊的概念javascript

一個複雜的項目開發中,會寫不少js文件,一個js文件執行某些特定的功能,那麼每一個js均可以稱爲一個模塊,這就是模塊的概念css

每一個js模塊內部數據/實現是私有的, 只是向外部暴露一些接口(方法)與外部其它模塊通訊html

 

模塊化的進化史前端

全局function模式:將不一樣的功能封裝成不一樣的全局函數java

問題: Global被污染了, 很容易引發命名衝突jquery

//數據
let data = 'atguigu.com'

//操做數據的函數
function foo() { console.log(`foo() ${data}`) } function bar() { console.log(`bar() ${data}`) }
let data2 = 'other data'; function foo() {  //與另外一個模塊中的函數衝突了
 console.log(`foo() ${data2}`) }
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>01_全局function模式</title>
</head>
<body>
<script type='text/javascript' src='module1.js'></script>
<script type='text/javascript' src='module2.js'></script>
<script type='text/javascript'> let data = "修改後的數據" // 模塊1中已經定義了data變量,重複定義同名變量報錯
 foo() // module2模塊中的foo()方法覆蓋了module1模塊中的foo()方法
 bar() </script>
</body>
</html>

namespace模式程序員

簡單對象封裝,減小了全局變量
問題: 不安全(數據不是私有的, 外部能夠直接修改)express

let myModule1 = { data: 'atguigu.com', foo() { console.log(`foo() ${this.data}`) }, bar() { console.log(`bar() ${this.data}`) } }
let myModule2 = { data: 'atguigu.com2222', foo() { console.log(`foo() ${this.data}`) }, bar() { console.log(`bar() ${this.data}`) } }
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>02_namespace模式</title>
</head>
<body>
<script type="text/javascript" src="module1.js"></script>
<script type="text/javascript" src="module2.js"></script>
<script type="text/javascript"> myModule1.foo() // foo() atguigu.com
 myModule1.bar() // bar() atguigu.com
 myModule2.foo() // foo() atguigu.com2222
 myModule2.bar() // bar() atguigu.com2222
 myModule1.data = 'other data' //能直接修改模塊內部的數據
 myModule1.foo() // foo() other data

</script>
</body>
</html>

IIFE模式: 匿名函數自調用(閉包)
IIFE : immediately-invoked function expression(當即調用函數表達式)
做用: 數據是私有的, 外部只能經過暴露的方法操做
問題: 若是當前這個模塊依賴另外一個模塊怎麼辦編程

(function (window) { let data = 'atguigu.com' // 數據

  //操做數據的函數
  function foo() { //用於暴露有函數
 console.log(`foo() ${data}`) } function bar() {//用於暴露有函數
 console.log(`bar() ${data}`) otherFun() //內部調用
 } function otherFun() { //內部私有的函數
    console.log('otherFun()') } //暴露行爲
  window.myModule = {foo, bar} })(window)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>03_IIFE模式</title>
</head>
<body>
<script type="text/javascript" src="module3.js"></script>
<script type="text/javascript"> myModule.foo() // foo() atguigu.com
 myModule.bar() // bar() atguigu.com
  //myModule.otherFun() //myModule.otherFun is not a function
 console.log(myModule.data) //undefined 不能訪問模塊內部數據
 myModule.data = 'xxxx' //不能修改的模塊內部的data,這只是給myModule對象增長了一個data屬性
 myModule.foo() // 沒有改變,foo() atguigu.com

</script>
</body>
</html>

IIFE模式加強 : 引入依賴安全

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

(function (window, $) { let data = 'atguigu.com' // 數據

  // 操做數據的函數
  function foo() {  // 用於暴露有函數
 console.log(`foo() ${data}`) $('body').css('background', 'red') } function bar() {  // 用於暴露有函數
 console.log(`bar() ${data}`) otherFun() // 內部調用
 } function otherFun() { //內部私有的函數
    console.log('otherFun()') } //暴露行爲
  window.myModule = {foo, bar} })(window, jQuery)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>04_IIFE模式加強</title>
</head>
<body>
<!--引入的js必須有必定順序-->
<script type="text/javascript" src="jquery-1.10.1.js"></script>
<script type="text/javascript" src="module4.js"></script>
<script type="text/javascript"> myModule.foo() // foo() atguigu.com
</script>
</body>
</html>

 

 

 

 

爲何要模塊化開發

首先來講明一下,項目中js爲何要模塊化的開發,當項目開發愈來愈複雜的時候,會常常遇到代碼衝突,每一個js文件之間的依賴關係,當js文件愈來愈多的時候頁面加載性能等等一些問題

代碼衝突:好比在團隊協做的過程當中,同事A寫了一個組件庫common的一個js文件,裏面有個操做選項卡的一個函數叫作tab,而後同事B在同一個頁面中進行修改的時候,也定義了一個叫作tab的函數,那這個時候,這兩個方法就衝突了(不只函數衝突,包括變量等等),通常狀況下,簡單的解決方案就是給這些函數或者變量加上命名空間(這個解決方案的缺點是名字比較長 , 只能下降衝突,不能徹底避免)

var above = {};  //名字比較長 , 只能下降衝突,不能徹底避免
 above.a = 10; above.tab = function(){}; above.drag = function(){}; above.dialog = function(){}; //調用的時候須要加上前綴,若是命名空間比較長的時候,調用的時候更加麻煩
above.tab();

多個js文件之間的依賴關係:當項目愈來愈大的時候,項目須要將js進行分層,當a.js和b.js兩個文件都須要引入頁面中,而且b.js須要依賴a.js的時候,當時後期項目需求更改須要加入一個功能,在寫一個c.js文件,須要依賴a.js,當愈來愈多文件,文件之間有相互依賴的關係,若是少了某個依賴的文件那麼頁面就出錯了

 

 

模塊化的好處和問題

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

模塊化能帶來不少好處,但現實開發中也會帶來問題

頁面引入加載script,產生的問題:請求過多,依賴模糊,難以維護,因此咱們須要一些模塊化的規範來解決這些問題

 

 

SeaJs簡介

Seajs庫的做用就是爲了解決代碼衝突,js模塊的依賴關係等等問題

Seajs,一個Web模塊加載框架,追求簡單、天然的代碼書寫和組織方式,:Sea.js 遵循 CMD 規範,模塊化JS代碼。依賴的自動加載、配置的簡潔清晰,可讓程序員更多地專一編碼。

 

 

Seajs優缺點

優勢:提升可維護性、模塊化編程、動態加載,前端性能優化

缺點:學習文檔偏少且混亂,會更改團隊使用JS的編寫習慣,必須使用模塊化編程。不太適合團隊目前的狀況,多JS文件但少改動,動態加載優點和模塊化優點不明顯。須要配套使用SPM工具,JS的打包和管理工具
 
 
 

SeaJs與JQuery的區別

 

 

什麼是CMD 和AMD

異步模塊定義(AMD)是Asynchronous Module Definition的縮寫,是 RequireJS 在推廣過程當中對模塊定義的規範化產出。
通用模塊定義(CMD)是Common Module Definition的縮寫,是SeaJS 在推廣過程當中對模塊定義的規範化產出。
RequireJS 和 SeaJS 都是模塊化框架的表明,AMD和CMD,是他們各自定義模塊化的方式,大同小異,主要是代碼風格和API不一樣
相關文章
相關標籤/搜索