js模塊化發展歷程 總結

前端技術變化太快了,新入坑的同窗每每會一臉懵逼,特此總結本身在學習過程當中對js模塊化這一方面的理解javascript

1、模塊化規範種類

image.png

2、發展歷史趨勢

image.png

step一、2002 - 命名空間模式

命名空間模式html

  • 大型項目仍是很差維護
  • 沒有解決模塊間依賴問題

step二、2009 - CommonJS

號召規範服務端的js接口,造成了ServerJs規範(即CommonJs)CommonJS 內的模塊規範成爲了 Node.js 的標準實現規範前端

  • require (同步下載的)
  • 隨着 Node.js 以及 Browserify 的流行,愈來愈多的開發者也接受了 CommonJS 規範

step三、2009年 - AMD 規範

關注js模塊的異步加載 提出 AMD 規範,require.js、curl是其對應實現java

  • 源自CommonJS,可是 異步的加載的
  • 模塊下載完後,當即執行加載,全部模塊加載完畢進入回調
  • 隨着以 npm (遵循CommonJS規範)爲主導的依賴管理機制的統一,愈來愈多的開發者放棄了使用 AMD 模式。

什麼是異步加載? 藍色是 下載文件  紅色是 加載js 綠色是解析html jquery

image.png

step四、2011年 - UMD規範

爲了支持一個模塊同時兼容AMD和CommonJs規範,適用於 同時支持瀏覽器端和服務端引用的第三方庫,提出了 UMD規範webpack

step五、2011年 - CMD規範

require.js 須要提早聲明 所依賴的庫,爲了作到 看起來"使用時才加載"(就近依賴),創造了sea.js,同時其對應CMD規範web

  • 下載完後,並不當即執行,回調函數中遇到require才執行加載模塊

step六、2015年 - ES2015 Modules

爸爸(ECMAScript 標準的起草者 TC39 委員會)不能坐視不理,推出了ES2015 Modules(import、export),最後有了ES6npm

  • 導入的值也是隻讀不可變對象(喪失了CommonJS的修改特性,但也是一個優勢,保證了 ES6 Modules 的依賴關係是肯定(Deterministic)的,和運行時的狀態無關,從而也就保證了 ES6 Modules 是能夠進行可靠的靜態分析的。),不像CommonJS是一個內存的拷貝

step七、終極奧義 - 現代工具webpack

webpack 本身實現了一套模塊機制,不管是 CommonJS 模塊的 require 語法仍是 ES6 模塊的 import 語法,都可以被解析並轉換成指定環境的可運行代碼。隨着webpack打包工具的流行,ES6語法普遍手中,後來的開發者對於 AMD CMD的感知愈來愈少瀏覽器

3、使用姿式

CommonJS

// file greeting.js 定義一個模塊
var helloInLang = {
    en: 'Hello world!',
    es: '¡Hola mundo!',
    ru: 'Привет мир!'
};

var sayHello = function (lang) {
    return helloInLang[lang];
}
// 對外輸出
module.exports.sayHello = sayHello;

// file hello.js 引入一個模塊
var sayHello = require('./lib/greeting').sayHello;
var phrase = sayHello('en');
console.log(phrase);
複製代碼

AMD

// file lib/greeting.js 定義一個模塊
define(function() {
    var helloInLang = {
        en: 'Hello world!',
        es: '¡Hola mundo!',
        ru: 'Привет мир!'
    };

    return {
        sayHello: function (lang) {
            return helloInLang[lang];
        }
    };
});

// file hello.js 引入一個模塊
define(['./lib/greeting'], function(greeting) {
    var phrase = greeting.sayHello('en');
    document.write(phrase);
});
複製代碼

UMD

// 定義一個模塊
(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['jquery', 'underscore'], factory);
    } else if (typeof exports === 'object') {
        // Node, CommonJS之類的
        module.exports = factory(require('jquery'), require('underscore'));
    } else {
        // 瀏覽器全局變量(root 即 window)
        root.returnExports = factory(root.jQuery, root._);
    }
}(this, function ($, _) {
    // 方法
    function a(){};    // 私有方法,由於它沒被返回 (見下面)
    function b(){};    // 公共方法,由於被返回了
    function c(){};    // 公共方法,由於被返回了

    // 暴露公共方法
    return {
        b: b,
        c: c
    }
}));
複製代碼

CMD

// 定義一個模塊

define(function(require, exports, module) {
   ....
})


//sea.js:
define(function(require, exports, module) {

    var mod_A = require("dep_A");
    var mod_B = require("dep_B");
    var mod_C = require("dep_C");
});
複製代碼

ES2015 Modules

// file lib/greeting.js 定義一個模塊
const helloInLang = {
    en: 'Hello world!',
    es: '¡Hola mundo!',
    ru: 'Привет мир!'
};
// 對外輸出
export const greeting = {
    sayHello: function (lang) {
        return helloInLang[lang];
    }
};

// file hello.js 引入一個模塊
import { greeting } from "./lib/greeting";
const phrase = greeting.sayHello("en");
document.write(phrase);
複製代碼

4、對比

AMD vs CMDcurl

AMD CMD
依賴前置
下載完後,執行加載,全部模塊加載完畢進入回調
就近依賴
下載完後,並不執行加載,回調函數中遇到require才執行加載

requre.js vs sea.js

require.js sea.js
RequireJS在實現AMD的同時,還提供了一個CommonJS包裹 專一於web

5、參考

javascript基礎修煉(4)——UMD規範的代碼推演
www.cnblogs.com/dashnowords…

JavaScript 模塊演化簡史
mp.weixin.qq.com/s?__biz=MjM…

前端模塊化
www.cnblogs.com/dolphinX/p/…

webpack 模塊加載機制
blog.csdn.net/weixin_3419…

前端模塊化(CommonJs,AMD和CMD)
www.jianshu.com/p/d67bc7997…

讓咱們再聊聊瀏覽器資源加載優化
www.infoq.cn/article/bro…

前端模塊化開發那點歷史
www.zhihu.com/question/20…

相關文章
相關標籤/搜索