RequireJsの使い方をまねて低配版のモジュールローダを書く

4283 ワード

RequireJsの使い方をまねて低配版のモジュールローダを書く
Contents
  • 前言
  • RequireJsの基本的な使い方を振り返る
  • 実現原理
  • 使用方法
  • まとめ
  • 前言
    この間ずっと1ページ開発技術で自分の個人サイトを書こうと思っていました(es 2015を使います)、一部を書いた後、1ページアプリケーションは1ページしかないのでindexを初めてロードしたことに気づきました.htmlではすべてのjsファイルをダウンロードし、各部分の状態を管理するためには、ページの各機能領域を各モジュールに分割する必要がある.es 2015自体は、AMD、CMD、CommonJsなどのモジュール仕様をサポートしていないため、このようなシミュレーションしか実現できない.
      // global
      var spa = (function(){...})();
    
      // module blog
      spa.blog = (function(){
        ...
        return {
          do1: do1,
          do2: do2,
        };
      })();
    
      // module model
      spa.model = (function(){...})();
    
      // module shell
      spa.model = (function(){...})();
    

    各モジュールの間にはindexでいくつかの依存関係がある.htmlにはscriptタグを書いてモジュールをロードする際に多くのことを書く必要があります.また、依存関係に基づいて書く順序を決めなければなりません.ページの論理が混乱しています.以下のようにします.
      
      
      
      
      
      
      
    

    RequireJs(ポピュラーなJavaScriptモジュールローダ)を ったことがありますが、これは じjsのアーキテクチャで かれているのでnode.js でも できます. は で1つの い のjsモジュールのローダrequireJs-nojsjaを いて のこの ページのウェブサイトに することを してみることができると って、もちろん な を しただけです.
    RequireJsの な い を り る
  • モジュール
  •   requirejs.config({
          baseUrl: '/javascripts',  //      
          paths: {
            moduleA: 'a.js',
            moduleB: 'b.js',
            moduleC: 'c.js',
          },
          shim: {  //      amd     
            moduleC: {
              exports: 'log',
              deps: ['moduleA']
            }
          },
      });
    
  • モジュール
  • を する
      define(name, ['moduleA', 'moduleB'], function(a, b){
        ...
        return {
          do: function() {
            a.doSomething();
            b.doAnother();
          }
        };
      });
    
  • は、モジュール
  • を する
      //     
      require(['moduleA', 'moduleB'], function(a, b) {
        a.doSomething();
        b.doAnother();
      });
    

  • configメソッドは、 モジュールの
  • を する.
      /*                   */
      Require.config({
        baseUrl: '/javascripts/',
        paths: {
          'moduleA': './moduleA.js',  //        
          'moduleB': '/javascripts/moduleB.js',  //    baseUrl
          'moduleC': 'moduleC.js',
    
          'moduleD': {
            url: 'moduleD.js',
            deps: ['moduleE', 'moduleF'],
          },
          ...
        },
        shim: {
          'moduleH': {
            url: 'moduleH.js',
            exports: 'log',
          },
        }
      });
    
  • データ プロセス
  • (1)config モジュール の 、indexにおいてネットワーク (2)はトリガーされない.jsメインエントリファイルでrequireメソッドを して のモジュールを する は、configプロファイルに づいてすべてのモジュールの ツリーを します.この ツリーを さ または さ で し、すべての を に1つの に し、 に が り されるため、 の を います.
      var dependsTree = new Tree('dependsTree');
      var dependsArray = [];
      var dependsFlag = {};  //       
    
      //    
      setDepends(depends, dependsTree);
      //       
      sortDepends(dependsArray, dependsTree);
      //     
      arrayFilter(dependsArray);
    
      return dependsArray;
    

    (3)XHRオブジェクト ダウンロード のすべてのjsファイルを し, にjsコードを1つずつ し, が するとコールバック をトリガし,コールバック に モジュールの を する.
      // ajax      
      Utils.request(url, 'get', null, function(responseText){
        //     
        _temp[module_name] = responseText;
      });
    
      //        eval    
      array.map(function(jsText){
        ...
        eval(jsText);
        ...
      });
    
      //       
      callback.apply(null, [dep1, dep2, dep3]);
    


    :github README.md
    まとめ
  • jsコードをダウンロードするときにajaxを って したので、ドメイン ファイルとCDNには し があります.これはscriptラベルを し、ラベルsrcを し、 にdocumentを することができます.head.appendChild(script)は、XMLhttpRequest 2.0、iframeなど、 のものを してもよいので、 してみてください.
  • でコードを するときにevalの を いましたが、このevalはJavaScriptの では あるので、これを てもいいですが、 にscriptタグを する を っていれば、 でevalを わなくてもいいです.
  • はバグを し、ループ がある 、コードが って され、まだ されていない.RequireJsは,モジュールaがbに し, にbがaに する ,bのモジュール が び されると, み まれるaはundefinedであるため, でbの で でaをrequireする がある.