簡單介紹一下目前開發 AngularJS 的工具 - gulp。
gulp 是幫助前端開發的工具,幫助我們 complie 語法或優化效能 (minify 或 concat js 等)。
網路上有很多大大都有介紹 gulp 跟實際用法,要不然看官網學也很快。
心動不如馬上行動 -> 官網
今天只會帶到一點在開發 AngularJS 會使用到的 gulp 套件,
假如你/或你身邊有再寫 AngularJS 可是沒有用任何工具去優化效能的人。請務必試試~
我們目前使用 gulp 是主要完成 minify 跟 concat 的部分。
minify:
minify AngularJS 會有兩步驟。
1. ng-annotate
先岔題來說一下 AngularJS 使用 DI 的其中兩種方式。
Implicite Dependencies
function 裡 argument 的名稱就是要 DI 的 service 名稱,所以不能變更
app.controller(‘MyCtrl’, function ($scope, service) {
/..../
})
Inline Array Annotation
把 DI 名稱改寫成 array 形式,在 function 的名稱就可以變更
app.controller(‘MyCtrl’, [‘$scope’, ‘myService’, function ($scope, s) {
/..../
})
回到壓縮 AngularJS 話題。
假如使用 Implicite Dependencies 的方式下壓縮。
在壓縮的過程中,壓縮會把 argument 名稱也壓縮到,導致 AngularJS 的 DI 無法找到指定的 service 而壞掉。
ex: (壓縮後)
angular.module("a").controller("b", function (c,d) {...});
// Error: [$injector:unpr] Unknown provider: cProvider <- c
AngularJS 不知道 c 跟 d 分別代表什麼 dependency
ng-annotate 就是幫我們把程式裡有用到 DI 的地方都幫我們轉換成 Inline Array Annotation。
確保程式在壓縮的時候就不會壞掉了!
ex: (壓縮後)
// work well!!
angular.module("a").controller("b", ['$scope', '$timeout', function (c,d) {...}]);
所以說壓縮檔案前, 一定要先讓 ng-annotate 檢查一下.
(我的習慣是要求自己先寫好 inline array annotation, 之後使用 ng-annotate 求心安~)
目前的 gulp task
gulp.src(’src')
.pipe(ngAnnotate())
.pipe(gulp.dest, ‘/dist/'));
壓縮 uglify:
加壓縮是先載入 uglify 工具後,確認跑完 ng-annotate 之後再執行。
gulp.src(’src')
.pipe(ngAnnotate())
.pipe(uglify())
.pipe(gulp.dest, ‘/dist/'));
concat:
concat 主要目的就是把你的檔案都連結在一起,讓客戶端只要只載入一份 JavaScript 檔案就好。
大大的提升因為載入太多隻檔案發生的塞車。
(尤其是 AngularJS module 觀念,使得程式的 JavaScript 的分散在多隻 JavaScript 檔案)
讓壓縮後的檔案都連接在一起。
// ‘all.min.js’ 是 concat 後 output 出來的檔名
gulp.src(’src')
.pipe(ngAnnotate())
.pipe(uglify())
.pipe(concat, 'all.min.js')
.pipe(gulp.dest, ‘/dist/'));
順利的跑完上面的 gulp task 後,會發現 minify 後的檔案其實非常不好 debug...
尤其還在測試階段的話,就不要自己害自己了。
把 gulp task 寫成兩種 task。
附上完整的程式:
var gulp = require('gulp’),
concat = require('gulp-concat'),
ngAnnotate = require('gulp-ng-annotate'),
uglify = require('gulp-uglify’);
// 上面沒有細講。
// 在檔案更新的時候,幫我們跑 task 。不用每次都手動跑 task
gulp.task('watch', function() {
// 開始 watch 就先幫我們建一份出來
gulp.start('developer');
gulp.watch('/app/**/*.js', ['developer']);
});
gulp.task(’developer’), function () {
// 在 debug 階段,只要跑 concat 就好
gulp.src(’src')
.pipe(concat, 'all.min.js')
.pipe(gulp.dest, ‘/dist/'));
}
// build 階段在跑 minify + concat
gulp.task(’build’), function () {
gulp.src(’src')
.pipe(ngAnnotate())
.pipe(uglify())
.pipe(concat, 'all.min.js')
.pipe(gulp.dest, ‘/dist/'));
}
ng-Annotation, uglify, concat 在 grunt 也有,假如習慣用 grunt 的朋友也可以選擇 grunt ~
除了 ng-Annotation, uglify, concat,gulp 跟 grunt 還有很多工具方便我們使用。
ex:
rimraf 在跑前清除前一份 build 好的檔案,避免奇怪事發生。
ngHtml2js 幫我們把 template 都先放在 $templateCache module,
我們只要下載一份 $templateCache JavaScript 檔案就好。
還有 gutil, lazypipe, htmlmin 等等很多工具可以去尋找!!
番外篇:Bower
Bower 是管理開發 application 需要的 package。
我們主要是拿來下載 bootstrap 跟 angular 的套件 (ui-router, angular-sanitize, etc)
等把 package 下載好後,在用現在的 gulp-concat 把需要的 library concat 成一份 JavaScript 檔案。
有鑑於網路上有很多教學... 我就不寫方法了。(飄走)
bower 官網