ionic代碼壓縮與代碼混淆
歡迎大家到我的部落格檢視相應内容,并關注我學習Ionic 1和Ionic 2的曆程,共同學習,共同進步。
本文為譯文,并加入個人了解部分,如有了解錯誤指出,請大家指出,大家也可移步原文。
本文解釋了ionic工程釋出之前的最後一步,即代碼壓縮(擷取更好的性能)以及代碼混淆(以免源碼被有心者輕易擷取)。包括以下步驟:
- (cordova hook)
:這一步需要在代碼壓縮和代碼混淆之前進行以保證javascript代碼無錯誤檢查javascript
- (gulp task)
:這一步起到了混淆html頁面代碼的作用将html頁面代碼轉換為angular的JS代碼
- (gulp task)
:這一步需要在代碼混淆之前進行以保證angular的依賴注入沒有問題啟用angular嚴格依賴注入
- (gulp task)
:這一步起到了混淆js代碼以及css代碼的作用組合js代碼以及組合css代碼
- (cordova hook)
:最後一步 -代碼醜化、壓縮、混淆
為完成上述任務,我們需要同時使用gulp tasks以及cordova hooks。當執行
ionic serve
時,gulp tasks會被執行。當執行
ionic build android/ios
或
ionic run android/ios
時,cordova hooks會被執行。
首先注意,本文說明的工程目錄結構如下,讀者需要根據不同的工程進行路徑修改:
$PROJECT_DIR/
hooks/
www/
js/
xxx.js
...
templates/
login/
xxx.html
...
register/
xxx.html
...
.../
...
...
index.html
檢查javascript
1.這一步需要用到jshint以及async,可以使用npm安裝:
$ npm install jshint --save-dev
$ npm install async --save-dev
2.複制cordova hooks檔案:
将此檔案下載下傳,并複制到$PROJECT_DIR/hooks/before_prepare檔案夾裡。特别注意需要給予此檔案“可執行”的權限,即
$ chmod +x file_name
注意:此檔案負責檢測$PROJECT_DIR/www/js/目錄下的js檔案是否有誤,請根據自己工程的實際情況對此檔案進行修改:
如我的工程中有2個存放js檔案的路徑:$PROJECT_DIR/www/js目錄和$PROJECT_DIR/www/patchjs目錄,則我需要對上述檔案進行如下修改:
var foldersToProcess = [
'js'
];
替換為:
var foldersToProcess = [
'js', 'patchjs'
];
3.測試:
終端執行:
$ ionic build android/ios
若成功,則可在終端輸出中看到工程中js檔案是否有錯誤,并指出錯誤/警告的行、列數以及錯誤/警告的原因:
檢查無誤:
檢查有誤:
根據輸出提示資訊可知www/patchjs/e2e-tests.conf.js檔案的第15行的第二列缺失了一個分号。
注意:js代碼中使用
eval
函數也會導緻此項檢測報錯,建議使用其他方法代替
eval
函數,如必須使用,可以使用
标注:
/*jslint evil: true */
var temp = eval('(' + JSON.stringify(response) + ')');
将html頁面代碼轉換為angular的JS代碼
這一步對html頁面代碼的混淆是将html頁面代碼處理成angular的js代碼(儲存到一個js檔案中)。
1.這一步需要用到gulp-angular-templatecache。可以使用npm安裝:
npm install gulp-angular-templatecache --save-dev
2.修改gulpfile.js檔案:
var templateCache = require('gulp-angular-templatecache');
var paths = {
sass: ['./scss/**/*.scss'],
templatecache: ['./www/templates/**/*.html']
};
gulp.task('templatecache', function (done) {
gulp.src('./www/templates/**/*.html')
.pipe(templateCache({standalone:true}))
.pipe(gulp.dest('./www/js'))
.on('end', done);
});
gulp.task('default', ['sass', 'templatecache']);
gulp.task('watch', function() {
gulp.watch(paths.sass, ['sass']);
gulp.watch(paths.templatecache, ['templatecache']);
});
3.修改ionic.project檔案:
"gulpStartupTasks": [
"sass",
"templatecache",
"watch"
]
4.在app.js中增加 templates
子產品依賴:
templates
angular.module('starter', ['ionic', 'starter.controllers', 'templates'])
5.在index.html中引入templates.js檔案:
注意:這裡的templates.js檔案是下一步生成的。
6.測試:
$ ionic serve
或者
$ gulp templatecache
執行完畢,在$PROJECT_DIR/www/js目錄下将生成templates.js檔案,此檔案中将包含對html頁面代碼的轉換結果。
7.改變templateUrl路徑:
打開$PROJECT_DIR/www/js/templates.js檔案,我們可以看到類似于下面的代碼:
$templateCache.put("login.html", ...
大家可以看到,此時的
login.html
前面沒有
templates
路徑字首,其他的html檔案也是類似的,是以我們之前在js中使用
templateUrl
指定的html檔案路徑便需要作出相應變化—-去除
templates
路徑字首:
首先,我們要知道哪裡會使用到
templateUrl
屬性,可能有如下幾種情況:
1.app.js中使用
$stateProvider.state()
定義路由時;
2.類似于
$ionicPopover
的控件或自定義的directives中到;
我們以情況1為例說明修改的過程:
app.js之前可能的情況:
.state('login', {
url: "/",
templateUrl: "templates/login.html",
controller: 'LoginCtrl'
});
修改之後則為:
.state('login', {
url: "/",
templateUrl: "login.html",
controller: 'LoginCtrl'
});
其他的也類似地進行修改。
啟用angular ng-strict-di
在我們進行代碼壓縮之前,我們需要啟用angular的ng-strict-di,即嚴格依賴注入,使用ng-strict-di使得工程中依賴注入不會有問題,更多關于ng-strict-di可以看這裡。
1.首先通過npm安裝gulp-ng-annotate:
$ npm install gulp-ng-annotate --save-dev
2.其次,修改gulpfile.js檔案:
var ngAnnotate = require('gulp-ng-annotate');
var paths = {
sass: ['./scss/**/*.scss'],
templatecache: ['./www/templates/**/*.html'],
ng_annotate: ['./www/js/*.js']
};
gulp.task('ng_annotate', function (done) {
gulp.src('./www/js/*.js')
.pipe(ngAnnotate({single_quotes: true}))
.pipe(gulp.dest('./www/dist/dist_js/app'))
.on('end', done);
});
gulp.task('default', ['sass', 'templatecache', 'ng_annotate']);
gulp.task('watch', function() {
gulp.watch(paths.sass, ['sass']);
gulp.watch(paths.templatecache, ['templatecache']);
gulp.watch(paths.ng_annotate, ['ng_annotate']);
});
3.修改ionic.project檔案:
"gulpStartupTasks": [
"sass",
"templatecache",
"ng_annotate",
"watch"
]
4.重新定位index.html裡js的檔案:
<script src="dist/dist_js/app/app.js"></script>
<script src="dist/dist_js/app/controllers.js"></script>
<script src="dist/dist_js/app/services.js"></script>
<script src="dist/dist_js/app/templates.js"></script>
5.在 ng-app
标簽下加入directive: ng-strict-di
:
ng-app
ng-strict-di
6.測試
$ ionic serve
或
$ gulp ng_annotate
上面的執行過程将會生成$PROJECT_DIR/www/dist/dist_js/app檔案夾,并且其中包含了嚴格符合注入标準的工程js檔案。
合并js檔案以及css檔案
1.通過npm安裝gulp-useref:
$ npm install gulp-useref --save-dev
2.其次,修改gulpfile.js檔案:
var useref = require('gulp-useref');
var paths = {
sass: ['./scss/**/*.scss'],
templatecache: ['./www/templates/**/*.html'],
ng_annotate: ['./www/js/*.js'],
useref: ['./www/*.html']
};
gulp.task('useref', function (done) {
var assets = useref.assets();
gulp.src('./www/*.html')
.pipe(assets)
.pipe(assets.restore())
.pipe(useref())
.pipe(gulp.dest('./www/dist'))
.on('end', done);
});
gulp.task('default', ['sass', 'templatecache', 'ng_annotate', 'useref']);
gulp.task('watch', function() {
gulp.watch(paths.sass, ['sass']);
gulp.watch(paths.templatecache, ['templatecache']);
gulp.watch(paths.ng_annotate, ['ng_annotate']);
gulp.watch(paths.useref, ['useref']);
});
3.修改ionic.project檔案:
"gulpStartupTasks": [
"sass",
"templatecache",
"ng_annotate",
"useref",
"watch"
]
4.修改index.html檔案,對需要合并的js檔案和css檔案進行處理:
<!-- build:css dist_css/styles.css -->
<link href="css/ionic.app.css" rel="stylesheet">
<!-- endbuild -->
<!-- build:js dist_js/app.js -->
<script src="dist/dist_js/app/app.js"></script>
<script src="dist/dist_js/app/controllers.js"></script>
<script src="dist/dist_js/app/services.js"></script>
<script src="dist/dist_js/app/templates.js"></script>
<!-- endbuild -->
注意:可能有些外部的css檔案或js檔案不想被處理,那麼就保持原狀即可。
5.測試
$ ionic serve
或
$ gulp useref
上面的執行過程會生成以下檔案:
$PROJECT_DIR/www/dist/index.html
$PROJECT_DIR/www/dist/dist_css/styles.css
$PROJECT_DIR/www/dist/dist_js/app.js
其中後面2個檔案,即是被合并過後的檔案。
注意:新版本的gulp-useref沒有assets()方法,是以可能會出現錯誤,大家可以用gulp-useref的2.1.0版本,即第一步安裝時使用:
$ npm install [email protected] --save-dev
最後一步
1.使用npm安裝 cordova-uglify
以及 mv
:
cordova-uglify
mv
$ npm install cordova-uglify --save-dev
$ npm instal mv --save-dev
2.複制cordova hooks檔案:
将這些檔案添加至$PROJECT_DIR/hooks/after_prepare檔案夾中。并且要注意這些檔案中的有關路徑的操作,是對應于前幾步中的路徑的,如果工程結構不一樣,請自行調整這些檔案中有關路徑的部分。特别注意需要給予此檔案“可執行”的權限,即
$ chmod +x file_name
現在,我們就可以生成處理完成的檔案了:
$ ionic build android/ios
延伸閱讀
ionic代碼壓縮與代碼混淆