前端模塊化之AMD/requireJS、CMD/seaJS

前言

請注意,如今是2019/05/22,這!不!是!墳!貼!,你沒!有!穿!越!!
爲了之後,可能須要搞一下之前的舊項目,本身也想玩玩,,,因此補一下舊時代的模塊化玩法。。。html

代碼:github地址前端

AMD/CMD/Common.js/UMD/ES6模塊化的主要區別

此前(2019年前前前前)前端模塊化,主流的就是AMD/CommonJS,支持UMD的兩者均可以用webpack

爲何模塊化?
git

  • 一直以來,前端開發的痛點之一就是 代碼複用/職責劃分 問題,兼容性好比ES6等新語法的支持/組件化/代碼壓縮等不在本文討論範圍。
  • 在這些 前端模塊化 的東西出現以前,都是用<script>標籤引入js,若是每一個頁面都 按模塊劃分 (好比全部變量方法都放在一個對象裏面)就不會形成全局變量污染,可是各類 js/模塊 的依賴關係就不明確了,並且有些暫時用不到的js,又會先下載,影響頁面加載速度。

同步/異步,靜態/動態

  • 同步:CMD/CommonJS/ES6import
  • 異步:AMD/CMDrequire.async
  • 靜態:編譯時執行;AMD/ES6import
  • 動態:運行時執行;CMD/CommonJS/ES6+ import()

運行環境:

  • 瀏覽器:AMD/CMD,ES6模塊化目前瀏覽器還不能原生支持,須要使用webpack/babel等編譯成瀏覽器支持的版本
  • 服務器:CommonJS:Node.js使用的模塊化規範

UMD:

  • 支持AMD/CommonJS的統一規範,使用UMD定義的模塊,能夠支持AMD和CommonJS

第三方庫:

  • 支持UMD的庫能夠在 AMD/CommonJS 上使用,CMD在這方面就稍微差一點;
  • 喜歡CommonJS模塊寫法的,CMD卻是個不錯的選擇

1、AMD/require.js

什麼是AMD?

  • AMD: Asynchronous Module Definition,中文名是 異步模塊定義 的意思
  • 依賴前置,define的時候就引入,而後做爲回調函數的參數使用
  • 第三方庫支持較多,相對的CMD支持的就比較少,如這裏使用的 lodash.js 庫(或者我沒配置對。。。)
  • 使用 return 的方式導出

如下使用require.js v2.3.6示例:github

目錄結構:

...\require.js-AMD
    ├─ index.html
    ├─ js
      ├─ lodash.js
      ├─ m1.js
      └─ m2.js
    ├─ main.js
    └─ require.js
複製代碼

HTML

<script src="./require.js" data-main="./main.js"></script>
複製代碼

入口 main.js

// js/mian.js
// 全局配置
require.config({
  // 根路徑設置,paths下面所有都是根據baseUrl的路徑去設置
  baseUrl:'./js',
  paths: { // 定義引用時名稱對應的路徑
    m1: 'm1',
    m2: 'm2',
    lodash: 'lodash'
  },
  // 用來配置不兼容的模塊,沒有module.exports的第三方庫(未驗證。。。)
  // shim:{
  // 'lodash': {
  // exports: '_'
  // }
  // }
})

define('main', function() {
  require(['m1'], function(m1) {
    console.log('name: ', m1.name);
    console.log('add: ', m1.add(2, 8));
  });
})

複製代碼

模塊定義

define函數格式: define(id?, dependencies?, factory);web

// js/m1.js
// define(id?, dependencies?, factory);
define('m1', ['lodash', 'm2'], function(_, m2) {
  
  _.map([1,2], function(num){
    console.log('num: ', num);
  });

  console.log(m2);

  var add = function(x, y) {
    return x + y;
  };

  return {
    name: 'm1.js',
    add: add
  };
})

複製代碼

2、CMD/sea.js

什麼是CMD?

  • 在瀏覽器端的CommonJS(除去某些Node.js環境特有的API);同步、動態加載;
  • 依賴就近,哪裏須要哪裏require
  • 異步引入 require.async([dependencies], callback)
  • 使用 exports/module.exports 方式導出

如下使用sea.js v3.0.0示例:瀏覽器

目錄結構:

...\sea.js--CMD
    ├─ index.html
    ├─ js
      ├─ lodash.js
      ├─ m1.js
      └─ m2.js
    ├─ main.js
    └─ sea.js
複製代碼

HTML

<script src="./js/lodash.js"></script>
  <script src="./sea.js"></script>
  <script> // 配置 seajs.config({ base: './', // 後續引用基於此路徑 alias: { // 別名,能夠用一個名稱 替代路徑(基於base路徑) lodash: 'js/lodash.js', m1: 'js/m1', m2: 'js/m2', }, }); // 加載入口模塊 seajs.use("./main.js", function(main) { // 執行完 main.js導出(exports/module.exports)以前的同步操做以後的 回調 main.init(); // init }); </script>
複製代碼

入口 main.js

// js/mian.js
define(function(require, exports, module) {
  var m1 = require('m1');
  console.log(m1.add(2,8));

  // 單獨導出
  exports.init = function init() {
    console.log('init');
  }

  // 或者 先定義,再統一導出
  // function init() {
  // console.log('init');
  // }
  // module.exports = {
  // init: init
  // }
});

複製代碼

模塊定義

define函數格式: define(function(require, exports, module) {})bash

// js/m1.js
define(function(require, exports, module) {
  // 使用第三方庫 lodash.js,script標籤導入
  // 優先require,否則使用script
  _.map([1,2], function(item) {
    console.log(item);
  })

  // 異步引入
  require.async('m2', function(m2) {
    console.log('異步引入 m2');
  }); // m2

  // 每一個函數單獨導出
  exports.add = function(x, y) {
    return x + y;
  }

  // 或者 先定義,再統一導出
  // function add(x, y) {
  // return x + y;
  // }
  // modules.exports = {
  // add: add
  // }
});

複製代碼
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息