r.js
是RequireJS
的一個附產品,支持在 NodeJS
環境下運行AMD
程序,並且其包含了一個名為RequireJS Optimizer
的工具,可以為項目完成合並腳本等優化操作
RequireJS Optimizer常規用法
寫好一個配置文件, 比如 config.js
,常用屬性有:
({
// 程序的根路徑
appDir: "xxx",
// 腳本的根路徑
// 相對於程序的根路徑
baseUrl: "xxx",
// 打包輸出到的路徑
dir: "xxx",
// 需要打包合並的js模塊,數組形式,可以有多個
// name 以 baseUrl 為相對路徑,無需寫 .js 后綴
// 比如 main 依賴 a 和 b,a 又依賴 c,則 {name: 'main'} 會把 c.js a.js b.js main.js 合並成一個 main.js
modules: [
{
name: "main"
}
...
],
// 通過正則以文件名排除文件/文件夾
// 比如當前的正則表示排除 .svn、.git 這類的隱藏文件
fileExclusionRegExp: /^\./
})
運行node
命令
node r.js -o config.js
這時 RequireJS Optimizer
就會:
- 把配置信息的
modules
下的所有模塊建立好完整的依賴關系,再把相應的文件打包合並到dir
目錄 - 把所有的
css
文件中,使用@import
語法的文件自動打包合並到dir
目錄 - 把其他文件賦值到
dir
目錄,比如圖片、附件等
適合老舊傳統項目使用的api
modules[i].include
modules: [
{
name: "main",
include: ["a", "b"]
}
]
這里include
字段提供了"強制建立依賴關系"的功能,也就是說,即使在 main.js
的代碼里沒有依賴 a.js
和 b.js
,它們也會在合並代碼的時候插入到 main.js
的前面,這種打包方式非常適合傳統老舊項目
two small demos using r.js to pack files
demo one:給使用`AMD`模塊化開發方式的項目打包
目錄結構
|——build
|——config.js
|——r.js
|——js
|——moduleA.js
|——moduleB.js
|——moduleC.js
|——main.js
|——require.min.js
|——index.html
文件詳情
index.html
<!-- data-main指向總的文件入口, 只能有一個入口文件 -->
<script src="js/require.min.js" data-main="js/main.js"></script>
moduleA.js
define(function () {
return {
a: 5
}
});
moduleB.js
define(function () {
return {
b: 10
}
});
moduleC.js
define([
'moduleA',
'moduleB'
], function(moduleA, moduleB) {
'use strict';
let a = moduleA.a;
let b = moduleB.b;
function add (x, y) {
return x + y;
}
function init() {
console.log('app init');
console.log('the result is: ' + add(a, b));
}
return {
init: init
}
});
main.js
// don't use moduleA.js or js/moduleA.js here
require(["moduleC"], function (moduleC) {
moduleC.init();
})
打包配置文件config.js
({
appDir: '../',
baseUrl: './js',
dir: "../dist",
keepBuildDir: false,
// 打包結果優化; 壓縮等
optimize: "none",
skipModuleInsertion: true,
removeCombined: true,
modules: [
{
name: "main"
}
],
fileExclusionRegExp: /^(\.|build|dist|README)/,
})
運行打包命令
node r.js -o config.js
打包結果
dist 目錄結構
|——js
|——main.js
|——require.min.js
|——build.txt
|——index.html
打包完的 main.js
;自動分析依賴,並將所有依賴到的文件統一打包到 main.js
中
define('moduleA',[],function () {
return {
a: 5
}
});
define('moduleB',[],function () {
return {
b: 10
}
});
define('moduleC',[
'moduleA',
'moduleB'
], function(moduleA, moduleB) {
let a = moduleA.a;
let b = moduleB.b;
function add (x, y) {
return x + y;
}
function init() {
console.log('app init');
console.log('the result is: ' + add(a, b));
}
return {
init: init
}
});
// don't use moduleA.js or js/moduleA.js here
require(["moduleC"], function (moduleC) {
moduleC.init();
});
demo two:給傳統舊項目打包
目錄結構
|——build
|——config.js
|——r.js
|——css
|——a.css
|——b.css
|——main.css
|——image
|——a.jpg
|——js
|——a.js
|——b.js
|——main.js
|——index.html
文件詳情
index.html
...
<link rel="stylesheet" href="css/main.css">
...
<div><img src="images/a.jpg" alt=""></div>
...
<script src="js/main.js"></script>
mian.css
@import url(a.css)
@import url(b.css)
a.js
alert('a')
b.js
alert('b')
main.js
// ...
打包配置文件config.js
({
// 程序的根路徑
appDir: "../",
// 腳本的根路徑
// 若appDir值未指定,模塊則相對build文件所在目錄。
// 若appDir值已指定,模塊根目錄baseUrl則相對appDir。
// 相對於程序的根路徑
baseUrl: "./js",
// 打包輸出到的路徑
dir: "../dist",
// 在 RequireJS 2.0.2 中,輸出目錄的所有資源會在 build 前被刪除
// 值為 true 時 rebuild 更快,但某些特殊情景下可能會出現無法預料的異常
keepBuildDir: false,
// RequireJS Optimizer 有個很智能的功能, 就是為沒有寫明 define(...) 函數
// 的模塊代碼自動將其放入 define(...) 之中
// 如果我們指定如下參數, 那么上述的處理將會被取消
skipModuleInsertion: true,
// If set to true, any files that were combined into a build layer will be
// removed from the output folder.
// 打包輸出的文件夾中只留打包后的js、css
removeCombined: true,
// 需要打包合並的js模塊, 數組形式, 可以有多個
// name以basrUrl為相對路徑, 無需寫.js后綴
// include字段提供了"強制建立依賴關系"的功能, 也就是說, 即使在main.js的代碼里
// 沒有依賴 a.js 和 b.js, 它們也會在合並代碼的時候插入到 main.js 的前面
modules: [
{
name: "main",
include: ["a", "b"]
}
],
// 通過正則以文件名排除文件/文件夾
// ex 排除 .svn、.git 這類隱藏文件
fileExclusionRegExp: /^(\.|build|dist|ignore|README)/,
// onBuildRead 這個參數可以定義一個函數, 在處理每個 js 文件之前,
// 會先對文件的文本內容進行預處理
// 比如下面, 就是把 main.js 里打包前的代碼全部清除(注釋外的代碼, 注釋自動會清除)
onBuildRead: function (moduleName, path, contents) {
if (moduleName === 'main') {
console.log('hello')
contents = '/* empty code */';
// return contents.replace(/foo/g, "bar");
}
return contents
}
})
運行打包命令
node r.js -o config.js
打包結果
目錄結構
|——css
|——main.css
|——image
|——a.jpg
|——js
|——main.js
|——build.txt
|——index.html
打包完的 main.css
;打包時自動合並a.css
和b.css
文件
.a-class {
font-size: 16px;
color: #000;
}
.b-class {
font-size: 20px;
color: red;
}
打包完的main.js
;打包時會把a.js
和b.js
插入到main.js
的前面,即使在main.js
的代碼里沒有依賴它們
這是因為在打包配置文件config.js
里配置了 modules[i].include
屬性
alert("a module"),alert("b module");