寫在前面: 這文章寫於15年底,後來16年才放到segmentfault上來,看到陸續仍是有瀏覽量甚至收藏,以避免形成誤導仍是在文章前頭稍稍提醒一下.
當時觀點放到今天不免有些打臉,就目前來講webpack已經徹底佔據主流位置,連我本身的項目都不多會在開發階段用glup了.但我依然以爲webpack與glup二者職能不一樣,例如把一些相似測試任務
,上線部署
之類的事交給gulp這類構建工具是很天然而然的事.webpack依然是打包工具,而打包,只是構建的其中一環而已.
我已經不是第一次看到這相似的話語,爲數很多的人都以爲webpack是目前前端工程化完整性解決方案,打出了終於再也不用糾結使用grunt或是gulp了的旗號,只要使用webpack就足夠了javascript
而事實果然如此?css
首先看看webpack官網給出的解析html
webpack is a module bundler.
簡單來講,官方對webpack的定位是模塊打包器,相比於gulp或是grunt,webpack的競爭對手應該是browserify之流前端
就連webpack官方也給出了webpack with gulp的一些說明java
雖然webpack的確能夠代替gulp的一些功能
可是很是明顯webpack和gulp/grunt就不是一個職能
的工具
因此說取代
還言過其實(以前個人一個提問)react
那麼問題來了webpack
爲何是gulp
而不grunt
?
由於我用的是gulp - -!
要構建這樣一個工做流,首先要理清幾個問題git
就如前面所說,webpack只是一個模塊打包器,因此,交予webpack處理的應該已經是通過各類lint檢查,各類編譯處理的代碼
而各類檢查,各類預處理就應該交給gulp之流了
最後壓縮代碼應該要交給webpack最後打包時再去執行es6
以前一直沒有注意這個問題
看看gulp的基本使用github
gulp.src('client/templates/*.jade') .pipe(jade()) .pipe(minify()) .pipe(gulp.dest('build/minified_templates'));
對於開發中gulp會使用watcher
實時檢查文件是否更新,檢查到有更新則立刻跑相應的構建任務,可是有上面的代碼能夠看出,gulp每次都只能經過通配符匹配大量的文件,而不能就單單獲取修改過的文件,這種狀況在大型項目中每次構建都會花很多時間,更別論要在構建任務以後再加一個webpack的打包任務
不過所幸上網找到一個gulp-changed的插件,實在棒!
以前開發時live reload都是交給gulp的,而如今gulp的構建任務並非在任務鏈的最後端,由gulp來實現顯然再也不合適
基於上面的思考,我作了個嘗試項目
作些簡單的說明,上面的項目只有簡單的幾個構建任務
js
gulp.task('js', function() { return gulp.src('src/**/*.js') .pipe($.changed('build')) // .pipe($.babel({ // presets: ['es2015', 'react'] // })) .pipe($.eslint({config: 'eslint.config.json'})) .pipe($.eslint.format()) .pipe(gulp.dest('build')); });
只簡單的用eslint檢測一下語法而已,而註釋的部分,是使用babel把es6的代碼轉化成es5的代碼,可是這部分應該是由webpack在最後打包階段處理,因此去掉了
css
gulp.task('css', function() { return sass('src/**/*.scss') .pipe($.changed('build')) .on('error', sass.logError) .pipe($.replace('@@FILEURL', fileUrl)) .pipe(gulp.dest('build')); });
就是把scss轉化成css,並替換掉css文件中的佔位符(能夠根據需求加上自動合併雪碧圖或者postcss處理等等)
這裏要說明一下在這個示例項目中其實並無實際編寫任何css或scss,由於項目中的todo應用實際是從redux todo直接拷貝的 = =!
html
gulp.task('html', function() { return gulp.src('src/**/*.html') .pipe($.changed('build')) .pipe($.replace('@@FILEURL'), fileUrl) .pipe(gulp.dest('build')); });
就沒什麼好說的,就是作了一下佔位符替換而已
若是是使用其餘模板引擎就能夠在這裏進行編譯
而live reload應該怎麼作呢?
參考了一下react-transform-boilerplate和redux todo(其實仍是直接拷貝的= =)
gulp.task('default', ['clean', 'js', 'css', 'html', 'watch'], function() { var app = require('./devServer'); var port = 3000; app.listen(port, function(error) { if (error) { console.error(error) } else { console.info("==> ? Listening on port %s. Open up http://localhost:%s/ in your browser.", port, port) } }); });
就是再把全部任務跑一遍後啓動實現live reload的devServer
修改文件時,gulp就會從src
->build
進行構建,而webpack則是檢測着build文件夾是否有更新來進行增量編譯,同時實現live reload
至此,已經把腦中想法基本實現了出來(其實並無,bug多多的說)
再來講說實踐事後的想法
webpack果然是業界殺雞用牛刀的最佳代言人
好吧,多是我接觸webpack不久
在如此小的應用上,使用webpack真是一點都體會不出它的好處
(惟一一點可能就是es6的import語法而已,不過要使用import仍是react或redux等等庫的坑)
在大型項目使用可有成功案例,但願你們不吝指教一下^ ^~
另一點,我還看過幾篇比較gulp和webpack的博文(國內外都有)
大意其實都差很少,就是說,若是用gulp,你要寫多不少代碼,你將會有很是多的開發依賴balabala....
而用webpack,你就能夠經過少許的代碼解決這些問題等等等等的,
且不論代碼多少
的問題,這點我並無實踐過
可是再一次代表個人見解
webpack和gulp/grunt就不是一個職能
的工具,談何取代?
至於代碼多少的問題
有沒有想過,代碼少
就真的必定好
嗎?
我認爲,gulp/grunt
或是browserify/webpack
等等工具的面世,其實都是爲了解決前端的工程化問題
在工程化問題
面前,難道追求的真的是write less, do more
嗎?
舉個例子,各類MV**
的設計模式,真的有讓你們少寫
不少代碼嗎?起碼我並不以爲有那麼一回事
我認爲,付出適當的代價,組合使用各類工具,使用合適的工做流,才能真正起到管理前端工程的做用
至於何爲適當
,何爲合適
,依然須要探索