Grunt 之 RequireJS

 RequireJs 提供了一个打包工具 r.js,能够将相关的模块打包为一个文件。相关说明:http://www.requirejs.org/docs/optimization.htmlhtml

  • 将相关的脚本模块整合为单个脚本文件,而后默认使用  UglifyJS 进行紧缩,或者在使用 java 的时候,使用  Closure Compiler 处理。
  • 还能够经过 @import 自动内联相应的样式,而且删除注释来优化 CSS

虽然能够经过命令行来使用这个打包工具,可是在 Grunt 中也提供了相应的插件来自动完成这个任务。java

1. 安装

地址:https://github.com/gruntjs/grunt-contrib-requirejs node

 npm install grunt-contrib-requirejs --save-dev

 控制台输出jquery

grunt-contrib-requirejs@0.4.4 node_modules\grunt-contrib-requirejs
└── requirejs@2.1.20

在 Gruntfile.js 文件中,使用 grunt.loadNpmTasks 来加载这个任务。git

grunt.loadNpmTasks('grunt-contrib-requirejs');

 

 2. 配置

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    
    copy: {
      dev: {
        files: [
        {expand: true, src: ['src/**/*.js'], dest: 'public/js', filter: 'isFile'}
        ]
      }
    },

    requirejs: {
      compile: {
        options: {
          name: "main",
          baseUrl: "src/js",
          mainConfigFile: "main.js",
          out: "public/js/main.js"
        }
      }
    }
    
  });

  // 加载包含 "copy" 任务的插件。
  grunt.loadNpmTasks('grunt-contrib-copy');

  grunt.loadNpmTasks('grunt-contrib-requirejs');

  // 默认被执行的任务列表。
  grunt.registerTask('default', ['uglify']);

};

 compile 是咱们为任务所起名称,options 中是相应的配置。angularjs

  • baseUrl, 相似于 requirejs 中的 baseUrl 参数,用来定义脚本的参照地址。
  • mainConfigFile: requirejs 的配置文件,工具经过它来获取 requirejs 的配置信息。它的地址要相对于 baseUrl 地址。
  • name, 入口模块的地址,也就是咱们的入口模块,这里是模块名称,因此不须要 .js 的扩展名,地址也要相对于 baseUrl 地址。若是你使用了 almond 进行压缩,almond 至关于入口模块了,这里就是 almond 的地址。也不须要 .js 扩展名。
  • out, 输出的结果,这个地址与 baseUrl 没有关系,是相对于 Gruntfile.js 的地址
  • include 须要包含的模块名称,若是使用了 almond,入口已经变成 almond 了,就必需要包含原始的入口模块名称。

2.1 直接使用 r.js

在使用这个紧缩任务的时候,默认是不包含 require.js 库的,因此有两种用法。github

第一种用法,只紧缩咱们定义的模块,这样紧缩出来的结果中,会包含 require 过的第三方库,好比 jquery, angularjs 等等,可是不会包含 requirejs 自己。因此,咱们须要在页面中先引用 require.js 库,而后引用咱们紧缩的结果。npm

requirejs: {
      compile: {
        options: {
          name: "main",
          baseUrl: "src/js",
          mainConfigFile: "main.js",
          out: "public/js/main.js"
        }
    }
}

 

第二种用法,直接将 require.js 也包含进来,这样,只须要在页面中引用紧缩的结果便可。json

先经过 paths 给 require.js 起一个名称,而后在 include 中包含这个模块。api

    //Set paths for modules. If relative paths, set relative to baseUrl above.
    //If a special value of "empty:" is used for the path value, then that
    //acts like mapping the path to an empty file. It allows the optimizer to
    //resolve the dependency to path, but then does not include it in the output.
    //Useful to map module names that are to resources on a CDN or other
    //http: URL when running in the browser and during an optimization that
    //file should be skipped because it has no dependencies.
    paths: {
        "requireLib": "lib/require"
    },

    include: ["requireLib"],

 

 

2.2 使用 almond 

在使用 almond 的时候,其实更加简单了。

咱们将 name 设置为 almond 的路径,而后使用 include 将咱们实际的入口模块包含进来就能够了。

这里须要注意一点,almond 是一个独立的脚本库,你须要本身将这个库下载来下,直接使用 bower 就能够。而后,设置 name 为相对于 baseUrl 的 almond 库路径便可。

requirejs: {
  compile: {
    options: {
      baseUrl: "tmp",
      mainConfigFile: "tmp/main.js",
      include: "main",
      name: "../bower_components/almond/almond",
      out: "tmp/<%= pkg.name %>.js"
    }
  }
}

 

 

注意,上面的官方实例中没有使用 include 包含实际的入口。结果就是不会执行的你的脚本。

关于 almond 的限制

  • 将全部的模块合并到单个文件,不会再有动态加载。
  • 全部的模块都拥有惟一的标识,以及经过 define() 来讲明的模块所依赖的模块说明数组,requirejs 优化器经过它来检查模块关系。
  • 只能使用一次 requirejs.config() 调用
  • requirejs.config 须要包含在输出中,这对于 map config 很重要
  • 不支持 var require = {} 来传递配置参数
  • 不支持  RequireJS multiversion support/contexts.
  • 不要使用 require.toRul() 或者 require.nameToUrl()
  • 不要使用 packages/packagePaths config

仍然支持的特性:

  • 使用相对路径的依赖
  • define('id', {}) 定义
  • define(), require() 和 requirejs() 调用
  • 将插件合并到优化以后的文件中,在优化以后能够同步访问这些资源。

参考资料

requirejs:杏仁的优化(almond)

相关文章
相关标签/搜索