公司還一直在延續使用jq+seajs的技術棧,所以只能基於現在的技術棧進行靜態文件打包,而眾所周知seajs的打包比較“偏門”,在查了不少的文檔和技術分享后終於琢磨出了自己的打包策略。
本文目錄
一:devDependencies依賴
了解gulp的肯定對npm都有所了解,在這里就不再贅述,直接貼依賴包。
"devDependencies": {
"gulp": "^3.9.1",
"gulp-autoprefixer": "^3.1.1",
"gulp-clean": "^0.3.2",
"gulp-cleanhtml": "^1.0.1",
"gulp-cssimport": "^5.0.0",
"gulp-cssmin": "^0.1.7",
"gulp-htmlmin": "^3.0.0",
"gulp-load-plugins": "^1.5.0",
"gulp-rename": "^1.2.2",
"gulp-rev": "^7.1.2",
"gulp-rev-collector": "^1.1.1",
"gulp-seajs-combo": "^1.2.3",
"gulp-uglify": "^2.1.0"
}
二: css的壓縮、合並、md5
文件中使用了gulp的插件“gulp-load-plugins”,沒用過的可以簡單了解下 https://www.npmjs.com/package/gulp-load-plugins
//css 合並 壓縮 md5
gulp.task('css', function(){
return gulp.src('./public/static/src/css/!(common|lib)/*.css')
.pipe($.cssimport({}))
.pipe($.autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
.pipe($.cssmin())
.pipe($.rev())
.pipe(gulp.dest('./public/static/dist/css'))
.pipe($.rev.manifest())
.pipe($.rename('css-mainfest.json'))
.pipe(gulp.dest('./public/static/dist/rev/css'));
});
考慮到每次修改需要把以前的css文件刪除,所以還要有清除css文件的任務
//清除原來的內容
gulp.task("cleancss", function(){
return gulp.src('./public/static/dist/css')
.pipe($.clean());
});
三: seajs合並
好了,下面是重頭戲--合並seajs,在合並seajs之前,我們先了解下一些不同的地方。
由於打包的局限性我們需要給每一個被頁面引入的seajs文件添加一個中介文件調用seajs.use,不要在頁面中使用seajs.use調用。
Demo如下:
// seajs合並
gulp.task('seajs', ['index/index', 'index/submit','require/index']);
gulp.task('index/index', function(){
return gulp.src("./public/static/src/js/{index,}/index_main.js")
.pipe($.seajsCombo({
map:{
'/static/src/js/index/index.js': 'D:/wamp/www/hxe/js/index/index.js'
}
}))
.pipe(gulp.dest('D:/wamp/www/hxe/temp'))
});
gulp.task('index/submit', function(){
return gulp.src("./public/static/src/js/{index,}/submit_main.js")
.pipe($.seajsCombo({
map:{
'/static/src/js/index/submit.js': 'D:/wamp/www/hxe/js/index/submit.js'
}
}))
.pipe(gulp.dest('D:/wamp/www/hxe/temp'))
});
gulp.task('require/index', function(){
return gulp.src("./public/static/src/js/{require,}/schedule_main.js")
.pipe($.seajsCombo({
map:{
'/static/src/js/require/index.js': 'D:/wamp/www/hxe/js/require/index.js'
}
}))
.pipe(gulp.dest('D:/wamp/www/hxe/temp'))
});
在這里重點強調一下,由於打包的一些限制,我們需要將js文件夾復制一份放到一個絕對路徑文件夾下,我在這放到了 D:/wamp/www/hxe/
下,而我們產生的合並文件也一並存放在這個文件夾下。
還需要注意的一點是我們在一個項目肯定會存在不同的文件夾下有相同的文件名,如我的項目在index和require文件夾下都存在index_main.js
和index.js
這就需要我們用正則區分,即上面的{index,}
和 {require,}
。
四: js壓縮
熟悉gulp的肯定知道我們只有在seajs
合並任務完畢后才能執行壓縮任務,所以我們可以將seajs
任務作為 js
的前置任務。
// 壓縮js
gulp.task('js', ['seajs'], function(){
return gulp.src("D:/wamp/www/hxe/temp/*/*.js")
.pipe($.uglify({
mangle: { except: ['require', 'exports', 'module', '$'] }//排除混淆關鍵字
}))
.pipe($.rev())
.pipe(gulp.dest('./public/static/dist/js'))
.pipe($.rev.manifest())
.pipe($.rename('js-manifest.json'))
.pipe(gulp.dest('./public/static/dist/rev/js'))
});
//清除原來的內容
gulp.task("cleanJs", function(){
return gulp.src('./public/static/dist/js')
.pipe($.clean());
});
在這里,就需要將我們再絕對路徑下合並產生的臨時文件壓縮並輸出到我們的項目路徑下。
五: html壓縮
html的操作,最主要的重頭戲還是在於css和js的路徑替換,所以打包的成功與否html這邊的操作也至為重要。
//html 壓縮
gulp.task('rev',['css','js'],function () {
var options = {
removeComments: true, //清除HTML注釋
collapseWhitespace: true, //壓縮HTML
collapseBooleanAttributes: true, //省略布爾屬性的值 input checked="true" ==> input checked
removeEmptyAttributes: true, //刪除所有空格作屬性值 input id="" ==> input
removeScriptTypeAttributes: true, //刪除<script>的type="text/javascript"
removeStyleLinkTypeAttributes: true, //刪除<style>和<link>的type="text/css"
minifyJS: true, //壓縮頁面JS
minifyCSS: true //壓縮頁面CSS
};
return gulp.src(['./public/static/dist/rev/*/*.json', './application/home/view/**/*.html'])
.pipe($.revCollector({
replaceReved: true,
dirReplacements: {
'/src/css': '/dist/css/',
'/src/js/': '/dist/js/'
}
}))
.pipe($.htmlmin(options))
.pipe(gulp.dest('./application/home/view_build'));
});
//清除html文件夾
gulp.task("cleanhtml", function(){
return gulp.src('./application/home/view_build')
.pipe($.clean());
});
六: 程序的默認執行
程序的默認執行,主要是對gulp打包的順序最后做一遍確認,在控制台直接使用gulp就能觸發default
任務。
//默認任務
gulp.task('default', ['cleancss','cleanJs', 'cleanhtml'], function(){
gulp.start('rev');
});
七: 總結
通過gulp打包seajs項目,主要的核心還是在於map映射的問題,所以我們通過借助絕對路徑的方式可以成功的繞開這個問題--將文件合並放在項目之外。
seajs模塊化,gulp壓縮打包合並只是幾個簡單的命令已經走了好幾個年頭,頗有些“廉頗老矣”的悲情,但是只要腦筋靈活還是能做很多事情的,當然我們也要擁抱變化,webpack都2.0了。。。
gulp打包seajs項目Demo地址 https://github.com/jinghaoo/seaJS-gulp
如果有什么問題,歡迎給我發郵件: jingh1024@163.com