说起来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也同步做了修改,方便有需要的小伙伴测试。
示例地址:
因为内部使用版本已发公网npm,占用了seajs-amd命名空间,此fork仅用作源码分享,并没有publish到npm