久聞r.js的大名,但實際沒有用它做過任何東西。今天用它時,發現網上許多教程都不對。研究一下,把我的實際經驗分享給大家。
例子1
先是HTML頁面
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
<script data-main="scripts/main-built" src="scripts/require.js"></script>
</head>
<body>
<h1>My App</h1>
</body>
</html>
js都放在scripts目錄下,換言之 html與scripts是平級。此目錄下有r.js, require.js, one.js, two.js, three.js, main.js
上面HTML提到的main-built.js是一會兒動態生成的。
r.js 可以在這里找到https://github.com/jrburke/r.js/blob/master/dist/r.js,總共7MB,非常瘋狂!聽說把各種情況都hold住了, 比spm強大多了!
接着是幾個JS的內容:
one.js
define(function(){
return 1
})
two.js
define(function(){
return 2
})
three.js
define(function(){
return 3
})
main.js
require(["one", "two", "three"], function (one, two, three) {
alert(one+two+three)
});
好了,我們再看一下build.js如何寫
({
baseUrl: ".",
name: "main",
out: "main-built.js"
})
定位到此目的,執行node r.js -o build.js
最后生成main-built.js文件,我格式化它一下,里面內容如下:
define("one",[],function(){return 1}),
define("two",[],function(){return 2}),
define("three",[],function(){return 3}),
require(["one","two","three"],function(e,t,n){alert(e+t+n)}),define("main",function(){});
最后運行服務器,發現真的能alert出6!
例子2
就是在上面的例子里面改一下
其他變化如下:
three.js放到sub目錄下,內容改成:
define(["./two"], function(a){
return 1 + a
})
one.js
define(["./two"], function(a){
return 1 + a
})
main.js改成
require(["one","sub/three"], function (one, three) {
console.log(one + three)
})
執行r.js,生成main-built.js為:
define("two", [], function() {
return 2
}), define("one", ["./two"], function(e) {
return 1 + e
}), define("sub/three", [], function() {
return 30
}), require(["one", "sub/three"], function(e, t) {
console.log(e + t)
}), define("main", function() {
});
下面合並前后的請求數比較
例子3, paths配置項的使用
目錄結構改成這樣,jquery自行到官網下載
main.js改成這樣
require.config({
paths: {
jquery: "jquery/jquery-1.11.2"
}
})
require(["one", "sub/three","jquery"], function(one, three, $) {
console.log(one + three)
console.log($)
});
main.js改成這樣
({
baseUrl: ".",
name: "main",
paths: {
jquery: "jquery/jquery-1.11.2"
},
out: "main-built.js"
})
然后執行node r.js -o build.js打包命令,生成的文件就可以用了。並且發現r.js有個非常智能的地方,如果把main.js中的require語句的依賴項中的jquery去掉,再執行打包,它會將jquery源碼從main-built.js中去掉。
例子4, 讓生產環境用的腳本放在另一個文件中
我們通常把我們自己工作的環境叫做發展環境, 上線的環境叫生產壞境,將它們分開是非常有好處的。我們把上面的目錄復制一下,改一名字:
相對而言, 頁面也改一下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>My App</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
<script data-main="develop/main-built" src="develop/avalon.js"></script>
<!-- <script data-main="develop/main" src="develop/avalon.js"></script>-->
<!-- <script data-main="develop/main-built" src="develop/require.js"></script>-->
</head>
<body>
<h1>My App</h1>
</body>
</html>
打包的腳本build.js變成這樣,
({
baseUrl: ".",
paths: {
jquery: "jquery/jquery-1.11.2"
},
dir: "../production",
name: "main"
})
對比一下,有了dir,就不能使用out配置項了,你在編譯時它有非常明確的提示。執行node r.js -o build.js打包命令,你的項目變成這樣了
既然目錄變了,我們有兩個辦法,1自己修改或通過腳本修改index.html引用腳本的路徑,2后端配置一下,對請求進行重定向,我們通常是使用后面一種。
例子5, shim配置項的使用
在例子4里面jquery目錄添加一個jquery.aaa.js,內容如下:
jQuery.fn.aaa = function(){
alert("aaa")
}
main.js改成
require.config({
paths: {
jquery: "jquery/jquery-1.11.2",
aaa: "jquery/jquery.aaa"
},
shim: {
aaa: {
deps: ["jquery"],
exports: "jQuery"
}
}
})
require(["one", "sub/three", "aaa"], function(one, three, $) {
console.log(one + three)
console.log($.fn.aaa)
})
build.js也跟着改成
require.config({
paths: {
jquery: "jquery/jquery-1.11.2",
aaa: "jquery/jquery.aaa"
},
shim: {
aaa: {
deps: ["jquery"],
exports: "jQuery"
}
}
})
require(["one", "sub/three", "aaa"], function(one, three, $) {
console.log(one + three)
console.log($.fn.aaa)
})
然后執行node r.js -o build.js打包命令,生成的文件就可以用了。
如果大家還有更好的打包方式, 可以https://github.com/avalonjs/avalonjs.github.io/tree/master/zh/engineering ,添加到這里,pull request給我
