原文连接: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接受起来简单些,而且确实,是一个好的另外一种选择。