Seajs通过require引用依赖,合并就需要分析出依赖关系。据seajs机制,压缩后的Js,不能再依赖require解析出依赖关系,为了确保后续行为,压缩前要先transport(规范化)。
本文介绍的合并压缩基于grunt,使用了seajs提供的两npm包,grunt-cmd-transport grunt-cmd-concat。demo地址
#方案
合并压缩前
–src/ //打包前目录
——seaConfig.js //Seajs配置文件
——page/ //页面级js
——page/share/share.js
——page/share/share.css
——page/share/imgs/
——business //业务模块
——business/wifi/
——business/wifi/wifi.js
——business/wifi/wifi.css
——business/wifi/imgs/
页面级的js放在page下;业务组件级别的js放在business下,会被page合并;公共组件级别的js放在widget下,不会被合并,结构如上所示。每个功能文件夹下
放着js、css、imgs。合并时,如果js里面require了css,grunt-cmd-concat
,默认会将css和js合并成一个文件,css引用的相对路径的图片资源会找不到。这里我改造了下,写了两个npm,grunt-cmd-concatcss
、grunt-cmd-concatfile
,将js和css合并拆成两个,并将css依赖的图片资源,合并在同一个imgs下。合并后的结构如下:
合并压缩后
--asset/
------seaConfig.js //Seajs配置文件
------page //页面级js
------page/share/share-.js
------page/share/share.css
------page/share/imgs/ #流程
-
transport
grunt-cmd-transport
,所有按照seajs模块化开发的js,transport成and规范的格式,这样依赖关系不再需要require,可放心压缩。要注意路径配置,容易出现使用合并压缩后的代码,资源加载了,却找不到执行路径。
-
合并js
grunt-cmd-concat
,存放页面级Js路径开始解析依赖合并,只合并require相对路径的js,设置别名的依赖不合并。合并前,在seajs配置文件中设置一些公用js的别名,公用的js先提前合并压缩。
-
合并css
grunt-cmd-concatcss
,合并的js涉及到的css都合并成一个css,放在页面级css中 -
合并imgs
grunt-cmd-concatfile
,合并的js涉及到的imgs文件夹都合并成一个imgs,放在页面级imgs中 -
压缩合并的Js
grunt-contrib-uglify
,经过transport,可放心压缩 -
压缩css
grunt-contrib-cssmin
-
压缩图片
grunt-contrib-imagemin
-
重命名合并压缩后的js
根据MD5重命名,解决Js设置缓存后,版本更新不能及时生效
在SeaJs配置文件,加入命名前后对照关系 方便切换开发与线上环境模式
-
公共js的合并压缩
--src -----widget -----------dialog -----------dialog/src -----------dialog/package.json --版本信息等 -----------dialog/Gruntfile.js --打包脚本 -----------dialog/examples --组件使用demo
将功能块js合并压缩后,生成带版本的路径到seajs别名配置表中,其它js直接require别名。
--asset --seaConfig.js --在配置文件中加入别名 "dialog": "widget/dialog/0.0.1/dialog.js", -----widget -----------dialog -----------dialog/0.0.1 --版本号 -----------dialog/0.0.1/dialog.js -----------dialog/0.0.1/dialog.css -----------dialog/0.0.1/imgs
-
其他js css
所有页面公用的js css,一般都不是seajs模块化,直接指定文件名合并,合并生成top.js放在html的head,bottom.js放在body闭合标签处
common:{ files:[{ src:['./src/common/css/reset.css','./src/common/css/font-awesome.css'], dest:'.build/common/css/out_common.css' },{ src:'./src/common/js/bottom/*.js', dest:'.build/common/js/bottom/out_footer.js' },{ src:['./src/common/js/top/jquery-1.9.1.js','./src/common/js/top/jquery-migrate.js', './src/common/js/top/json2.js','./src/common/js/top/util.js','./src/common/js/top/base.js'], dest:'.build/common/js/top/out_top.js' }] }
#其它 ##下载使用 git clone https://github.com/sprying/ys7.git npm install npm install -g grunt-cli grunt build-widget –的js,生成相关文件到asset/widget 拷贝asset/seaConfig.js下 alias : { “dialog”: “widget/dialog/0.0.1/dialog.js”, “jquery.validate”: “widget/validator/1.12.0/jquery.validate.js”, } 到根目录下package.json的spm部分 “spm”: { “alias”: { “dialog”: “widget/dialog/0.0.1/dialog.js”, “jquery.validate”: “widget/validator/1.12.0/jquery.validate.js” } } grunt build-all –合并压缩整个项目 查看app/test.html 和 app/test2.html,对比压缩前后效果 ##使用注意点 page、business、widget的文件夹里只能放一级功能目录,
--page
------/setting/
--------------/product_s1
-------------------------/product_s1.js
-------------------------/product_s1.css
-------------------------/imgs
--------------/product_s2
-------------------------/product_s2.js
-------------------------/product_s2.css
-------------------------/imgs
应该改成这样
--page
------/product_s1
-----------------/product_s1.js
-----------------/product_s1.css
-----------------/imgs
------/product_s2
-----------------/product_s2.js
-----------------/product_s2.css
-----------------/imgs
##启动调试 在写合并压缩代码时,如何开启调试?
先安装插件
npm install -g node-inspector
打开命令行,启动调试端口
node-inspector
打开另一个命令行窗口
node --debug-brk $(which grunt) task
node --debug-brk C:\Users\administrator\AppData\Roaming\npm\node_modules\grunt-cli\bin\grunt concat:app
node --debug-brk C:\Users\administrator\AppData\Roaming\npm\node_modules\spm-build\bin\spm-build
最后打开chrome,输入网址
http://127.0.0.1:8080/debug?port=5858