原文出处:一步步学会使用SeaJS 2.0
--------------------------------------------------
1、SeaJS是什么?
我知道你看到那么长的文章肯定会望而却步,也许你是希望能够快速开始敲代码(程序员的通病……)。没关系,如果实在读不下去,只要记住模块化要解决的问题即可:命名冲突、文件依赖关系。
这两个闹心的问题应该遇到过吧,如果没遇到过……我只能说你太牛X了
2、下载并检阅SeaJS
3、建立工程和各种目录
(我使用了Sublime2.0,在这里强烈推荐)
注意:SeaJS会根据自身的URI来决定URL base,而SeaJS在加载其他模块的时候会根据这个URL base来计算路径。SeaJS会忽略掉seajs、seajs/2.0.0/seajs这两种目录,照上述的目录结构,此处的URL base就是HelloSeaJS/assets/scripts,这样其他模块就可以与seajs目录并行存放。
4、引入SeaJS库
b. SeaJS内部通过document.getElementById("seajsnode")来获取这个script标签(其实SeaJS内部还有一种方式,不过另一种方式的效率比较低,所以不推荐,如果有兴趣,可以看一下源码https://github.com/seajs/seajs/blob/master/src/util-path.js)
5、编写自己的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
define(
function
(require,exports,module){
var
util = {};
var
colorRange = [
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
];
util.randomColor =
function
(){
return
'#'
+
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)];
};
var
helloSeaJS = document.getElementById(
'hello-seajs'
);
helloSeaJS.style.color = util.randomColor();
window.setInterval(
function
(){
helloSeaJS.style.color = util.randomColor();
},1500);
});
|
随着代码的增多,你肯定会遇到util越来越多的情况。很好,这样看来,我们就有了两个模块:util模块和application模块。SeaJS中,文件即模块,所以当然要将其分为两个文件。先看util.js:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
define(
function
(require,exports,module){
var
util = {};
var
colorRange = [
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
];
util.randomColor =
function
(){
return
'#'
+
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)];
};
module.exports = util;
});
|
再看application.js:
1
2
3
4
5
6
7
8
9
10
|
define(
function
(require,exports,module){
var
util = require(
'./util'
);
var
helloSeaJS = document.getElementById(
'hello-seajs'
);
helloSeaJS.style.color = util.randomColor();
window.setInterval(
function
(){
helloSeaJS.style.color = util.randomColor();
},1500);
});
|
我们看到var util = require('./util');这句比较特殊。这句就是在说,我application模块由于业务需要,想请util模块来帮忙,所以把util给require进来。
6、引入自己的代码
你看不到效果吧?这就是这个小节存在的理由。
那么,加载路径就是HelloSeaJS/assets/scripts/application/application.js(SeaJS会自动加上.js后缀)
如果你对你的程序有完全的控制权,建议使用data-main的方式,这样整个页面就只有一段script标签!作为一名前端开发人员,我不得不惊叹:干净、完美!
7、压缩合并
压缩后之后,require变量变成了a变量。SeaJS是通过require字面来判断模块之间的依赖关系的,所以,require变量不能被简化。
SeaJS在2.0之前,是采用SPM作为压缩合并工具的,到了2.0,改为Grunt.js,SPM变为包管理工具,类似NPM(不知道NPM?Google一下吧)
……
Grunt最核心的就两个部分,package.json、Gruntfile.js。
a. package.json
1
2
3
4
5
6
7
8
9
10
11
12
|
{
"name" : "HelloSeaJS",
"version" : "1.0.0",
"author" : "Qifeng Liu",
"devDependencies" : {
"grunt" : "0.4.1",
"grunt-cmd-transport" : "0.1.1",
"grunt-cmd-concat" : "0.1.0",
"grunt-contrib-uglify" : "0.2.0",
"grunt-contrib-clean" : "0.4.0"
}
}
|
grunt-contrib-clean模块用来清除临时目录
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
module.exports =
function
(grunt){
grunt.initConfig({
transport : {
options : {
format :
'application/dist/{{filename}}'
//生成的id的格式
},
application : {
files : {
'.build'
: [
'application.js'
,
'util.js'
]
//将application.js、util.js合并且提取依赖,生成id,之后放在.build目录下
}
}
},
concat : {
main : {
options : {
relative :
true
},
files : {
'dist/application.js'
: [
'.build/application.js'
],
// 合并.build/application.js文件到dist/application.js中
'dist/application-debug.js'
: [
'.build/application-debug.js'
]
}
}
},
uglify : {
main : {
files : {
'dist/application.js'
: [
'dist/application.js'
]
//对dist/application.js进行压缩,之后存入dist/application.js文件
}
}
},
clean : {
build : [
'.build'
]
//清除.build文件
}
});
grunt.loadNpmTasks(
'grunt-cmd-transport'
);
grunt.loadNpmTasks(
'grunt-cmd-concat'
);
grunt.loadNpmTasks(
'grunt-contrib-uglify'
);
grunt.loadNpmTasks(
'grunt-contrib-clean'
);
grunt.registerTask(
'build'
,[
'transport'
,
'concat'
,
'uglify'
,
'clean'
])
};
|
该命令会运行grunt.registerTask方法中指定的任务
8、总结展望
最后,感谢SeaJS作者玉伯。
PS,本文参考了SeaJS提供的使用范例https://github.com/seajs/examples/tree/master/static/hello