首页 > 代码库 > 浏览器端的javascript加载器

浏览器端的javascript加载器

  commonJS,定义了一种同步加载脚本的规范。对于浏览器端而言,因为js脚本都是在远端,用同步的方式可能会长时间阻塞线程。因此,浏览器端的js加载器并不会严格按照commonJS来做。seajs作为一个试图遵循commonJS规范的加载器,是在规范的基础上在外面包一层define,来异步加载js,以下是seajs官网的一个例子:

// 所有模块都通过 define 来定义define(function(require, exports, module) {  // 通过 require 引入依赖  var $ = require(‘jquery‘);  var Spinning = require(‘./spinning‘);  // 通过 exports 对外提供接口  exports.doSomething = ...  // 或者通过 module.exports 提供整个接口  module.exports = ...});

define为回调提供一个获取模块的函数require、两个提供对外接口的对象exports和module。可以看到,模块的依赖是通过调用require来声明的。seajs会用正则把依赖的模块抓取出来,进行加载。为了正确的抓取,seajs定义了一些书写规范。定义模块之后,使用seajs.use使用定义的模块。

  requirejs作为一个遵循AMD规范的加载器。其在全局内定义了两个变量,define和require。可以用以下方式定义一个模块:

define(‘module‘,["alpha"], function (alpha) {       return {         verb: function(){           return alpha.verb() + 2;         }       };   });

同样也可以用类似seajs那样的定义方式。requirejs用以下方式引用一个模块:

require([‘module‘],function(module){    console.log(module);}) ;

  对于seajs和requirejs,一个js文件内只能有一个define函数,也就是说一个js文件对应一个模块。requirejs会在加载完一个模块后,马上执行。而seajs会在加载完执行require时执行模块。

  seajs和requirejs还有一些不同。requirejs有shim机制去支持那些不符合AMD规范的模块,seajs本来没有shim机制,之后又加上,最新版又删除了这个功能。requirejs支持webworker,seajs需要第三方的插件支持。

  如果需要实现一个加载器,最需要处理的是模块之间的触发关系。一个模块如果依赖别的模块,就需要等到依赖的模块都准备好了,该模块才处于可用的状态。依赖的模块也有可能有其所依赖的模块。所以需要建立一个触发的机制,让模块在已准备的状态下触发对其依赖的模块,使其检查自身的依赖模块是否都已准备好。seajs和requirejs对这个的实现方式有所不同。这里是我实现的一个版本:github地址。

  

浏览器端的javascript加载器