前端极致优化 :AMDclean去除requirejs
引子
:
最近做了一个和腾讯合作了一个项目,后台由他们开发。我们负责前端,前端是requirejs+backbone做的单页应用。
问题
:
前端需要引入腾讯的库文件实现qq登录,而腾讯的库文件又会动态的加载seajs。在seajs和requirejs中都有使用全局变量define
和require
,会造成冲突。但是requirejs中并没有像jquery中的$.noConflict()方法。正好以前看过一个叫做AMDclean的工具,结合requirejs自带的优化工具r.js。正好可以解决这个问题。
解决方案
:
- 利用r.js将所有的脚本(实际上利用r.js的text插件可以将css和html文件也一块打包)打包到一个叫做app.js的脚本中。
- 利用AMDclean将app.js中amd格式的代码转化为标准的js代码。这样最终生成的app.js中就不会有define和require了。
AMD:
define('example', ['example1', 'example2'], function(one, two) {
var test = true;
});
Standard:
var example;
example = function (one, two) {
var test = true;
}(example1, example2);
优点
:
- 所有js(html,css)文件都都合并到了一个文件中,减少了http请求数。
- 不用加载requirejs,减少了总的文件大小。
缺点
:
- 使用requrejs动态加载的文件也会被合并。
r.js和AMDclean都可以基于grunt配置运行。下面给出我的grunt配置做参考。
requirejs: {
build: {
options: {
appDir: 'app', //开发目录
mainConfigFile: 'temp/scripts/main.js', //requirejs的配置文件
dir: 'dist', //发布目录
optimize: 'uglify',
findNestedDependencies: true, //合并动态加载的脚本
modules: [{
name: 'app'
}],
onModuleBundleComplete: function(data) {
var fs = require('fs'),
amdclean = require('amdclean'),
outputFile = 'dist/' + data.path; //输出文件的路径
fs.writeFileSync(outputFile, amdclean.clean({
'filePath': outputFile
}));
}
}
}
}
结语
:
有同学可能会说,这么麻烦干嘛,一开始不用requirejs不就好了吗?但是其实我们在开发阶段是一直在享用requirejs给我们带来的便利(把脚本分解成多个模块,管理模块之间的依赖)还可以使用requirejs的优化工具r.js合并脚本文件。
最后推荐一个更好用的模块工具webpack.