前端优化:AMDclean去除requirejs

前端极致优化 :AMDclean去除requirejs

引子

最近做了一个和腾讯合作了一个项目,后台由他们开发。我们负责前端,前端是requirejs+backbone做的单页应用。

问题

前端需要引入腾讯的库文件实现qq登录,而腾讯的库文件又会动态的加载seajs。在seajs和requirejs中都有使用全局变量definerequire,会造成冲突。但是requirejs中并没有像jquery中的$.noConflict()方法。正好以前看过一个叫做AMDclean的工具,结合requirejs自带的优化工具r.js。正好可以解决这个问题。

解决方案:

  1. 利用r.js将所有的脚本(实际上利用r.js的text插件可以将css和html文件也一块打包)打包到一个叫做app.js的脚本中。
  2. 利用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);

优点

  1. 所有js(html,css)文件都都合并到了一个文件中,减少了http请求数。
  2. 不用加载requirejs,减少了总的文件大小。

缺点

  1. 使用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.

原文地址:https://www.cnblogs.com/selfstudy/p/AMDclean.html