在使用seajs时,常常将若干脚本分为多次require进来,这样开发中比较方便,但是,会增加http请求次数,在生产环境中需要进行打包合并、压缩等操作。
以Grunt构建工具为例,对一个seajs项目打包:
普通的项目,直接对脚本进行合并、压缩接口,但是seajs中会涉及到动态引入的依赖脚本,需要对依赖的脚本也进行合并压缩操作。
具体思路是:
一般在使用define定义一个模块时,通常省略了moduleID标识的声明,而且seajs是依赖后置的,根据需要随时引入依赖脚本,所以依赖信息在定义的也未声明,需要去解析获取这些信息。Grunt中提供了一个grunt-cmd-transport插件,专门用于提取模块的moduleId和依赖dependencies信息。将各脚本以define(moduleId,[dep1,dep2,..],function (){})的形式重新定义,明确了模块的id和依赖数组,将这些重新定义的脚本放置在一个临时文件夹里如build中,然后对这里面的文件进行合并、压缩。
项目的目录结构:
module.exports = function (grunt) { // 项目配置 grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), //找出依赖文件,将依赖的文件由匿名模块变为具名模块(定义moduleID),放在一个临时目录里.build transport:{ options:{ path:['.'] }, utils:{ options:{ //format : 'dist/modules/{{filename}}' //生成的id的格式 idleading:'dist/modules/' //最终引用的js脚本的位置, (依赖脚本的moduleID以idleading作为相对路径) //如transport后的形式 define("dist/modules/codewin/codewin", [], function(require, exports, module) { }, files:[{ expand: true, cwd: 'modules/', //将modules下的所有js脚本进行transport操作,将生成的文件存放在.build/modules下 src: '**/*.js', filter: 'isFile', dest: '.build/modules/' } ] }, //单独对另一路径下的一个文件index.js进行transport index:{ options:{ idleading:'dist/js/' //最终引用的js脚本的位置 define('dist/js/*',[],function (){}) }, files:[{ expand: true, cwd: 'js', src: 'index.js', filter: 'isFile', dest: '.build/js' } ] } }, concat : { options : { separator: '/*-------每个文件的分割-------*/', banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' + '<%= grunt.template.today("yyyy-mm-dd") %> */', footer: '/*-------合并文件的footer-------*/' }, sub: { src: ['.build/modules/codewin/*.js','!.build/modules/codewin/*-debug.js','.build/modules/head/head.js'], dest: '.build/util.js' //合并临时目录.build中的依赖脚本 }, all : { src: ['.build/js/index.js','.build/util.js'], //将依赖的脚本与主文件进行合并 dest: 'dist/all.js' } }, /** * 压缩 合并后的 文件 */ uglify: { hellosea: { files: { 'dist/all.js': ['dist/all.js'] //对dist/all.js进行压缩,之后存入dist/all.js文件 } } }, clean:{ build : ['.build'] //清除临时文件夹.build文件 } }); // 加载提供"uglify"任务的插件 grunt.loadNpmTasks('grunt-cmd-transport'); grunt.loadNpmTasks('grunt-contrib-concat'); //这里使用的是contrib-concat进行的合并,使用cmd-concat会出现错误,还没弄懂啥原因 grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-clean'); grunt.registerTask('default',['transport','concat','uglify','clean']); }