我想要的打包目标是:将模块合并,同时实现只需要简单修改的配置就能在发布版和调试版之间切换。
我的CMD模块文件
src/modules/module-1.js
src/modules/module-2.js
//src/modules/module-all.js
src/modules/startup.js
我想要的目标文件是
dist/modules/module-all.js
dist/modules/startup.js
首页文件 index.html
<script type="text/javascript">
seajs.config({
base: "/scripts/",
//paths: {
// "modules": "dist/modules",
//},
map: [[".js", ".js?v=" + 123]],//这样子更新版本号就很方便了
});
console.log("startup");
seajs.use([‘modules/startup‘], function (s) {s.show() });//‘zepto‘,‘spa‘,
</script>
当我们想切换成发布版时只需要把paths注释去掉就可以了。
//切换成发布版
<script type="text/javascript">
seajs.config({
base: ""/scripts/")",
paths: {
"modules": "dist/modules",
},
map: [[".js", ".js?v=" + 123]],//这样子更新版本号就很方便了
});
console.log("startup");
seajs.use([‘modules/startup‘], function (s) {s.show() });//‘zepto‘,‘spa‘,
</script>
各js文件
//src/modules/module-1.js
define(function (require, exports, module) {
exports.show = function () {
console.log("module-1 show");
}
});
//src/modules/module-2.js
define(function (require, exports, module) {
exports.show = function () {
console.log("module-2 show");
}
});
//src/modules/startup.js
define(function (require, exports, module) {
exports.show = function () {
require.async(["./module-2"], function (m1) {
m1.show();
});
}
});
没的说,关于CMD合并打包网上一搜一大把,我是使用grunt-cmd-transport、grunt-cmd-concat进行合并的。以下是合并后的目标文件,以为可以一下子就弄好,结果各种报错,各种郁闷。
//dist/modules/module-all.js
define("dist/modules/module-1", [], function(require, exports, module) {
exports.show = function() {
console.log("module-1 show");
};
});
define("dist/modules/module-2", [], function(require, exports, module) {
exports.show = function() {
console.log("module-2 show");
};
});
//dist/modules/startup.js
define("dist/modules/startup",["./module-2"],function (require, exports, module) {
exports.show = function () {
require.async(["./module-2"], function (m1) {
m1.show();
});
}
});
首先,grunt-cmd-transport 5.0有bug,老是把斜杠变(“/”)成双反斜扛”\\”(这是巨坑呀),各种报路径错误,后来Google了一下,发现是要降低版本才可以,最后降到了”v0.4.1”(改一下package.json中的版本号),这个问题修复之后,还是报“找不到 ‘dist/modules/module-2.js’”错误。到这里,想到了一个CMD的规范:一个模块就是一个文件(这也是坑呀)。合并后只有module-all文件当然会报这个错误了。于是把dist/modules/startup.js改成了以下的样子,就是要在加载”./module-2”模块前把”./module-all”加载好,这样他会先在已加载的模块中找,找不到才会从远端下载(我是这样理解的):
//dist/modules/startup.js
define("dist/modules/startup",["./module-all"],function (require, exports, module) {
exports.show = function () {
require.async(["./module-2"], function (m1) {
m1.show();
});
}
});
这样子发现可行,但是总不能每次发布后都这样子改吧,于是想到在src/modules/startup.js中加上依赖[‘../module-all’]
//src/modules/startup.js
define(["./module-all"],function (require, exports, module) {
exports.show = function () {
require.async(["./module-2"], function (m1) {
m1.show();
});
}
});
加上后发现grunt报错,网上说可以使用grunt –force强制执行,果然,加上后grunt不报错了,源码版也可以运行,但是老是报找不到modules/module-all.js文件,实在不爽。
这时候脑袋一亮,既然他要这个文件,我就给他一个不就得了。所以添加了以下的文件:
//src/modules/module-all.js
define(function(require, exports, module) {
//定义一个空模块,这样可以避免切换到源码版报找不到module-all.js文件的js错误,合并时记得要把它排除掉
//require("./module-1");//不能写
});
不报错了,总算完美的解决了。
注意事项:
1、src/modules/module-all.js不能写require(“./module-1”);源码版可能会出问题,在我的测试项目中没有发现这个问题,但是在另一个项目中发现require文件会不执行;
2、concat的时候不要把src/modules/module-all.js合并进去;
3、concat 配置成include: “relative”不是很关键。
4、CMD模块的ID是区分大小写的。
最后的Gruntfile配置如下,先transport再concat
//将cmd文件transport一下,用于后面的cmd打包
transport: {
options: {
idleading: ‘dist/‘ /*模块ID前缀*/,
debug: false,
//uglify:false
},
modules: {
//options: { idleading: ‘dist/‘ },
files: [{
expand: true,//如果设为true,就表示下面文件名的占位符(即*号)都要扩展成具体的文件名。
src: [‘modules/*.js‘],
dest: ‘tran‘,
}],
},
},
//cmd合拼文件
concat: {
options: {
//定义一个用于插入合并输出文件之间的字符
//separator: ‘;‘,
//stripBanners: { line: true },
include: ‘relative‘,
},
template: {
options: {
noncmd: true //忽略非cmd模块
},
files: {
//不要把transport后的*-all.js文件合并
‘dist/modules/module-all.js‘: [‘tran/modules/module-*.js‘,‘!tran/modules/module-all.js‘],
‘dist/modules/startup.js‘: [‘tran/modules/startup.js‘]
}
},
}
参考文档: