時間匆匆如流水繼上週熟悉了gulp的初步安裝與環境配置之後,個人項目又進入了新的階段!
這篇文章將把我這一週遇到的一些問題,以及解決的方式作一個小小的總結,不必定記的完整,但都是我的的一點經驗,分享給你們。有什麼錯誤疏漏還望指正。
1.angular仍是vue?
這裏我是有很大的猶豫的,最後的結果是angular。這裏有不少私心,這個項目須要技術上的認同,angular做爲一個熱門前端框架擁有更大的知名度,這是我選擇angular的一部分緣由。另外若是詳細的對比,團隊技術若是從jquery轉型,能夠嘗試接觸vue,vue的上手更簡單,這裏不作展開了。
2.requirejs仍是webpack?
最後的決定是用webpack,由於我requirejs要到瀏覽器端去進行代碼的組織,而webpack在上線以前就把這些作好了,因此性能應該更好。並且webpack能夠打包其餘類型資源,如css與圖片,雖然我如今不打算用這些功能,但能給我留下一些擴展改變的空間。最後requirejs和angular的組合須要引入angular的異步插件,這樣讓我望而卻步。而webpack引入angular只須要一句require('angular');
固然,這裏邊也有些坑,不過都是後話了。
3.那麼如今開始整合吧,先從webpack與gulp的整合開始。
webpack與gulp的整合(固然前提是安裝了webpack,同窗們本身去官網查看安裝嘍),能夠經過gulp的一個插件來作,這個插件的名字叫gulp-webpack,名字是否是至關直觀?最簡單的使用方式以下:
gulp-webpack的npm文檔javascript
gulpWebpack = require('gulp-webpack');
...//stream
.pipe(gulpWebpack(require('./webpack.config.js')))
...//stream
遇到的坑一個(採用配置文件運行webpack失敗),這個連接裏有詳細的問答: gulp-webpack的坑
好了,這兩個就配置好了,那麼項目整合angular以前,咱們還有一件事沒有作,那就是watch
對了,watch很重要啊,實時的編譯寫好的代碼,這樣才能更有效率的搭建框架,編寫代碼。
watch的同時,咱們還想要把自動緩存清理的機制加進去。從網上查了,gulp的插件rev配合revCollector能夠完成這個任務。這裏有一篇很不錯的文章
gulp解決項目部署緩存
讀完以後,咱們瞭解到,這樣作對於個人服務器,還不是很完美,由於我沒有靜態資源服務器啊,並且上面的資源固然也不是永不過時。相反的,若是資源沒用我就但願儘快的刪掉。從網上看了一些,感受沒有合適個人,因而就須要本身動手刪掉。好比編譯sass,直接使用rev的流程是這樣的:css
.pipe(sass.sync().on('error', sass.logError))
.pipe(minifyCss())
.pipe(rename(function(path){
path.basename=path.basename;
path.extname = ".css";
}))
.pipe(rev({merge: true}))
.pipe(gulp.dest(distCss))
.pipe(rev.manifest())
.pipe(gulp.dest(distRev+'/css'));
那麼在進入rev步驟以前,咱們要把服務器上已有的文件刪掉,刪文件就用del這個命令,須要一個參數,要刪掉的文件的路徑,咱們用這個through2這個命令來獲取gulp流中的文件路徑,地址稍微手動修改一下,指到編譯結果的文件夾裏:html
var gulp = require('gulp'),
sass = require('gulp-sass'),
rename = require('gulp-rename'),
minifyCss = require('gulp-minify-css'),
debug = require('gulp-debug'),
rev = require("gulp-rev"),
revCollector = require("gulp-rev-collector"),
through = require("through2"),
del = require("del");
gulp.task('compile-sass',function(){
return gulp.src('src/scss/*.scss')
.pipe(changed(distCss,{extension:'.css'}))
.pipe(debug({title:'debuging:'}))
.pipe(through.obj(function(chunk,encode,callback){
var delPath = chunk.cwd+"/"+distCss+"/"+chunk.relative.substring(0,chunk.relative.lastIndexOf("."))+"-*"+".css";
console.log(delPath);
del(delPath);
this.push(chunk);
callback();
}))
.pipe(sass.sync().on('error', sass.logError))
.pipe(minifyCss())
.pipe(rename(function(path){
path.basename=path.basename;
path.extname = ".css";
}))
.pipe(rev({merge: true}))
.pipe(gulp.dest(distCss))
.pipe(rev.manifest())
.pipe(gulp.dest(distRev+'/css'));
});
gulp.task('revCollectorHtml',function(){
return gulp.src(['webContent/rev/**/*.json','webContent/index.html'])//注意參數是一個數組,用【】包起來的,要否則會報沒法給第二個參數建立cwd屬性的錯誤
.pipe(revCollector({
replaceReved:true //必定要加上這一句,否則不會替換掉上一次的值
}))
.pipe(gulp.dest(distBase));
});
這樣,watch的任務就變成了:監聽文件變化,並在變化之後,將rev-collector任務完成。咱們採用異步的策略來作這件事:前端
var watchScss = gulp.watch('src/scss/*.*',gulpSync.sync([['compile-sass'],'revCollectorHtml']));
個人文件目錄結構以下:vue
│ gulpfile.js
│ karma.conf.js
│ package.json
│ webpack.config.js
│
├─node_modules
├─src
│ │ index.html
│ │
│ ├─js
│ │ │ app.js
│ │ │ index.js
│ │ │ router.js
│ │ │
│ │ └─modules
│ │ appUsedetailModule.js
│ │ listsModule.js
│ │ statisticModule.js
│ │
│ ├─scss
│ │ index.scss
│ │
│ └─tpls
│
│
├─test
│ testIndex.js
│
└─webContent
│ favicon.ico
│ index.html
│
├─css
│ index-5067f89afc.css
│
├─js
│ bundle-588100fbe5.js
│
├─rev
│ ├─css
│ │ rev-manifest.json
│ │
│ └─js
│ rev-manifest.json
│
└─tpls
整個gulpfile.js就變成了這樣:java
var gulp = require('gulp'),
sass = require('gulp-sass'),
rename = require('gulp-rename'),
minifyCss = require('gulp-minify-css'),
changed = require('gulp-changed'),
uglify = require('gulp-uglify'),
debug = require('gulp-debug'),
minifyHtml = require('gulp-minify-html'),
webpack = require("webpack"),
rev = require("gulp-rev"),
revCollector = require("gulp-rev-collector"),
through = require("through2"),
del = require("del"),
ngAnnotate = require("gulp-ng-annotate"),
gulpWebpack = require('gulp-webpack');
var gulpSync = require('gulp-sync')(gulp);
var distCss = 'webContent/css',
distJs = 'webContent/js',
distRev = 'webContent/rev',
distBase = 'webContent';
gulp.task('compile-sass',function(){
return gulp.src('src/scss/*.scss')
.pipe(changed(distCss,{extension:'.css'}))
.pipe(debug({title:'debuging:'}))
.pipe(through.obj(function(chunk,encode,callback){
var delPath = chunk.cwd+"/"+distCss+"/"+chunk.relative.substring(0,chunk.relative.lastIndexOf("."))+"-*"+".css";
console.log(delPath);
del(delPath);
this.push(chunk);
callback();
}))
.pipe(sass.sync().on('error', sass.logError))
.pipe(minifyCss())
.pipe(rename(function(path){
path.basename=path.basename;
path.extname = ".css";
}))
.pipe(rev({merge: true}))
.pipe(gulp.dest(distCss))
.pipe(rev.manifest())
.pipe(gulp.dest(distRev+'/css'));
});
gulp.task('compile-js',function(){
return gulp.src('src/js/**/*.js')
.pipe(changed(distJs))
.pipe(debug({title:'debuging js:'}))
.pipe(through.obj(function(chunk,encode,callback){
var delPath = chunk.cwd+"/"+distJs+"/bundle-*"+".js";
console.log(delPath);
del(delPath);
this.push(chunk);
callback();
}))
.pipe(gulpWebpack(require('./webpack.config.js')))
.pipe(ngAnnotate())
.pipe(uglify())
.pipe(rev())
.pipe(gulp.dest(distJs))
.pipe(rev.manifest())
.pipe(gulp.dest(distRev+'/js'))
});
gulp.task('compile-html',function(){
return gulp.src('src/**/*.html')
.pipe(changed(distBase,{extension:'.html',cwd: ''}))
.pipe(debug({title:'debuging:'}))
.pipe(minifyHtml())
.pipe(rename(function(path){
path.basename=path.basename;
path.extname = ".html";
}))
.pipe(gulp.dest(distBase));
});
gulp.task('revCollectorHtml',function(){
return gulp.src(['webContent/rev/**/*.json','webContent/index.html'])//注意參數是一個數組,用【】包起來的,要否則會報沒法給第二個參數建立cwd屬性的錯誤
.pipe(revCollector({
replaceReved:true //必定要加上這一句,否則不會替換掉上一次的值
}))
.pipe(gulp.dest(distBase));
});
// gulp.task('revCollectorCss',function(){
// return gulp.src(['webContent/rev/css/*.json','webContent/css/*.css'])
// .pipe(revCollector({
// replaceReved:true //必定要加上這一句,否則不會替換掉上一次的值
// }))
// .pipe(gulp.dest(distCss));
// });
function getWatchDelFunc(type){
return function(event){
if(event.type==='deleted'){
var basePath = event.path.substring(0,event.path.lastIndexOf("src"));
var fileName = event.path.substring(event.path.lastIndexOf("\\")+1,event.path.lastIndexOf("."));
var delPath = basePath+distCss+"/"+fileName+"-*."+type;
console.log("watchDelPaths:"+delPath);
del(delPath);
}
}
}
gulp.task('watch',function(){
var watchScss = gulp.watch('src/scss/*.*',gulpSync.sync([['compile-sass'],'revCollectorHtml']));
var watchJs = gulp.watch('src/js/**/*.*',gulpSync.sync([['compile-js'],'revCollectorHtml']));
var watchHtml = gulp.watch('src/**/*.html',gulpSync.sync([['compile-html'],'revCollectorHtml']));
watchScss.on('change',getWatchDelFunc("css"));
// watchJs.on('change',getWatchDelFunc("js"));
watchHtml.on('change',getWatchDelFunc("html"));
});
gulp.task('default',gulpSync.sync([['compile-sass','compile-html','compile-js'],'revCollectorHtml','watch']));
webpack.config.js裏只作了最基本的js編譯:node
var webpack = require("webpack");
module.exports = {
debug: true,
watch: false,
entry: "./src/js/index.js",
output: {
path: __dirname+'/webContent/js',
filename: "bundle.js"
},
module: {
loaders: [
]
},
resolve: {
},
plugins: [
]
}