我正在使用RequireJS(版本2.1.14),并希望将我的JavaScript文件连接成一个app-built.js
。
我创建了一个小节点模块,它读取我的app.js
,提取项目路径,并在我的应用程序的node build
目录中运行js
后执行。
节点模块(build.js):
var fs = require('fs'),
path = require('path'),
directory = __dirname + path.sep,
requirejs = require(directory + 'vendor/r.js');
fs.readFile(directory + 'app.js', 'utf8', function(err, data) {
if (err) {
console.log('Error: ' + err);
return
} else {
data = data.replace(/'/g, '"').replace(/\s+/g, '');
var paths = data.substr(data.indexOf('{'), data.indexOf('}')),
paths = paths.substr(0, paths.indexOf('}') + 1),
paths = JSON.parse(paths);
createAppBuilt(paths);
}
});
function createAppBuilt(paths) {
var config = {
baseUrl: __dirname,
paths: paths,
name: 'app',
out: 'app-built.js',
preserveLicenseComments: false,
findNestedDependencies: true,
removeCombined: true
};
requirejs.optimize(config, function(buildResponse) {
var contents = fs.readFileSync(config.out, 'utf8');
console.log('Created app-built.js');
}, function(err) {
console.log('Error: ' + err);
return;
});
}
app.js:
var paths = {
'jquery': 'vendor/jquery-1.11.0.min',
// other paths
};
// Set language, necessary for validtaion plugin -> validation.js
if (Modernizr.localstorage) {
localStorage.getItem('language') || localStorage.setItem('language', navigator.language || navigator.userLanguage);
}
requirejs.config({
paths: paths,
shim: {
touchswipe: {
deps: ['jquery']
},
icheck: {
deps: ['jquery']
},
validate: {
deps: ['jquery']
},
mask: {
deps: ['jquery']
},
chosenImage: {
deps: ['jquery', 'chosen']
},
cookie: {
deps: ['jquery']
}
}
});
require(['globals', 'jquery', 'underscore'], function() {
var initial = ['main'];
if (!Modernizr.localstorage) {
initial.push('cookie');
}
require(initial, function(Main) {
$(function() {
if (!Modernizr.localstorage) {
$.cookie.json = true;
}
Main.init();
});
});
});
生成app-built.js
但是当我将它包含在我的index.php中时,所有其他模块也会被加载。如何阻止加载所有模块并仅加载app-built.js
?
答案 0 :(得分:-1)
我建议你研究http://webpack.github.io/ 或http://browserify.org/因为这些可以解决这个问题。
它们允许您像以前一样使用require
,但代码被编译/连接成一个文件。
Webpack允许在为站点的不同部分加载不同的代码块时更加灵活,但到目前为止,Browserify是最知名的。
切换到这些可能会有成本,因为我不认为他们是100%兼容的需求,但是它们带来了很大的优势。
Here's有人从RequireJS到Browserify的旅程中有一些优点和缺点。
答案 1 :(得分:-1)
将模块分成不同的文件,例如app-built.js
,user-built.js
。然后在需要时加载脚本。
以下是演示:http://plnkr.co/edit/s6hUOEHjRbDhtGxaagdR?p=preview。
加载页面时,requirejs仅加载global.js
。点击Change Color
按钮后,requirejs开始加载colorfy.js
所需的random-color.js
和colorfy.js
。
答案 2 :(得分:-1)
我不确定具体细节,但是,如果您没有exports
选项,则r.js不会为您定义命名模块,这会导致实际加载脚本。
我假设你有jquery插件,所以添加额外的exports
选项:
shim: {
touchswipe: {
deps: ['jquery'],
exports: 'jQuery.fn.touchswipe'
},
这应该强制r.js为touchswipe构建一个命名模块:
define("touchswipe", (function (global) {
return function () {
var ret, fn;
return ret || global.jQuery.fn.touchswipe;
};
}(this)));
请注意,exports
选项可能无法构建此命名模块,在这种情况下,您最好的选择是手动包含此模块。
我再次不确定为什么以及如何发生这种情况,必须是requirejs中的一个错误,不太可能对此进行调整。
答案 3 :(得分:-1)
更改r.js优化器(到uglify2)解决了我的问题:
var config = {
baseUrl: __dirname,
paths: paths,
name: 'app',
out: 'app-built.js',
findNestedDependencies: true,
preserveLicenseComments: false,
removeCombined: true,
optimize: 'uglify2'
};