ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
## 第二步 构建系统 如果你经常参与web社区,那么你应该听说过[Browserify](http://browserify.org/)和[Webpack](http://webpack.github.io/)工具。如果不使用它们,你将面临手动的在HTML输入很多`<script>`标签,并且需要将JS代码放到合适的地方。 ![](https://box.kancloud.cn/2015-09-14_55f6422bd4f37.jpg) 并且,我们还不能直接在浏览器使用ES6,在将代码提供给用户之前,我们需要用Babel将它们转换为ES5代码。 我们将使用Gulp和Browserify而不用Webpack。我并不认为它们两个谁优谁劣,但我想说Gulp+Browserify比等价的Webpack文件要直观多了,我还没有在任何React boilerplate项目中看到一个易于理解的*webpack.config.js*文件。 创建文件*gulpfile.js*并粘贴下面的代码: ~~~ var gulp = require('gulp'); var gutil = require('gulp-util'); var gulpif = require('gulp-if'); var streamify = require('gulp-streamify'); var autoprefixer = require('gulp-autoprefixer'); var cssmin = require('gulp-cssmin'); var less = require('gulp-less'); var concat = require('gulp-concat'); var plumber = require('gulp-plumber'); var source = require('vinyl-source-stream'); var babelify = require('babelify'); var browserify = require('browserify'); var watchify = require('watchify'); var uglify = require('gulp-uglify'); var production = process.env.NODE_ENV === 'production'; var dependencies = [ 'alt', 'react', 'react-router', 'underscore' ]; /* |-------------------------------------------------------------------------- | Combine all JS libraries into a single file for fewer HTTP requests. |-------------------------------------------------------------------------- */ gulp.task('vendor', function() { return gulp.src([ 'bower_components/jquery/dist/jquery.js', 'bower_components/bootstrap/dist/js/bootstrap.js', 'bower_components/magnific-popup/dist/jquery.magnific-popup.js', 'bower_components/toastr/toastr.js' ]).pipe(concat('vendor.js')) .pipe(gulpif(production, uglify({ mangle: false }))) .pipe(gulp.dest('public/js')); }); /* |-------------------------------------------------------------------------- | Compile third-party dependencies separately for faster performance. |-------------------------------------------------------------------------- */ gulp.task('browserify-vendor', function() { return browserify() .require(dependencies) .bundle() .pipe(source('vendor.bundle.js')) .pipe(gulpif(production, streamify(uglify({ mangle: false })))) .pipe(gulp.dest('public/js')); }); /* |-------------------------------------------------------------------------- | Compile only project files, excluding all third-party dependencies. |-------------------------------------------------------------------------- */ gulp.task('browserify', ['browserify-vendor'], function() { return browserify('app/main.js') .external(dependencies) .transform(babelify) .bundle() .pipe(source('bundle.js')) .pipe(gulpif(production, streamify(uglify({ mangle: false })))) .pipe(gulp.dest('public/js')); }); /* |-------------------------------------------------------------------------- | Same as browserify task, but will also watch for changes and re-compile. |-------------------------------------------------------------------------- */ gulp.task('browserify-watch', ['browserify-vendor'], function() { var bundler = watchify(browserify('app/main.js', watchify.args)); bundler.external(dependencies); bundler.transform(babelify); bundler.on('update', rebundle); return rebundle(); function rebundle() { var start = Date.now(); return bundler.bundle() .on('error', function(err) { gutil.log(gutil.colors.red(err.toString())); }) .on('end', function() { gutil.log(gutil.colors.green('Finished rebundling in', (Date.now() - start) + 'ms.')); }) .pipe(source('bundle.js')) .pipe(gulp.dest('public/js/')); } }); /* |-------------------------------------------------------------------------- | Compile LESS stylesheets. |-------------------------------------------------------------------------- */ gulp.task('styles', function() { return gulp.src('app/stylesheets/main.less') .pipe(plumber()) .pipe(less()) .pipe(autoprefixer()) .pipe(gulpif(production, cssmin())) .pipe(gulp.dest('public/css')); }); gulp.task('watch', function() { gulp.watch('app/stylesheets/**/*.less', ['styles']); }); gulp.task('default', ['styles', 'vendor', 'browserify-watch', 'watch']); gulp.task('build', ['styles', 'vendor', 'browserify']); ~~~ > 如果你从未使用过Gulp,这里有一个很棒的教程《[An Introduction to Gulp.js](http://www.sitepoint.com/introduction-gulp-js/)》 下面简单介绍一下每个Gulp任务是干嘛的。 | Gulp Task | Description | | --- | --- | | `vendor` | 将所有第三方JS文件合并到一个文件 | | `browserify-vendor` | 因为性能原因,我们将NPM模块和前端模块分开编译和打包,因此每次重新编译将会快个几百毫秒 | | `browserify` | 仅将app文件编译并打包,不包括其它模块和库 | | `browserify-watch` | 包括上面的功能,并且监听文件改变,然后重新编译打包app文件 | | `watch` | 当文件改变时重新编译LESS文件 | | `default` | 运行上面所有任务并开始监听文件改变 | | `build` | 运行上面所有任务然后退出 | 下面,我们将注意力转移到项目结构上,我们将创建*gulpfile.js*需要的文件和文件夹。