前端模塊化發展歷程 (-)


本文將從以下三點來做一個詳細講解:

  1. 模塊化產生
  2. 早期模塊化解決方案
  3. 模塊化規范的產生和差異

模塊化產生

在早期的前端開發中,並沒有模塊的概念,模塊只在服務端存在,用於處理復雜的業務通信等。 直到 AJAX 被提出,前端能夠像后端請求數據,前端邏輯越來越復雜,就出現了許多問題:全局變量,函數名沖突,依賴關系不好處理... 隨着業務邏輯的增加,對模塊需求越來越大,所以才有了后續一系列 AMD、commonJS、ES6Module 規范。

早期模塊化解決方案

兩種解決方法:

  • 匿名函數自調用(閉包): 形成私有變量; 棧內存處理 
  • 基於對象進行分組 堆內存處理; “單例模式思想” : 基於單獨的實例, 來實現信息分組, 避免全局變量的污染

下面一個簡單的例子

// 新聞板塊
let newMOdel = (function(){
  let time = new  Date()
  const query = function query() {}
  const handle = function handel() {}
  return {
    query,
    handle
  }
}())
// 皮膚板塊
let skinModel = (function() {
  let time = '2021-07-05'
  const hanle = function handel(){ }
  newMOdel.query()
}())

最早期的模塊編程思想就是這種 高級單例設計模「閉包+對象」的組合 模塊塊化編程思想:就是各個板塊/模塊 /功能 拼接成一起的東西 ,提出公共的模塊。

帶來的好處?

公用&復用性、提供開發效率、方便管理、團隊協作開發 ; 問題:需要自己構建、根據模塊間的依賴關系,需要明確導出順序。 所以就產生了一些其他的模塊化規范。

模塊化規范 - AMD

AMD 即 Asynchronous Module Definition:異步模塊加載,代表 require.js

RequireJS是一個遵守AMD規范的工具庫,用於客戶端的模塊管理。它通過 define 方法,將代碼定義為模塊;通過 require 方法,實現代碼的模塊加載,使用時需要下載和導入項

 文件目錄

├── AMD  
    ├── moduleA.js  
    ├── moduleB.js  
    ├── main.js  
    └── require.min.js 

簡單實現一個require.js

let factories = {}
function define(moduleName,factory) {
  factories[moduleName] = factory
}
function require(modules,callback) {
  modules = modules.map(function(item){
    let factory = factories[item];  // 定義好每一個 然后把它執行
    return factory() // 執行之后返回的東西 放到modules
  });
  callback(...modules) // 然后回掉函數執行這些modules
}
/**使用AMD */
define('moduleA', function() {
  return {
    fn() {
      console.log('moduleA')
    }
  }
  
});
define('moduleB', function() {
  return {
    fn() {
      console.log('moduleB')
    }
  }
  
});
require(['moduleB','moduleA'],function(moduleB,moduleA) {
  moduleB.fn()
  moduleA.fn()
})

模塊化規范 - CMD

CMD即 Common Module Definition : 通用模塊加載。

CMD(Sea.js )& CommonJs規范(Node.js)。

問題:CommonJs只能在 node 環境下支持,客戶端/瀏覽器不支持  CommonJS 規范

那如何讓瀏覽器支持CommonJs規范? 所以有了 Sea.js  ,也就產生了CMD規范(Sea.js 就是Commonjs規范直接搬到瀏覽器上 )

AMD、CMD 區別

AMD 是 RequireJS 在推廣過程中對模塊定義的規范化產出 CMD是SeaJS在推廣過程中對模塊化定義的規范化產出

區別:

  • 對於依賴的模塊,AMD 是提前執行,CMD 是延遲執行。不過 RequireJS 從 2.0 開始,也改成可以延遲執行(根據寫法不同,處理方式不同)。CMD 推崇 as lazy as possible.
  • CMD 推崇依賴就近,AMD 推崇依賴前置

模塊化規范 - ES6Module

 ModuleA.js

const sum =  function sum(...args){
  let len = args.length
  let firstItem = args[0]
  if(len === 0) return 0;
  if(len === 1) return firstItem;
  return args.reduce((total,item) => {
    return total + item
  })
}

export default { sum }

moduleB.js

import A from './a.js'
const average = function average(...args) {
  let len = args.length
  let firstItem = args[0]
  if(len === 0) return 0;
  if(len === 1) return firstItem;
  return (A.sum(...args) / args.length).toFixed(2)
}

export default  { average }

main.js

import A from './a.js'
import B from './b.js'
console.log(A.sum(1,2,3))
console.log(B.average(1,2,3))

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script type="module" src="./main.js"></script>
</body>
</html>

注意:

  • es6Module 不需要引入外部依賴,瀏覽器可以直接運行,但要告訴瀏覽器我是esModule規范,type='module'   <script type="module" src="./main.js"></script>
  • es6Module 瀏覽器不支持file協議,要在本地起一個服務,可以在vscode上裝一個live serve插件,給本地一個服務。

ES6 在語言標准的層面上,實現了模塊功能,而且實現得相當簡單,完全可以取代 CommonJS 和 AMD 規范,成為瀏覽器和服務器通用的模塊解決方案

特點:webpack 支持、瀏覽器也支持.        

CommonJS、ES6Module差異

  • CommonJs輸出的是一個值的拷貝,ES6輸出的是值的引用
  • CommonJs是運行時加載,ES Module是編譯時就確認了依賴關系

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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM