<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          可能是最詳細(xì)的UMD模塊入門指南

          共 9978字,需瀏覽 20分鐘

           ·

          2021-03-09 21:35

          點(diǎn)擊上方藍(lán)字“前端司南”關(guān)注我
          您的關(guān)注意義重大

          原創(chuàng)@前端司南

          學(xué)習(xí)UMD

          介紹

          這個(gè)倉庫[1]記錄了一些關(guān)于javascript UMD模塊規(guī)范的demo,對我學(xué)習(xí)UMD規(guī)范有了很大幫助,希望也能幫助到你。

          回顧

          之前也寫了幾篇關(guān)于javascript模塊的博客,鏈接如下:

          • 回頭再看JS模塊化編程[2]
          • 回頭再看JS模塊化編程之AMD[3]
          • sea.js的同步魔法[4]

          近幾天準(zhǔn)備總結(jié)一下javascript模塊的知識點(diǎn),所以建了這個(gè)Git倉庫[5],如果能幫助到您,麻煩點(diǎn)個(gè)star哦,非常感謝!

          這篇博客主要說下自己關(guān)于UMD的一點(diǎn)認(rèn)知和思考,從實(shí)現(xiàn)一個(gè)簡單的UMD模塊,再到實(shí)現(xiàn)一個(gè)有依賴關(guān)系的UMD模塊,整個(gè)過程加深了我對UMD模塊的理解。

          什么是UMD

          所謂UMD (Universal Module Definition),就是一種javascript通用模塊定義規(guī)范,讓你的模塊能在javascript所有運(yùn)行環(huán)境中發(fā)揮作用。

          簡單UMD模塊的實(shí)現(xiàn)

          實(shí)現(xiàn)一個(gè)UMD模塊,就要考慮現(xiàn)有的主流javascript模塊規(guī)范了,如CommonJS, AMD, CMD等。那么如何才能同時(shí)滿足這幾種規(guī)范呢?

          首先要想到,模塊最終是要導(dǎo)出一個(gè)對象,函數(shù),或者變量。

          而不同的模塊規(guī)范,關(guān)于模塊導(dǎo)出這部分的定義是完全不一樣的。

          因此,我們需要一種過渡機(jī)制。

          首先,我們需要一個(gè)factory,也就是工廠函數(shù),它只負(fù)責(zé)返回你需要導(dǎo)出的內(nèi)容(對象,函數(shù),變量等)。

          我們從導(dǎo)出一個(gè)簡單的對象開始。

          function factory({
              return {
                  name'我是一個(gè)umd模塊'
              }
          }

          全局對象掛載屬性

          假設(shè)不考慮CommonJS, AMD, CMD,僅僅將這個(gè)模塊作為全局對象的一個(gè)屬性應(yīng)該怎么寫呢?

          (function(root, factory{
              console.log('沒有模塊環(huán)境,直接掛載在全局對象上')
              root.umdModule = factory();
          }(thisfunction({
              return {
                  name'我是一個(gè)umd模塊'
              }
          }))

          我們把factory寫成一個(gè)匿名函數(shù),利用IIFE(立即執(zhí)行函數(shù))去執(zhí)行工廠函數(shù),返回的對象賦值給root.umdModule,這里的root就是指向全局對象this,其值可能是window或者global,視運(yùn)行環(huán)境而定。

          打開效果頁面鏈接[6](要看源碼的話,點(diǎn)開Git倉庫[7]),觀察Network的文件加載順序,可以看到,原則就是依賴先行。

          再進(jìn)一步,兼容AMD規(guī)范

          要兼容AMD也簡單,判斷一下環(huán)境,是否滿足AMD規(guī)范。如果滿足,則使用require.js提供的define函數(shù)定義模塊。

          (function(root, factory{
              if (typeof define === 'function' && define.amd) {
                  // 如果環(huán)境中有define函數(shù),并且define函數(shù)具備amd屬性,則可以判斷當(dāng)前環(huán)境滿足AMD規(guī)范
                  console.log('是AMD模塊規(guī)范,如require.js')
                  define(factory)
              } else {
                  console.log('沒有模塊環(huán)境,直接掛載在全局對象上')
                  root.umdModule = factory();
              }
          }(thisfunction({
              return {
                  name'我是一個(gè)umd模塊'
              }
          }))

          打開效果頁面鏈接[8],可以看到,原則是調(diào)用者先加載,所依賴的模塊后加載。

          起飛,直接UMD

          同理,接著判斷當(dāng)前環(huán)境是否滿足CommonJSCMD規(guī)范,分別使用相應(yīng)的模塊定義方法進(jìn)行模塊定義。

          (function(root, factory{
              if (typeof module === 'object' && typeof module.exports === 'object') {
                  console.log('是commonjs模塊規(guī)范,nodejs環(huán)境')
                  module.exports = factory();
              } else if (typeof define === 'function' && define.amd) {
                  console.log('是AMD模塊規(guī)范,如require.js')
                  define(factory())
              } else if (typeof define === 'function' && define.cmd) {
                  console.log('是CMD模塊規(guī)范,如sea.js')
                  define(function(require, exports, module{
                      module.exports = factory()
                  })
              } else {
                  console.log('沒有模塊環(huán)境,直接掛載在全局對象上')
                  root.umdModule = factory();
              }
          }(thisfunction({
              return {
                  name'我是一個(gè)umd模塊'
              }
          }))

          最終,使用require.js, sea.js, nodejs或全局對象掛載屬性等方式都能完美地使用umd-module.js這個(gè)模塊,實(shí)現(xiàn)了大一統(tǒng)。

          給個(gè)sea.js調(diào)用UMD的效果頁面鏈接,sea.js調(diào)用UMD模塊[9]

          nodejs調(diào)用UMD模塊需要執(zhí)行node命令,

          node umd-simple-used-by-nodejs

          效果如下:

          有依賴關(guān)系的UMD模塊

          當(dāng)然,我們不能止步于此,模塊會被調(diào)用,當(dāng)然也會調(diào)用其他模塊。因此我們還需要實(shí)現(xiàn)一個(gè)有依賴關(guān)系的UMD模塊,來驗(yàn)證UMD規(guī)范的可行性。

          全局對象掛載屬性

          這個(gè)簡單,在html中你的模塊前引入所依賴的模塊即可。umd-module-dependedumd-module都是UMD模塊,后者依賴前者。

          <!DOCTYPE html>
          <html>
              <head>
                  <title>Test UMD</title>
                  <!-- 依賴放前面 -->
                  <script src="assets/js/umd-dep/umd-module-depended.js"></script>
                  <script src="assets/js/umd-dep/umd-module.js"></script>
                  <script src="assets/js/umd-dep/umd-global.js"></script>
              </head>
              <body>
                  <h1>測試UMD模塊</h1>
                  <h2></h2>
                  <p id="content"></p>
                  <p id="content2"></p>
              </body>
          </html>

          點(diǎn)開效果頁面鏈接[10],看得更清楚明白!

          兼容AMD規(guī)范

          我們先在入口文件umd-main-requirejs.js中,定義好模塊路徑,方便調(diào)用。

          require.config({
              baseUrl"./assets/js/umd-dep/",
              paths: {
                  umd"umd-module",
                  depModule"umd-module-depended"
              }
          });

          被依賴的模塊umd-module-depended,只需要簡單實(shí)現(xiàn)UMD規(guī)范即可。

          而調(diào)用者umd-module,則需要做一些處理。按照require.js的規(guī)范來即可, define時(shí),指定依賴的模塊depModule,而匿名工廠函數(shù)需要在參數(shù)上接收依賴的模塊depModule

          (function(root, factory{
              if (typeof define === 'function' && define.amd) {
                  console.log('是AMD模塊規(guī)范,如require.js')
                  define(['depModule'], factory)
              } else {
                  console.log('沒有模塊環(huán)境,直接掛載在全局對象上')
                  root.umdModule = factory(root.depModule);
              }
          }(thisfunction(depModule{
              console.log('我調(diào)用了依賴模塊', depModule)
              // ...省略了一些代碼,去代碼倉庫看吧
              return {
                  name'我自己是一個(gè)umd模塊'
              }
          }))

          打開效果頁面鏈接[11],看得更清楚明白!

          UMD依賴寫法

          同理,各種規(guī)范要求你怎么寫模塊依賴,你就怎么寫就行。

          (function(root, factory{
              if (typeof module === 'object' && typeof module.exports === 'object') {
                  console.log('是commonjs模塊規(guī)范,nodejs環(huán)境')
                  var depModule = require('./umd-module-depended')
                  module.exports = factory(depModule);
              } else if (typeof define === 'function' && define.amd) {
                  console.log('是AMD模塊規(guī)范,如require.js')
                  define(['depModule'], factory)
              } else if (typeof define === 'function' && define.cmd) {
                  console.log('是CMD模塊規(guī)范,如sea.js')
                  define(function(require, exports, module{
                      var depModule = require('depModule')
                      module.exports = factory(depModule)
                  })
              } else {
                  console.log('沒有模塊環(huán)境,直接掛載在全局對象上')
                  root.umdModule = factory(root.depModule);
              }
          }(thisfunction(depModule{
              console.log('我調(diào)用了依賴模塊', depModule)
           // ...省略了一些代碼,去代碼倉庫看吧
              return {
                  name'我自己是一個(gè)umd模塊'
              }
          }))

          給個(gè)sea.js調(diào)用的示例鏈接[12]

          nodejs調(diào)用也是通過命令行測試,

          node umd-dep-used-by-nodejs

          效果如下:

          總結(jié)

          以上實(shí)現(xiàn)了簡單的UMD模塊,也驗(yàn)證了UMD模塊間存在依賴關(guān)系時(shí)的可行性。雖然本文是以簡單對象導(dǎo)出為例,但足以作為我們深入UMD規(guī)范的起點(diǎn),加油!

          最后厚著臉皮求個(gè)star點(diǎn)亮我吧[13]

          參考

          [1]

          倉庫: https://github.com/cumt-robin/umd-learning

          [2]

          回頭再看JS模塊化編程: http://hexo.wbjiang.cn/%E5%9B%9E%E5%A4%B4%E5%86%8D%E7%9C%8BJS%E6%A8%A1%E5%9D%97%E5%8C%96%E7%BC%96%E7%A8%8B.html

          [3]

          回頭再看JS模塊化編程之AMD: http://hexo.wbjiang.cn/%E5%9B%9E%E5%A4%B4%E5%86%8D%E7%9C%8BJS%E6%A8%A1%E5%9D%97%E5%8C%96%E7%BC%96%E7%A8%8B%E4%B9%8BAMD.html

          [4]

          sea.js的同步魔法: http://hexo.wbjiang.cn/sea.js%E7%9A%84%E5%90%8C%E6%AD%A5%E9%AD%94%E6%B3%95.html

          [5]

          Git倉庫: https://github.com/cumt-robin/umd-learning

          [6]

          效果頁面鏈接: https://cumt-robin.github.io/umd-learning/umd-simple-used-by-global.html

          [7]

          Git倉庫: https://github.com/cumt-robin/umd-learning

          [8]

          效果頁面鏈接: https://cumt-robin.github.io/umd-learning/umd-simple-used-by-requirejs.html

          [9]

          sea.js調(diào)用UMD模塊: https://cumt-robin.github.io/umd-learning/umd-simple-used-by-seajs.html

          [10]

          效果頁面鏈接: https://cumt-robin.github.io/umd-learning/umd-dep-used-by-global.html

          [11]

          效果頁面鏈接: https://cumt-robin.github.io/umd-learning/umd-dep-used-by-requirejs.html

          [12]

          示例鏈接: https://cumt-robin.github.io/umd-learning/umd-dep-used-by-seajs.html

          [13]

          點(diǎn)亮我吧: https://github.com/cumt-robin/umd-learning


          END



          如果覺得這篇文章還不錯(cuò)
          點(diǎn)擊下面卡片關(guān)注我
          來個(gè)【分享、點(diǎn)贊、在看】三連支持一下吧


             “分享、點(diǎn)贊在看” 支持一波  

          瀏覽 49
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久久久久久性 | 婷婷伊人九色在线 | 一道本一区二区三区免费视频 | 国产不卡一二三 | 婷婷丁香五月亚洲 |