Gulp
Gulp是一款項目自動化的構建工具,與Grunt一樣可以通過創建任務(Task)來幫助我們自動完成一些工作流的內容。當然,今天我們的內容並不是討論這二者的區別,僅僅是介紹介紹如何利用Gulp來優化我們的Web項目中前端自動化工作流。
引言
相信不少人看過百度大牛張雲龍的那篇講解大公司里怎樣開發和部署前端代碼?的文章,如果沒有閱讀的朋友請戳。由於在項目部署時,我們需要對項目js,css,image等文件進行壓縮,合並處理,從而減少客戶端對服務Http請求,已達到增強頁面的加載速度,優化服務器帶寬壓力等等目的。所以本文主要講的是利用Gulp優化我們Web部署優化工作。
安裝&初始化
首先你得確保你的電腦上面是否已經安裝了Nodejs, 如果沒有安裝的話,那么請移步。假定有如下一個Nodejs的Web項目(當然你也可以是其他的例如Java,.Net的Web項目,且具體開發目錄如下:
|- project
|- src // 前端項目的源文件
|- js
|- html
|- images
|- css
|- bower_component // bower 前端依賴包管理
|- node_component // nodejs 插件
|- server
|- api
|- views
|- app
|- assets // 前端靜態文件存放目錄
|- js
|- css
|- images
|- templates
|- ... // 其他目錄就不一一列出了
src
文件夾為前端的js
,css
, html
, image
的開發目錄, 我們會通過gulp將這些源文件進行壓縮合並后打包到目標目錄,也就是assets
目錄下相應的js
,css
目錄,html視圖文件會打包到views
下的app
文件夾和assets
下的templates
模板文件夾,具體視情況而定。其中的bower_component
為bower前端包管理,我們可以用bower直接下載幾乎任何我們前端日常所需的庫,框架,而且可以任選版本,例如JQuery
,Bootstrap
,Angular
,只需執行bower install packageName
即可,不同版本只需bower install packageName#version
,更多內容,可以去官網自行查閱,這里就不展開了。至於node_component
文件夾即是用npm
安裝的我們打包會用到的插件資源了。
-
全局安裝Gulp
$ npm install --global gulp
-
安裝Gulp到開發項目中
$ npm install --save-dev gulp
-
在src創建
gulpfile.js
文件,這個文件用來配置我們所需的task
,接下來會具體講解。 -
執行
$ gulp 或者 $ gulp taskName
gulp會執行
gulpfile.js
文件下定義的default
任務,如果我們需要執行特定的task,則需要執行下面的命令
gulpfile.js文件
gulpfile.js
用來定義我們需要自動化的任務,里面包含了很多依賴關系。這里我們會創建4個Task,第一個develop task
,用於開發時使用,另一個release task
,用於部署發布時用的,還有一個watch task
, 用於實時監聽文件修改行為,可及時打包,最后一個default task
, gulp默認執行的task.
創建Default Task
var gulp = require('gulp'); gulp.task('default', function() { // place code for your default task here }); // 如果默認情況下我們會執行一個叫develop的task,則這么寫,執行gulp命令時, // 會自動調用develop gulp.task('default', ['develop']);
創建Develop Task
創建develop task
前,先介紹下我們今天要用到的一些插件
- gulp-uglify Js壓縮插件
- gulp-minify-css Css壓縮插件
- gulp-imagemin 圖片壓縮插件,支持格式: PNG, JPEG, GIF and SVG images
- gulp-strip-debug 清除源文件console,debugger代碼
- gulp-useref 合並壓縮html文件中的文件
以上列出的插件為我個人常用的一些插件,如果你還有fonts文件的話,也可以添加進去,gulp有很多其他或者相似的插件,都可以去google搜索。安裝方法則是正常的npm
安裝,可以戳進官網去查看。
首先我們需要為我們要壓縮的源文件配置路徑以及導入插件,假設我們bower里面已有jquery和bootstrap插件,以及其他源文件目錄,如下:
// 引入插件 var uglify = require('gulp-uglify'); // 壓縮 var minifyCss = require('gulp-minify-css'); var stripDebug = require('gulp-strip-debug'); // 該插件用來去掉console和debugger語句 var useref = require('gulp-useref'); var imagemin = require('gulp-imagemin'); var pngquant = require('imagemin-pngquant'); // 任務處理的文件路徑配置 var paths = { js: [ // js目錄 'app/*' ], css: [ 'css/*' ], img: [ 'images/*' ], html: [ 'html/*' ], lib: { // 第三方依賴文件 js: [ 'bower_components/bootstrap/dist/js/bootstrap.js', 'bower_components/jquery/jquery.js' ], css: [ 'bower_components/bootstrap/dist/css/bootstrap.css' ], img: [ 'bower_components/bootstrap/dist/images/*' ] } };
定義develop task
var output = "../server/assets/"; // output /* 開發環境 */ gulp.task('develop', function() { gulp.src(paths.js) .pipe(gulp.dest(output + '/js')); gulp.src(paths.lib.js) .pipe(gulp.dest(output + '/js')); gulp.src(paths.css) .pipe(gulp.dest(output + '/css')); gulp.src(paths.lib.css) .pipe(gulp.dest(output + '/css')); gulp.src(paths.img) .pipe(gulp.dest(output + '/images')); gulp.src(paths.lib.img) .pipe(gulp.dest(output + '/images')); });
上面的develop task直接將代碼都輸出到了我們的server目錄下,並未通過插件進行相應的處理,主要是因為我們等會還會創建release task
, 當真正部署的時候我們才進行壓縮合並這些處理。
定義release task
/* 部署環境 */ gulp.task('release', function() { gulp.src(paths.js) .pipe(stripDebug()) .pipe(gulp.dest(output + '/js')); gulp.src(paths.lib.js) .pipe(stripDebug()) .pipe(gulp.dest(output + '/js')); gulp.src(paths.css) .pipe(gulp.dest(output + '/css')); gulp.src(paths.lib.css) .pipe(gulp.dest(output + '/css')); gulp.src(paths.img) .pipe(imagemin({ progressive: true, svgoPlugins: [{removeViewBox: false}], use: [pngquant()] })) .pipe(gulp.dest(output + '/images')); gulp.src(paths.lib.img) .pipe(imagemin({ progressive: true, svgoPlugins: [{removeViewBox: false}], use: [pngquant()] })) .pipe(gulp.dest(output + '/images')); var assets = useref.assets(); gulp.src(paths.html) .pipe(assets) .pipe(gulpif('*.js', uglify())) .pipe(gulpif('*.css', minifyCss())) .pipe(assets.restore()) .pipe(useref()) .pipe(gulp.dest(output + '/templates')); });
上面的代碼首先是先打包靜態文件到指定包,去掉多余的console,debugger,給圖片文件進行壓縮處理,最后利用useref
插件對ejs視圖文件中的js,css進行壓縮合並處理,並打包到指定目錄。
利用useref
對html內部的文件進行壓縮合並
上面的release
中我們以及定義了對app目錄下html文件內部的js,css進行壓縮何必,僅僅配置task是還不夠的,我還需要在html內部做如下配置:
<html> <head> <!-- build:css css/main.css --> <link href="css/style.css" rel="stylesheet"> <link href="css/bootstrap.cs.css" rel="stylesheet"> <!-- endbuild --> </head> <body> <!-- build:js scripts/main.js --> <script type="text/javascript" src="js/bootstrap.js"></script> <script type="text/javascript" src="js/jquery.js"></script> <!-- endbuild --> </body> </html>
經過合並后的文件:
<html> <head> <link rel="stylesheet" href="css/main.css"/> </head> <body> <script type="text/javascript" src="js/main.js"></script> </body> </htm>
更多關於gulp-useref的使用方法請戳。
定義watch Task
watch task
是為了監聽文件發生改變后立即觸發的任務,已便於我們開發。代碼如下:
var watcher = gulp.watch(paths.scripts, ['develop']); watcher.on('change', function (event) { console.log('Event type: ' + event.type); // added, changed, or deleted console.log('Event path: ' + event.path); // The path of the modified file });
總結
以上基本介紹了如何使用gulp來自動完成打包,壓縮,合並文件等任務,Gulp插件非常多,本文只是簡單的介紹了幾種基本的。總之,使用gulp,只需要幾行命令便可以完成以上任務,使很多優化工作變得十分簡單。