关于javascript:JS模块化-AMD

8次阅读

共计 1717 个字符,预计需要花费 5 分钟才能阅读完成。

AMD usage

    define(id?, depencies?, factory);

    define('foo', ['utils'], function(utils){utils.add(1, 2);
        return {name: 'foo'}
    })

实现一个合乎 AMD 的 rj.js

  1. 能够间接配置依赖门路
    rj.confing({
        paths: {'jquery': '...'}
    })
  1. 加载模块
    // RequireJs('')
    rj(['moduleA'], function(moduleA) {})
  1. 定义模块
    rj('moduleA', [], function() {return 'hello world';})

行为

    define('a', function() {console.log('a load');
        return {run: function() {console.log('a run') }
        }
    })
    define('b', function() {console.log('b load');
        return {run: function() {console.log('b run') }
        }
    })

    require(['a', 'b'], function(a, b) {console.log('main run');    
        a.run();
        b.run();})

    // a load
    // b load
    // main load
    // a run
    // b run

rj.js 简略实现

  // 默认配置
  const defaultOptions = {paths: ''}

  const def = new Map();

  const rj = {};

  // config
  rj.config = (options) => Object.assign(defaultOptions, options);

  // from CDN
  const __import = (url) => {return new Promise((resolve, reject) => {System.import(url).then(resolve, reject);
      }) 
  }

  // normal script
  const __load = (url) => {return new Promise((resolve, reject) => {const header = document.getElementsByTagName("header")[0];
          const script = document.createElement('script');
          script.async = true;
          script.src = url;
          script.type = 'text/javascript';
          script.onload = resolve;
          script.onerror = reject;
          header.appendChild(script);
      }) 
  }

  // 获取地址
  // dep -> a -> a.js -> http:xxx/xx/xx/a.js
  const __getUrl = (dep) => {
      const p = location.pathname;
      return p.slice(0, p.lastIndexOf('/')) + '/' + dep + 'js';
  }

  // 定义模块 增加依赖
  const define = (name, deps, factory) => {def.set(name, {name, deps, factory});
  }

  // 触发依赖
  const require = (deps, factory) => {return new Promise((resolve, reject) => {
          Promise.all(deps.map(dep => {
              // 走 CDN
              if(defaultOptions.paths[dep]) __import(defaultOptions.paths[dep]);

              return __load(__getUrl(dep)).then(() => {const {deps, factory} = def.get(dep);
                  if(deps.length == 0) return factory(null);
                  return require(deps, factory);
              })
          })).then(resolve, reject);
      }).then(instance => factory(...instance));
  }

正文完
 0