亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

模仿RequireJs的用法實(shí)現(xiàn)一個(gè)低配版的模塊加載器

WalkerXu / 1159人閱讀

摘要:我想自己可以嘗試一下寫一個(gè)低配版的模塊加載器來(lái)應(yīng)付一下我這個(gè)單頁(yè)網(wǎng)站,當(dāng)然只是大致模仿了主要功能。是這樣處理的模塊依賴,同時(shí)依賴,這種情況下的模塊函數(shù)被調(diào)用時(shí),被傳入的是,所以需要自己在里面手動(dòng)一下。

Contents

前言

回顧RequireJs的基本用法

實(shí)現(xiàn)原理

使用方法

總結(jié)

前言

前段時(shí)間一直想用單頁(yè)開發(fā)技術(shù)寫一個(gè)自己的個(gè)人網(wǎng)站(使用es2015),寫了一部分之后,發(fā)現(xiàn)單頁(yè)應(yīng)用因?yàn)橹挥幸粋€(gè)頁(yè)面,所以第一次加載index.html時(shí)就要下載所有js文件,并且為了好管理各個(gè)部分的狀態(tài),需要?jiǎng)澐猪?yè)面的各個(gè)功能區(qū)為各個(gè)模塊,es2015本身是不支持一些模塊規(guī)范的(比如AMD、CMD、CommonJs等),所以只能這樣模擬實(shí)現(xiàn):

  // global
  var spa = (function(){...})();

  // module blog
  spa.blog = (function(){
    ...
    return {
      do1: do1,
      do2: do2,
    };
  })();

  // module model
  spa.model = (function(){...})();

  // module shell
  spa.model = (function(){...})();

并且各個(gè)模塊之間又存在一些依賴關(guān)系,在index.html里面寫script標(biāo)簽來(lái)載入模塊時(shí)需要寫很多個(gè),同時(shí)也要根據(jù)依賴關(guān)系來(lái)確定書寫順序,頁(yè)面邏輯混亂,如下:

  
  
  
  
  
  
  

之前用過(guò)RequireJs(一個(gè)流行的JavaScript模塊加載器),它是用同構(gòu)js的架構(gòu)來(lái)寫的,所以node.js環(huán)境下也能使用。我想自己可以嘗試一下寫一個(gè)低配版的js模塊加載器 requireJs-nojsja 來(lái)應(yīng)付一下我這個(gè)單頁(yè)網(wǎng)站,當(dāng)然只是大致模仿了主要功能。

回顧RequireJs的基本用法 1. 配置模塊信息
      requirejs.config({
          baseUrl: "/javascripts",  // 配置根目錄
          paths: {
            moduleA: "a.js",
            moduleB: "b.js",
            moduleC: "c.js",
          },
          shim: {  // 配置不遵循amd規(guī)范的模塊
            moduleC: {
              exports: "log",
              deps: ["moduleA"]
            }
          },
      });
2. 定義一個(gè)模塊
  define(name, ["moduleA", "moduleB"], function(a, b){
    ...
    return {
      do: function() {
        a.doSomething();
        b.doAnother();
      }
    };
  });
3. 引用一個(gè)模塊
  // 引用模塊
  require(["moduleA", "moduleB"], function(a, b) {
    a.doSomething();
    b.doAnother();
  });
實(shí)現(xiàn)原理 1. config方法確定各個(gè)模塊的依賴關(guān)系
  /* 記錄模塊訪問(wèn)地址和模塊的依賴等信息 */
  Require.config({
    baseUrl: "/javascripts/",
    paths: {
      "moduleA": "./moduleA.js",  // 相對(duì)于當(dāng)前目錄
      "moduleB": "/javascripts/moduleB.js",  // 不使用baseUrl
      "moduleC": "moduleC.js",

      "moduleD": {
        url: "moduleD.js",
        deps: ["moduleE", "moduleF"],
      },
      ...
    },
    shim: {
      "moduleH": {
        url: "moduleH.js",
        exports: "log",
      },
    }
  });
2. 數(shù)據(jù)請(qǐng)求請(qǐng)求過(guò)程分析

(1) config配置模塊信息時(shí)并不會(huì)觸發(fā)網(wǎng)絡(luò)請(qǐng)求
(2) 在index.js主入口文件里使用require方法引用多個(gè)模塊時(shí),根據(jù)config配置文件構(gòu)造一下所有模塊的依賴分析樹。按深度優(yōu)先或是廣度優(yōu)先來(lái)遍歷這個(gè)依賴樹,將所有依賴按照依賴順序放進(jìn)一個(gè)數(shù)組,最后進(jìn)行數(shù)組去重處理,因?yàn)闀?huì)出現(xiàn)依賴重復(fù)的情況

  var dependsTree = new Tree("dependsTree");
  var dependsArray = [];
  var dependsFlag = {};  // 解決循環(huán)依賴

  // 創(chuàng)建樹
  setDepends(depends, dependsTree);
  // 得到依賴數(shù)組
  sortDepends(dependsArray, dependsTree);
  // 數(shù)據(jù)去重
  arrayFilter(dependsArray);

  return dependsArray;

(3) 創(chuàng)建XHR對(duì)象異步下載數(shù)組里面的所有js文件,按照依賴順序挨個(gè)解析js代碼,解析完成后觸發(fā)回調(diào)函數(shù),回調(diào)函數(shù)里傳入各個(gè)模塊的引用

  // ajax下載代碼文件
  Utils.request(url, "get", null, function(responseText){
    // 暫時(shí)保存
    _temp[module_name] = responseText;
  });
    
  // 文件下載完成后eval解析代碼
  array.map(function(jsText){
    ...
    eval(jsText);
    ...
  });
    
  // 調(diào)用回調(diào)函數(shù)
  callback.apply(null, [dep1, dep2, dep3]);
使用方法

詳細(xì)說(shuō)明: github README.md

總結(jié)

下載js代碼時(shí)我用了ajax來(lái)實(shí)現(xiàn),所以對(duì)于跨域文件和CDN會(huì)有點(diǎn)問(wèn)題,這個(gè)可以改成創(chuàng)建script標(biāo)簽,指定標(biāo)簽src,最后將document.head.appendChild(script),這樣來(lái)解決,其它的諸如使用XMLHttpRequest 2.0,iframe等也可以的,可以實(shí)驗(yàn)一下。

解析代碼時(shí)我用了eval的方法,這個(gè)eval在JavaScript里面是眾說(shuō)紛紜,可以看看這個(gè),如果是用了上面創(chuàng)建script標(biāo)簽的方法的話,就不用自己eval了。

發(fā)現(xiàn)一個(gè)bug,存在循環(huán)依賴時(shí),代碼會(huì)報(bào)錯(cuò),還沒去解決。RequireJs是這樣處理的:模塊a依賴b,同時(shí)b依賴a,這種情況下b的模塊函數(shù)被調(diào)用時(shí),被傳入的a是undefined,所以需要自己在b里面手動(dòng)require一下a。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/92469.html

相關(guān)文章

  • 【教學(xué)向】再加150行代碼教你實(shí)現(xiàn)一個(gè)配版web component庫(kù)(1) —設(shè)計(jì)篇

    摘要:為的內(nèi)置一個(gè)方法,用法和原生的事件機(jī)制一毛一樣。 前言 上兩篇Mvvm教程的熱度超出我的預(yù)期,很多碼友留言表?yè)P(yáng)同時(shí)希望我繼續(xù)出下一篇教程,當(dāng)時(shí)我也半開玩笑說(shuō)只要點(diǎn)贊超10就兌現(xiàn)承諾,沒想到還真破了10,所以就有了今天的文章。 準(zhǔn)備工作 熟讀 【教學(xué)向】150行代碼教你實(shí)現(xiàn)一個(gè)低配版的MVVM庫(kù)(1)- 原理篇【教學(xué)向】150行代碼教你實(shí)現(xiàn)一個(gè)低配版的MVVM庫(kù)(2)- 代碼篇 本篇是在...

    Clect 評(píng)論0 收藏0
  • 【教學(xué)向】150行代碼教你實(shí)現(xiàn)一個(gè)配版MVVM庫(kù)(2)- 代碼篇

    摘要:也放出地址,上面有完整工程以及在線演示地址相關(guān)閱讀教學(xué)向行代碼教你實(shí)現(xiàn)一個(gè)低配版的庫(kù)原理篇教學(xué)向行代碼教你實(shí)現(xiàn)一個(gè)低配版的庫(kù)代碼篇教學(xué)向再加行代碼教你實(shí)現(xiàn)一個(gè)低配版的庫(kù)設(shè)計(jì)篇教學(xué)向再加行代碼教你實(shí)現(xiàn)一個(gè)低配版的庫(kù)原理篇 書接上一篇: 150行代碼教你實(shí)現(xiàn)一個(gè)低配版的MVVM庫(kù)(1)- 原理篇 寫在前面 為了便于分模塊,和閱讀,我使用了Typescript來(lái)進(jìn)行coding,總行數(shù)是正好...

    loonggg 評(píng)論0 收藏0
  • 【教學(xué)向】150行代碼教你實(shí)現(xiàn)一個(gè)配版MVVM庫(kù)(1)- 原理篇

    摘要:模塊則負(fù)責(zé)維護(hù),以及各個(gè)模塊間的調(diào)度思考題了解了的實(shí)現(xiàn)機(jī)制,你能否自己動(dòng)手也試著用百來(lái)行代碼實(shí)現(xiàn)一個(gè)庫(kù)呢好了本教程第一部分設(shè)計(jì)篇就寫到這里,具體請(qǐng)移步下一篇教學(xué)向行代碼教你實(shí)現(xiàn)一個(gè)低配版的庫(kù)代碼篇我會(huì)用給出一版實(shí)現(xiàn)。 適讀人群 本文適合對(duì)MVVM有一定了解(如有主流框架ng,vue等使用經(jīng)驗(yàn)配合本文服用則效果更佳),雖然會(huì)用這類框架,但是對(duì)框架底層核心實(shí)現(xiàn)又不太清楚,或者能說(shuō)出個(gè)所以然...

    selfimpr 評(píng)論0 收藏0
  • 基于canvas和web audio實(shí)現(xiàn)配版MikuTap

    摘要:導(dǎo)言最近發(fā)掘了一個(gè)特別的網(wǎng)頁(yè)小游戲。于是第二天我就繼續(xù)沉迷,隨著一陣抽搐,這個(gè)游戲索然無(wú)味之后,冷靜的我決定用和開發(fā)出一個(gè)低配版。我的低配版在交互操作比較高的情況下,還是比較卡的,沒有原網(wǎng)頁(yè)的流暢性,可能后續(xù)考慮版本實(shí)現(xiàn)。 導(dǎo)言 最近發(fā)掘了一個(gè)特別happy的網(wǎng)頁(yè)小游戲--MikuTap。打開之后沉迷了一下午,導(dǎo)致開發(fā)工作沒做完差點(diǎn)就要?jiǎng)h庫(kù)跑路了,還好boss瞥了我一眼就沒下文了。于是...

    Awbeci 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<