現在咱們開發web網頁的方式主要有幾種,使用vue-cli、create-react-app、webpack、不借助構建工具
等實現單頁或多頁網站。「工欲善其事,必先利其器」,前三種方式無疑能知足咱們開發網頁的絕大部分需求,但在某些狀況下,好比先後端不分離(jsp、php、tpl等嵌套後端語言的方式),以及單純地開發一些靜態頁(活動頁、幫助手冊等),使用gulp搭建一個輕量級的前端開發環境是一個選擇。javascript
gulp相對上手簡單,有經驗的前端也都比較熟悉,這裏不打算一步步地介紹gulp開發環境的搭建,而是分享一下實際使用gulp的代碼及思路。php
使用gulp的目的是實現自動化構建,提高開發效率、代碼質量,因此有如下一些目標。css
實際上gulp能作到的還有更多,不過出於開發靜態頁的目的,這裏只羅列了一些經常使用功能。html
基本目錄以下 前端
gulpfile.js主要代碼vue
gulp.task('server', done => {
connect.server({
root: 'dist',//根目錄
livereload: true,//自動更新
port: 9090//端口
})
done();
});
複製代碼
gulp.task('html', function () {
return gulp.src('src/*.html')
.pipe(htmlmin({ collapseWhitespace: true }))
.pipe(gulp.dest('dist'))
.pipe(connect.reload())
})
複製代碼
gulp.task('css', done => {
var processors = [px2rem({ remUnit: 100 })];
gulp.src('src/less/**/*.less') //獲取全部less文件路徑
.pipe(less())         //執行less
.pipe(autoprefixer({//補全前綴
overrideBrowserslist: [
"Android 4.1",
"iOS 7.1",
"Chrome > 31",
"ff > 31",
"ie >= 8"
]
}))
.pipe(postcss(processors))//px轉rem tips: 若是某個px不轉換,可以使用大寫代替,相似1PX
.pipe(minifyCss())
.pipe(gulp.dest('dist/css'))
.pipe(connect.reload())
done();
});
複製代碼
gulp.task('js', function () {
return gulp.src('src/js/**/*.js')
//.pipe(jshint())//檢查代碼
.pipe(babel({//編譯ES6
presets: ['@babel/env']
}))
.pipe(uglify())//壓縮js
.pipe(gulp.dest('dist/js'))
.pipe(connect.reload())
})
複製代碼
gulp.task('images', function () {
return gulp.src('src/images/**/*.+(png|jpg|jpeg|gif|svg)')
.pipe(imagemin())
.pipe(gulp.dest('dist/images'))
});
複製代碼
gulp.task('watcher', done => { //監聽變化
gulp.watch('src/*.html', gulp.series('html'));
gulp.watch('src/less/**/*.less', gulp.series('css'));
gulp.watch('src/js/**/*.js', gulp.series('js'));
gulp.watch('src/images/**/*', gulp.series('images'));
done();
})
複製代碼
這裏還使用了gulp-rev-delete-original
刪除舊文件。java
gulp.task("hash", done => {
gulp
.src("dist/**")
.pipe(
RevAll.revision({
dontRenameFile: [/\.html$/]
})
)
.pipe(revdel({
exclude: function (file) {
if (/\.html$/.test(file.name)) {
return true; //if you want to exclude the file from being deleted
}
}
}))
.pipe(gulp.dest("dist"))
done();
});
複製代碼
打開本地服務器,以及打包文件。react
// 初始化
gulp.task('init', gulp.series('clean', gulp.parallel('html', 'css', 'js', 'images')));
// 開發
gulp.task('default', gulp.series('init', 'server', 'watcher'));
// 打包
gulp.task('build', gulp.series('hash'));
複製代碼
能夠看出上面的代碼比較簡單,由於初衷是作一些簡單的靜態頁,因此並無作得比較複雜,監控文件變化編譯至dist目錄,再由gulp-rev-all生成hash文件名。webpack
這裏須要區分先後端不分離的狀況,因爲公司的技術不升級,或者須要維護老項目,就要應付先後端不分離的場景。好比頁面是jsp、php文件,這時靜態頁跟實際頁面並無直接對應關係,每次gulp打包後,gulp-rev-all會從新生成帶hash的文件和路徑,而且不支持test.css?v=123
這種方式,這樣所有手動複製到項目目錄並不實際,只能放棄gulp-rev-all(build
),而且移除代碼壓縮。git
值得一提的是,先後端不分離能夠用後端語言進行資源的緩存控制,例如使用php讀取文件的修改日期來作版本號。
function autoVersion($file) {
if( file_exists($_SERVER['DOCUMENT_ROOT'].$file) ) {
$ver = filemtime($_SERVER['DOCUMENT_ROOT'] . $file);
} else {
$ver = 1;
}
return $file .'?v=' .$ver;
}
複製代碼
<link rel="stylesheet" href="<?= autoVersion('xxx/css/main.css')?>"> <!-- main.css?v=13579 -->
複製代碼
此外,應對先後端不分離應該還有一種解決方案,藉助構建工具直接生成後端所需的模板文件(如index.tpl),這裏暫不討論。
這些是根據工做經驗總結出來的,雖然當下使用或基於webpack開發單頁是主流,但在某些覆蓋不到的場景下進行一些梳理仍是有必要的。
源碼地址:gulp-util,另外附上一個webpack多頁腳手架webpack-multiple-entry,這是做者fork別人的項目來修改的,比較簡單實用,感興趣的小夥伴能夠參考下。