原文連接:http://survivejs.com/webpack_react/webpack_compared/javascript
開始正文前端
當你把Webpack放到過往歷史中你就會很好地理解爲何它的方法是如此的有力。在早些時候,它的能力對於僅僅把一些腳本鏈接在一塊兒是足夠的。然而時光變遷,如今分佈你的Javascript代碼能夠是個複雜的奮鬥者號。java
SPA(單頁應用)的崛起node
隨着單頁應用(SPAs,single page application)的崛起,這個問題已經逐漸凸顯出來。它們傾向於使用很是多笨重的庫。你最不想看到的應該是一次性地把它們所有加載出來。其實有不少很好的解決辦法,Webpack與它們中的不少均可以緊密配合使用。react
得益於Node.js的火爆,Node.js的包管理器npm提供了許多環境。在以前,npm還難以讓開發人員去使用這些依賴。如今,隨着npm已經由於前端開發而變得廣爲熟知,環境已經發生了不少變化。依賴管理也是愈來愈簡單了。jquery
任務運行工具和打包工具webpack
從歷史上來說,已經有了不少的構建系統。Make多是最廣爲數值的,而且仍然是個可行的選項。爲了讓工做簡單一些,專業的任務運行工具,相似於Grunt和Gulp出現了。經過npm可得到的插件使得這些任務運行工具變得很是好用。web
任務運行工具已是高水準中的很是棒的工具了。它們容許你去跨平臺去進行一些操做。可是當你須要把很是多的資源拼接在一塊兒並在生產中打包時問題就會出現了。這也就是爲何咱們須要打包工具,好比Browserify或者Webpack。npm
爲了在這條路上更進一步,JSPM直接向瀏覽器推出了包管理器。它依賴於Systerm.js,一個動態模塊加載器。不像Browserify和Webpack,它跳過了開發過程當中全部的打包步驟。然而你也能夠用它打包生成一個產品。Glen Maddern在他的關於JSPM的視頻中有更多的細節。gulp
Make
你能夠說Make在走下坡路。它最初在1977年發佈。儘管它是個很是老的工具,可是它仍然保持放鬆。Make容許你爲了創造一個生產構建工具去寫一些分散的任務——壓縮你的JavaScript代碼或運行一些測試。你能夠在一些其餘的工具中發現相同的想法。
即便Make在C語言項目中普遍使用,它不以任何方式依賴於這些使用Make的C語言項目。James Coglan在如何經過JavaScript使用Make中討論了細節。仔細思考一下下面的基於James文章的簡短代碼
Makefile
PATH := node_modules/.bin:$(PATH) SHELL := /bin/bash source_files := $(wildcard lib/*.coffee) build_files := $(source_files:%.coffee=build/%.js) app_bundle := build/app.js spec_coffee := $(wildcard spec/*.coffee) spec_js := $(spec_coffee:%.coffee=build/%.js) libraries := vendor/jquery.js .PHONY: all clean test all: $(app_bundle) build/%.js: %.coffee coffee -co $(dir $@) $< $(app_bundle): $(libraries) $(build_files) uglifyjs -cmo $@ $^ test: $(app_bundle) $(spec_js) phantomjs phantom.js clean: rm -rf build
你能夠經過Make使用Make的特殊語法和終端命令來模擬你的任務。這使得它很方便地就能集成Webpack。
Grunt
Grunt在Gulp以前就成爲了主流。特別一提的是它的插件構建特性,這有助於它的流行。同時,這種構建特性也是Grunt的惟一弱點。我知道有不少你不想必須維護一個300行的Gruntfile而了結的經歷。這是Grunt documentation上的一個例子。
module.exports = function(grunt) { grunt.initConfig({ jshint: { files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'], options: { globals: { jQuery: true } } }, watch: { files: ['<%= jshint.files %>'], tasks: ['jshint'] } }); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.registerTask('default', ['jshint']); };
在這個例子中,咱們定義了兩個基本的任務把jshint關聯起來,jshint是個悠久的用來定位你的JavaScript原代碼中可能的問題點的工具。咱們有一個單獨的任務去運行jshint。當咱們運行Grunt時,隨着咱們編輯保存原代碼咱們也會在終端機上獲得實時的警告。
在實踐中,你會爲各類各樣的相似構建一個項目這樣的目標而有不少小任務。 例子展現了這些任務是如何構造的。Grunt的優勢中很重要的一點就是它隱藏了你的不少線路。儘管,過分使用的話仍是會變得有問題的。它會讓你很難徹底理解在表面下進行的是什麼。
注意:grunt-webpack插件能使你在一個Grunt環境下使用Webpack。你能夠告別繁重的Webpack。
Gulp
Gulp採用了不一樣的方法。你能夠用真實的代碼去解決而不是依賴配置配個插件。Gulp構建在可靠地正確的管道基礎上。若是你對Unix熟悉,這裏是相同的理論。你僅僅有軟件源、過濾器和接收器。
軟件源與文件相適配。過濾器在軟件源上進行操做(舉例來講就是轉化成JavaScript代碼)。最後,結果經過給過濾器(舉例來講就是你創建了一個目錄也就是文件夾)。這裏有個從一個項目上的README上拿下來的Gulpfile來幫你更好地理解這種方法。它已經縮寫過了。
var gulp = require('gulp'); var coffee = require('gulp-coffee'); var concat = require('gulp-concat'); var uglify = require('gulp-uglify'); var sourcemaps = require('gulp-sourcemaps'); var del = require('del'); var paths = { scripts: ['client/js/**/*.coffee', '!client/external/**/*.coffee'] }; // Not all tasks need to use streams // A gulpfile is just another node program and you can use all packages available on npm gulp.task('clean', function(cb) { // You can use multiple globbing patterns as you would with `gulp.src` del(['build'], cb); }); gulp.task('scripts', ['clean'], function() { // Minify and copy all JavaScript (except vendor scripts) // with sourcemaps all the way down return gulp.src(paths.scripts) .pipe(sourcemaps.init()) .pipe(coffee()) .pipe(uglify()) .pipe(concat('all.min.js')) .pipe(sourcemaps.write()) .pipe(gulp.dest('build/js')); }); // Rerun the task when a file changes gulp.task('watch', function() { gulp.watch(paths.scripts, ['scripts']); }); // The default task (called when you run `gulp` from CLI) gulp.task('default', ['watch', 'scripts']);
給出配置的是代碼,若是你運行出問題時一般能夠僅僅刪改。你能夠打包做爲Gulp的插件放在Node.js的包管理器中,等等。對比Grunt,你對正在運行的有更清晰的理解。儘管如此,你仍然能夠中止爲臨時任務寫一堆引用。這裏有一些更新的方法來使用。
gulp-webpack容許你在gulp的環境中使用Webpack。
Fly是一個和Gulp類似的工具。它依賴於ES6的生成器。
Browserify
使用JavaScript模塊處理已經有了不少的問題。這種語言自己在ES6以前並無對模塊的明肯定義。所以,當談到瀏覽器環境時,咱們就已經陷在90年代了。各類解決措施包括AMD,已經被提出。
在實際生產中,只使用CommonJS是很是方便點,這是Node.js的格式,而且剩下的能夠用工具解決。優點是你能夠常常鏈接到npm上,能夠避免重複造輪子。
Browserify是一個解決模塊化問題的辦法。它提供了一種一塊兒打包CommonJS模塊一塊兒的方式。你能夠把它和Gulp鏈接到一塊兒。有一些小的轉換工具能使你超越基本用途。例如:watchify提供了一個文件監測器當開發過程當中爲你生成打包。這將省去你不少工夫,而且毫無疑問這在必定程度上是一個好的解決方案。
Browserify的系統是由不少小的模塊組成的。在這一方面,Browserify緊隨Unix哲學。Browserify比Webpack接受起來簡單些,而且確實,是一個好的另外一種選擇。