说起来seajs,早些年接触前端的同学应该都有所了解,经常被我们拿来和requirejs对比,而今,webpack等构建工具盛行,这些加载器的使用逐渐退出了我们的视野。

但是,目前手上就有个在用webpack的项目遇到了一些问题——不能在构建阶段拿到或者预期到即将加载的代码有哪些,换句话说页面框架的构建与业务代码是完全分离的,甚至不是同一个团队写的。于是想到了早期的模块化方案,我们知道,webpack支持打包umd、commonjs2、amd等形式的输出物,但是,在web端我们的选择只有amd。

团队在早些年用惯了seajs,也喜欢其小巧,对比了requirejs后,决定还是沿用seajs。于是,就有了让seajs支持amd风格的改造,最初内部改造,为了方便分享,在官方仓库fork了一份,但seajs和requirejs类似,上次提交都是很久之前了,甚至seajs的构建脚本都跑不起来,直接改了源码。

seajs的define本质上和amd已无差异,就是factory参数不是amd形式。话不多说,直接上代码。

// 先单独写一个执行模块的函数
function execDependencies(mod) {
  var dependencies = (mod && mod.dependencies) || []
  var len = dependencies.length
  var deps = []
  for (var i = 0; i < len; i++) {
    var m = mod.deps[dependencies[i]]
    deps[i] = m && m.exec()
  }
  return deps
}

找到 src/module.js 200 – 202 行,这里就是seajs执行代码时的factory,我们主动执行所有模块即可

var exports = isFunction(factory) 
    factory.call(mod.exports = {}, require, mod.exports, mod) :
    factory
// 改造为如下形式,execDependencies 内容如下
var exports = isFunction(factory) ?
    factory.apply(mod.exports = {}, execDependencies(mod)) :
    factory

改造完毕,因为项目内使用的版本包含一些内部需要的其他改造,而为分享fork的官方库不能构建( 不想折腾官方的seatools ),在dist目录的sea-debug.js也同步做了修改,方便有需要的小伙伴测试。

示例地址: https://github.com/weizs/seajs-amd

因为内部使用版本已发公网npm,占用了seajs-amd命名空间,此fork仅用作源码分享,并没有publish到npm