这篇文章算是对上一篇文章《在微信中使用ionic1之填坑总结》的一个补充,是项目在微信浏览器中使用出现缓存问题的一个解决方案。
在上篇文章的最后提出来了还可以做得更好的一个点就是关于缓存这个问题的优化。当时提出来的做法是在每个页面的ur后面加上一个时间戳来实现去缓存,但是最后通过实践发现这个办法并不可行。最后的最后,选择使用Gulp来完成了这个任务。
关于Gulp
Gulp是一个前端的自动化构建工具,做前端的同学应该都知道。比如之前的Grunt,以及现在流行的Webpack。
但是作为一个从做原生(Native APP)开发到做混合(Hybrid APP)开发再到把混合开发的APP移植到微信公众号程序猿来说,这是一个新的知识点。
通过自动化构建工具,我们可以完成对代码的合并、压缩以及混淆,这里的代码包含JS、HTML、CSS甚至还有图片文件。
其实原生开发的IDE已经帮我们做了大部分的自动化构建的工作,以至于在原生开发的时候并不是很关心这方面。
为什么是Gulp?
最简单的原因就是ionic1本身就是支持Gulp的,在创建好的ionic1项目中就已经包含了gulpfile.js文件。
使用Gulp的前期准备工作这里就不再多讲,请自行参考--Gulp中文网--。
使用Gulp打包之后的优缺点:
优点:
- 无需引入其他第三方的框架(比如RequireJS)即可拆分js文件,避免了出现超级js文件
- 打包压缩之后,代码体积减小,文件数量减少,节省了加载时间
- 在引用文件是配合参数的使用,解决了微信浏览器中的缓存问题
缺点:
- 每次代码修改之后都必须要打包之后才能看到修改的结果,不能像之前代码修改之后马上就能看到效果。这是目前最大的一个缺点,暂时未发现解决办法
在项目中使用Gulp
在项目中使用Gulp,需要完成3个工作:
- 配置gulpgile.js文件,以及安装相关Gulp插件
- angularJS代码的改造
- 修改index.html中对文件的引用
在gulpfile.js中引入相关插件(ps:记得在项目中安装相关Gulp的插件!)
var concat = require('gulp-concat');
var minifyCss = require('gulp-minify-css');
var rename = require('gulp-rename');
var sh = require('shelljs');
var ngmin = require('gulp-ngmin');
var uglify = require('gulp-uglify');
var stripDebug = require('gulp-strip-debug');
var ngAnnotate = require('gulp-ng-annotate');
var ngHtml2Js = require('gulp-ng-html2js');// ng模板合并压缩成js
合并压缩 js
这里要合并压缩的js是我们自己写的那些js代码,也就是www/js目录下的文件。对于本地的第三方js文件,最好是放到lib目录中去,第三方的js基本不会怎么改变,而且大部分第三方的js代码都是已经打包过了的。
gulp.task('minifyJs', function () {
return gulp.src('./www/js/**/*.js') // 需要操作的文件
.pipe(concat('myionic.js')) // 合并需要操作的文件为一个文件myionic.js
.pipe(gulp.dest('./www/dist')) // 输出myionic.js到www/dist目录
.pipe(rename('myionic.min.js')) // 文件重命名为myionic.min.js
.pipe(ngAnnotate())
.pipe(ngmin({dynamic: false}))//Pre-minify AngularJS apps with ngmin
.pipe(stripDebug())//除去js代码中的console和debugger输出
.pipe(uglify({compress: true})) // 压缩
.pipe(gulp.dest('./www/dist')); // 输出
});
合并压缩angularjs模板
gulp.task('html2js', function () {
return gulp.src("./www/templates/**/*.html")//原路径
.pipe(ngHtml2Js({
moduleName: "myionic.templates"
}))//html模板转js文件
.pipe(concat("templates.min.js"))//合并
.pipe(uglify({compress: false}))//压缩
.pipe(gulp.dest("./www/dist"));//目标路径
});
合并压缩css
gulp.task('minifyCss', function () {
return gulp.src("./www/css/*.css")
.pipe(concat('myionic.min.css'))
.pipe(minifyCss())
.pipe(gulp.dest("./www/dist"));
});
对js代码的改造,首先是app.js
var myionic = angular.module('imcyz', ['ionic', 'myionic.controllers', 'myionic.services', 'myionic.directives', 'myionic.filters', 'ngCordova', 'ionicLazyLoad', 'ngTouch', 'myionic.templates']);
// 这里的myionic.templates对应合并压缩angularjs模板中的moduleName
var controllers = angular.module('myionic.controllers', []);
var services = angular.module('myionic.services', []);
var directives = angular.module('myionic.directives', []);
var filters = angular.module('myionic.filters', []);
myionic.run(['$ionicPlatform', '$rootScope', '$timeout', '$http', '$ionicPopup', '$ionicHistory', '$location', '$ionicLoading', function ($ionicPlatform, $rootScope, $timeout, $http, $ionicPopup, $ionicHistory, $location) {
// TODO
}
myionic.config(['$stateProvider', '$urlRouterProvider', '$ionicConfigProvider', '$httpProvider', '$locationProvider', function ($stateProvider, $urlRouterProvider, $ionicConfigProvider, $httpProvider, $locationProvider) {
$ionicConfigProvider.platform.android.tabs.style('standard');
$ionicConfigProvider.platform.android.tabs.position('standard');
$ionicConfigProvider.platform.android.navBar.alignTitle('center');
$ionicConfigProvider.platform.android.backButton.previousTitleText('ion-android-arrow-back');
$ionicConfigProvider.platform.android.views.transition('android');
$ionicConfigProvider.views.swipeBackEnabled(false);
// TODO
}
因为我们已经打包了项目中的模板文件,所以在配置路由的templateUrl,甚至是其他(比如modal)的templateUrl,也就只需要配置为templates之后的路径。
然后,是controller、service、factory、directive、filter文件的改造
所有的依赖注入都必须严格按照下面的样式来写,包括在app.js中的依赖注入,不然在打包之后运行项目会报错。
controllers.controller('AboutUsCtrl', ['$scope', '$cordovaAppVersion', function ($scope, $cordovaAppVersion,) {
// TODO
}]);
services.service("MyService", ['$http', function ($http) {
// TODO
}]);
services.factory("MyFactory", ['$http', '$injector', function ($http, $injector) {
// TODO
}]);
directives.directive('setFocus', ['$timeout', function ($timeout) {
return {
link: function (scope, element) {
$timeout(function () {
element[0].focus();
}, 500);
}
};
}]);
filters.filter('trustedAsRes', ['$sce', function ($sce) {
return function (url) {
return $sce.trustAsResourceUrl(url);
};
}]);
至此也就完成了代码的改造以及Gulp的配置。
可以单个的执行gulp html2js这样的命令来合并压缩模板文件,也可以通过把任务加到default里面去,直接一个gulp命令执行所有要执行的任务。
gulp.task('default', ['html2js','minifyCss','minifyJs']);
改造index.html
在命令行运行gulp命令之后,在项目的www目录下就会多出一个dist目录,里面包含4个文件。
www/
../dist/
../../myionic.js
../../myionic.min.js
../../myionic.min.css
../../templates.min.js
在index.html中对文件的引用,也就只需引用以上四个文件即可。
myionic.js只是所有js文件的合并,可以在开发的时候使用方便调试。
myionic.min.js做了混淆,适合用于正式上线的生产环境。
在每个文件引用里面加入一个版本参数v,每次代码改变之后都需要变更v的值,这样就可以达到去缓存的效果了!!!