盒子
文章目录
  1. 为什么要这样搭配?
  2. 具体实现
    1. 参考

spm3和seajs在实际项目的应用

为什么要这样搭配?

在spm3,支持的书写规范从 CMD 模块 转向了 CommonJS。因此在构建之前,要先把原 CMD 模块的 define 包装去掉。
这就跟spm2.x时代,spm2+seajs的紧密配合完全不一样了。
既然spm3已经不和seajs配套,为什么我还要用seajs+spm,我用gulp或者grunt不是更方便吗。

答案就是为了能够在无论是开发环境还是生产环境(线上),每一个页面都只能有一个单一的js文件,也就是页面的脚本入口文件。

具体实现

以php为例,在每个页面的页脚都include这个php文件:

registerJsFile.php

1
2
3
4
5
6
7
8
9
10
$route //动态生成,对应页面的路由,比如当前页index.php,$route = 'index.js';
echo '<script src="path/to/sea.js"></script>';
if( 开发环境 ){
//seajs-wrap,能够让sea.js 加载 commonJs规范的js文件 的一个插件
echo '<script src="path/to/seajs-wrap.js"></script>';
echo '<script src="js-dev/static/'.$route.'"></script>';
}else{
//生产环境的代码已经通过spm完成合并,只要加载入口文件的js就可以了。
echo '<script> src="/static/'.$route.'"></script>';
}

接下来是spm的配置文档 package.json ,这也是很多文章说的不够详细的地方
我自己并没有把js单独放在一个子域名下。所以文件夹的位置需要好好的组织。

开发环境的js,放在 http://localhost/js-dev/static/ 下,
spm的package.json放在http://localhost/js-dev/ 下。

package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
name:'',
"spm": {
"dependencies": {
"jquery": "1.8.3",
"test": "1.0.1",
},

"devDependencies": {
"expect.js": "0.3.1"
},

"output": [
"static/index.js",
"static/user.js",
"static/login.js",
"static/product/list.js",
],

/** dest定义输出的目录,../是输出在开发代码的上一层 **/
"dest": "../"
},

"devDependencies": {
"spm": "3"
},

"scripts": {
"test": "spm test",
"build": "spm build"
}

}

output的值是数组,那么spm build就会生成对应的多个文件。
例如:

http://localhost/js-dev/static/index.js

1
2
var component = require('./component');
console.log(component.a);

http://localhost/js-dev/static/component.js

1
module.exports.a = 10;

最终生成出来两个文件 http://localhost/static/index.jshttp://localhost/static/index.js

1
2
define("/static/index",[],function(n){var t=n("/static/component");console.log(t.a)}),
define("/static/component",[],function(n,t,o){o.exports.a=10});

1
2
3
4
5
6
7
8
define("/static/index-debug", [], function(require, exports, module){
var component = require("/static/component-debug");
console.log(component.a);
});
define("/static/component-debug", [], function(require, exports, module){

module.exports.a = 10;
});

如果你已经配置好,生产环境的代码就能够根据自己route, 直接引用属于自己的入口脚本了~

当然这种用法只是实际项目中,我自己的实践过程,如果有什么不足,或者更好的改进办法,欢迎指出。

参考

使用spm@3构建seajs项目
sea.js在实际项目中的一些应用思路
Seajs 实践(二)—— 使用 spm3 构建项目
Package.json