1. 程式人生 > >JS模組化之歷史演進

JS模組化之歷史演進

為什麼迫切需要js模組化

隨著2006年ajax概念被提出,前端的業務的業務越來越多,程式碼也越來越多,並逐漸發展成為前後端分離的狀態,出現了專門的前端攻城獅。
但是隨著程式碼的增多,也隨之衍生很多問題。

1.早期的js程式碼:

  • common.js
let mode = "single";

function operation(a, b){
    return a + b;
}
//other functions...
  • main.js
function operation(a, b){
    return a * b;
}
//other functions...
  • main.html 中同時引入兩個js檔案
<script src="common.js"></script>
<script src="main.js"></script>

<script type="text/javascript">
    var result = operation(5,5);	
    console.log(result); 		//25
</script>
  • 由程式碼可以發現common.js中的operate函式被main.js中的operate函式覆蓋掉了,這種現象稱為Global全域性變數汙染,容易引起命名衝突。

改良版本1:名稱空間模式

  • common.js
let common = {
    data: 'single',
    operation1(a, b) {
        return a + b;
    },
    operation2() {
        return a * b;
    },
}
  • main.js
let main = {
    operation1(a, b){
        return a * b;
    }
    //,other functions......
}
  • test.html
<script src="common.js"></script>
<script src="main.js"></script>

<script type="text/javascript">
    var result = common.operation(5,5);	
    common.data = "changed"  //私有資料被改變,資料不安全
    console.log(result); 		//25
</script>
  • 簡單物件封裝,減少了全域性變數,但是資料依然不安全

改良版本2:IIFE模式

  • common.js
(function (window) {
  //資料
  let data = 'test'

  //操作資料的函式
  function foo() { //用於暴露有函式
    console.log(`foo() ${data}`)
  }

  function bar() {//用於暴露有函式
    console.log(`bar() ${data}`)
    otherFun() //內部呼叫
  }

  function otherFun() { //內部私有的函式
    console.log('otherFun()')
  }

  //暴露行為
  window.myModule = {foo, bar}
})(window)
  • test.html
<script type="text/javascript" src="common.js"></script>
<script type="text/javascript">
  myModule.foo()
  myModule.bar()
  //myModule.otherFun()  //myModule.otherFun is not a function
  console.log(myModule.data) //undefined 不能訪問模組內部資料
  myModule.data = 'xxxx' //不是修改的模組內部的data
  myModule.foo() //沒有改變

</script>
  • 說明:
    • IIFE模式: 匿名函式自呼叫(閉包)
    • IIFE : immediately-invoked function expression(立即呼叫函式表示式)
    • 作用: 資料是私有的, 外部只能通過暴露的方法操作
    • 問題: 如果當前這個模組依賴另一個模組怎麼辦?

IIFE模式增強

  • 引入jquery到專案中
    • common.js
      (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)
      
    • test.html
      <script type="text/javascript" src="jquery-1.10.1.js"></script>
      <script type="text/javascript" src="common.js"></script>
      <script type="text/javascript">
        myModule.foo()
      </script>
      
    • 說明
      • IIFE模式增強 : 引入依賴
      • 這就是現代模組實現的雛形
  1. 頁面載入多個js的問題
  • 頁面:
    <script type="text/javascript" src="module1.js"></script>
    <script type="text/javascript" src="module2.js"></script>
    <script type="text/javascript" src="module3.js"></script>
    <script type="text/javascript" src="module4.js"></script>
    
  • 說明
    • 一個頁面需要引入多個js檔案
    • 問題:
      • 請求過多
      • 依賴模糊
      • 難以維護
    • 這些問題可以通過現代模組化編碼和專案構建來解決