天天看點

javascript-子產品發展史

作者:重慶源碼時代

什麼是子產品?

所謂的子產品話就是将一個系統拆分成各個獨立的部分,每個部分實作一塊功能,然後組合在一起形成系統。這樣的有點如下:

  • 可維護
  • 可複用
  • 可組合

JavaScript 程式本來很小——在早期,它們大多被用來執行獨立的腳本任務,在你的 web 頁面需要的地方提供一定互動,是以一般不需要多大的腳本。過了幾年,我們現在有了運作大量 JavaScript 腳本的複雜程式,還有一些被用在其他環境

javascript-子產品發展史

有必要提供一種将 JavaScript 程式拆分為可按需導入的單獨子產品的機制,二這個機制就是子產品的規範,從js早期到現在,産生了很多的子產品規範。接下來一一介紹一下:

檔案劃分

一個js檔案即一個子產品,然後再該js檔案下定義子產品的資料方法。最終将各個子產品一script的方式引入到index.html中

優缺點:

  • 一定程度上實作了子產品劃分。
  • 變量同名
  • 變量方法來源不清晰
  • 依賴關系不明确

命名空間

命名空間的出現就是為了檔案劃分中,全局變量的問題。其實就是将每個檔案子產品下分散的資料和方法用對象包裝起來(對象的名字做到唯一唯一性就好),然後放再window上。

優缺點

  • 變量或者方法來源清晰了
  • 隻要人們按照一定規範命名,可以避免變量同名危險。
  • 不太安全,變量并沒有私有化。
  • 但是依賴關系還是有問題,也就是script的加載順序

IIFE

基于上訴不安全的原因,後來人們又提出了一個IIFE(立即執行函數)的方式,因為IIFE一運作就形成了一個私有的作用域,外界是沒辦法通路這個作用域下的變量的。

優缺點:

  • 比命名空間更加安全
  • 依賴關系還是無法解決。

CommonJS 規範(服務端-node)

最早比較正式的一個子產品規範,主要用于node中。module.exports導出, require導入。文法如下:

// commonjs規範           

特點如下:

  • 得到node的支援
  • 基于檔案的,一個檔案就是一個子產品。
  • 加載子產品是同步的

缺點如下:

  • CommonJS 的實作需要使用到node操作檔案的api,是以它并不能運作再浏覽器上
  • CommonJS 本身約定以同步的方式進行子產品加載,這種加載機制放在服務端是沒問題的,一來子產品都在本地,不需要進行網絡 IO,二來隻有服務啟動時才會加載子產品,而服務通常啟動後會一直運作,是以對服務的性能并沒有太大的影響。但如果這種加載機制放到浏覽器端,會帶來明顯的性能問題。它會産生大量同步的子產品請求,浏覽器要等待響應傳回後才能繼續解析子產品。也就是說,子產品請求會造成浏覽器 JS 解析過程的阻塞,導緻頁面加載速度緩慢。

AMD 規範

總之,CommonJS 是一個不太适合在浏覽器中運作的子產品規範,随後才又了AMD全稱為Asynchronous Module Definition,即異步子產品定義規範。子產品根據這個規範,在浏覽器環境中會被異步加載,而不會像 CommonJS 規範進行同步加載,也就不會産生同步請求導緻的浏覽器解析過程阻塞的問題了。

  • 使用define定義一個子產品
// main.js
define(["./print"], function (printModule) {
  printModule.print("main");
});

// print.js
define(function () {
  return {
    print: function (msg) {
      console.log("print " + msg);
    },
  };
});           
  • 使用require 加載一個子產品
// module-a.js
require(["./print.js"], function (printModule) {
  printModule.print("module-a");
});           

AMD規範并沒有得到浏覽器的支援,如果要再項目中使用,需要借助第三方的 loader 來實作,也就是require.js庫。例子如下:

總結:

  • AMD規範更加使用運作到浏覽器上,
  • 不過代碼閱讀和書寫都比較困難

UMD

相容 AMD 和 CommonJS 的一個子產品化方案,可以同時運作在浏覽器和 Node.js 環境。不做多的介紹,已經不流行了

ES6 Module

ES6 Module 也被稱作 ES Module(或 ESM), 是由 ECMAScript 官方提出的子產品化規範,作為一個官方提出的規範,ES Module 已經得到了現代浏覽器的内置支援。

ES Module 的相容性問題,其實 ES Module 的浏覽器相容性如今已經相當好了,覆寫了 90% 以上的浏覽器份額,

不僅如此,一直以 CommonJS 作為子產品标準的 Node.js 也緊跟 ES Module 的發展步伐,從 12.20 版本開始正式支援原生 ES Module。也就是說,如今 ES Module 能夠同時在浏覽器與 Node.js 環境中執行,擁有天然的跨平台能力。