gulp+webpack+angular1的一點小經驗(第一部分gulp與webpack的整合)
阿新 • • 發佈:2018-12-15
時間匆匆如流水繼上週熟悉了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文件
gulpWebpack = require('gulp-webpack');
...//stream
.pipe(gulpWebpack(require('./webpack.config.js')))
...//stream
遇到的坑一個(採用配置檔案執行webpack失敗),這個連結裡有詳細的問答: gulp-webpack的坑
好了,這兩個就配置好了,那麼專案整合angular之前,我們還有一件事沒有做,那就是watch
對了,watch很重要啊,實時的編譯寫好的程式碼,這樣才能更有效率的搭建框架,編寫程式碼。
watch的同時,我們還想要把自動快取清理
gulp解決專案部署快取
讀完之後,我們瞭解到,這樣做對於我的伺服器,還不是很完美,因為我沒有靜態資源伺服器啊,而且上面的資源當然也不是永不過期。相反的,如果資源沒用我就希望儘快的刪掉。從網上看了一些,感覺沒有合適我的,於是就需要自己動手刪掉。比如編譯sass,直接使用rev的流程是這樣的:
.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流中的檔案路徑,地址稍微手動修改一下,指到編譯結果的資料夾裡:
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']));
我的檔案目錄結構如下:
│ 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就變成了這樣:
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編譯:
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: [
]
}