本文將介紹gulp的基礎使用和一次項目實踐。
1.gulp是一個工具,用於在開發工做流程中自動執行咱們須要執行的任務,好比修改代碼後從新編譯,構建環境等,gulp能夠一行命令搞定這些重複瑣碎的工做。css
gulp.task(name[,deps,fn]):定義任務,任務的名稱不該該有空格,當前執行的任務若是依賴於或者須要其餘任務先執行完,採用下圖方式便可,mytask任務將在其餘四我的任務執行完後執行。html
gulp.task('mytask', ['array', 'of', 'task', 'names'], function() { // Do stuff });
也能夠定義任務用於執行一系列的任務,例如構建開發環境,產品環境。react
gulp.task('build', ['array', 'of', 'task', 'names']);
項目要完成的任務是: 1. 將keppAcounts模塊打包壓縮並提供開發和產品兩套環境的打包 2. 其餘模塊合併相應文件到一個目錄供外殼項目引入 3. 整個項目新老框架兩種打包方式(gulp、webpack)用一個命令完成構建 4. 監聽全部文件的改變
const concat = require("gulp-concat"); //文件的合併 const uglify = require("gulp-uglify"); //js文件壓縮 const cleanCSS = require("gulp-clean-css"); //css文件壓縮 const template = require("gulp-template-compile"); //html模板文件轉爲js文件 const del = require("del"); //清空文件目錄 const webpack = require("webpack-stream"); //在gulp中執行webpack的打包 const rev = require("gulp-rev"); //內容hash碼附加到文件名
gulp.task("gulpKeepAccountsHtml", () => { gulp.src("keepAccounts/templates/**/*.html") .pipe(template({namespace: "keepAccountsTmpl"})) .pipe(concat("keepAccountsTmpl.js")) .pipe(gulp.dest(".tmp")) })
由於項目裏用的html文件只是一些純模板文件,因此轉換後放一個變量下引入便可,不須要採用html文件傳統的去註釋等處理。經過template插件將目錄下的全部html文件經過template插件轉成js模塊,namespace能夠指定轉換後的模板文件放在windows下對應的變量名裏。而後合併成keepAccountsTmpl.js文件,並輸出到一個.tmp文件夾中。webpack
//js模塊=>html模塊執行完以後執行 gulp.task("gulpKeepAccountsJS", ["gulpKeepAccountsHtml"], () => { gulp.src(["keepAccounts/scripts/**/*.js", ".tmp/keepAccountsTmpl.js"]) .pipe(concat("app.js")) .pipe(gulp.dest("keepAccounts")) })
由於這是一個獨立的模塊,html模板代碼不多,因此咱們和js模塊都打入一個包裏。那麼打包js模塊時,須要html模塊先轉化完js,因此這個任務須要先依賴於gulpKeepAccountsHtml任務完成,放在此任務的依賴任務中。而後引入對應的js,html轉換好的js模塊即完成js模塊的合併。es6
gulp.task("gulpKeepAccountsJSPro", ["gulpKeepAccountsHtml"]() => { gulp.src(["keepAccounts/scripts/**/*.js", ".tmp/keepAccountsTmpl.js"]) .pipe(concat("app.js")) .pipe(gulp.dest("keepAccounts")) .pipe(uglify()) .pipe(rev()) .pipe(gulp.dest("../dist/financial/keepAccounts")); })
在產品環境中,代碼須要打包壓縮加上內容哈希碼,這樣若是第二次上線這個模塊的包沒有更新,用戶就不須要從新下載這個包。在開發環境合併(此模塊合併給其餘項目使用)的基礎上,壓縮加上內容哈希碼後輸入到產品環境包目錄下。web
js模塊打包還應該注意的一個問題是,文件合併順序問題。有些工具類文件、樣式要合併在前面,在src裏文件數組的順序就是會打包的順序。gulp
//開發環境 gulp.task('runES6', function () { return gulp.src('scripts-es6/main.js') .pipe(webpack({config:require('./config/webpack.config.dev.js'),watch: true})) .pipe(gulp.dest("packagedFiles/es6")); })
項目裏有些模塊代碼是react寫的,採用了webpack的打包方式。在產品模塊構建時,爲了方便統一構建,在gulp加入構建新框架的代碼。不一樣的環境引入不一樣的webpack配置環境,開發引入的配置文件裏開啓了sorce-map,配置參數watch爲true開啓了webpack的監聽。windows
//開發環境監聽 gulp.task("watch", function () { livereload.listen(); gulp.watch(jsFiles, ["gulpAppJS"]); gulp.watch(["views/**/*.html", "!views/MainView.html"],["gulpTemplate"]); gulp.watch(cssFiles, ["gulpAppCSS"]); gulp.watch(["data/*"], ["copyData"]); gulp.watch(["keepAccounts/templates/**/*.html", "keepAccounts/scripts/**/*.js"], ["gulpKeepAccountsJS"]); gulp.watch(["keepAccounts/styles/**/*.css"], ["gulpKeepAccountsCSS"]); });
兩個模塊的文件分別監聽,當文件發生改變時從新打包。由於最終運行的項目是一個外殼項目,須要把更新後的代碼從新打包傳過去。數組
/*開發環境構建*/ //運行命令 gulp gulp.task("default", ["copyData", "gulpTemplate", "gulpAppCSS", "gulpAppJS", "copyImage", "gulpKeepAccountsJS", "gulpKeepAccountsCSS","watch","runES6"]); /*生產環境構建*/ //運行命令 gulp build gulp.task("build", ["delFinancial", "copyData", "gulpTemplate", "gulpAppCSS", "gulpAppJS", "copyImage", "gulpKeepAccountsJSPro", "gulpKeepAccountsCSSPro","runES6Pro"]);
兩個命令分別對應不一樣的環境,執行不一樣的任務。app
沒有考慮model、collections、viewModels的合併順序,原來是統一將js模塊下的代碼都合併。解決方案是按順序將文件目錄寫進src的數組裏,按順序合併。這也說明了一個項目規劃好目錄的重要性。
有兩個css文件打包順序錯誤,致使後面一個文件的樣式覆蓋了上一個文件,這兩個文件都是寫分頁組件相關的。解決方案爲了避免多引入插件,將應該後打入的文件名改成z開頭,合併順序是按文件名字母排列,也能夠引入order插件解決。
(1)configuration.output.path: The provided value "./packagedFiles/es6" is not an absolute path! -> The output directory as absolute path (required).
解決:產生錯誤的地方是webpack.config.js的配置文件的output中path路徑,這個路徑改了屢次都沒有生效,後來想到的是,用gulp.dist能夠直接輸出打包後的文件在正確的地址,用不着裏面配置的output,去掉以後解決。
(2)Chunk.entry was removed. Use hasRuntime()
解決:產生的緣由是引用的插件webpack-stream裏面的webpack已經升級到3.4.1,而項目裏的webpak版本仍是1.13.2,升級版本後問題解決。