Created
October 10, 2015 18:14
-
-
Save oscar-g/4ec52eacc3eb533ddd31 to your computer and use it in GitHub Desktop.
React js dev workflow gulp file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var gulp = require('gulp'), | |
source = require('vinyl-source-stream'), | |
browserify = require('browserify'), | |
watchify = require('watchify'), | |
gulpif = require('gulp-if'), | |
uglify = require('gulp-uglify'), | |
streamify = require('gulp-streamify'), | |
notify = require('gulp-notify'), | |
concat = require('gulp-concat'), | |
gutil = require('gulp-util'), | |
livereload = require('express-livereload'), | |
extReplace = require('gulp-ext-replace'), | |
babelify = require('babelify'), | |
mergeStream = require('merge-stream'), | |
del = require('del'), | |
htmlReplace = require('gulp-html-replace'), | |
gulpConcat = require('gulp-concat'), | |
styl = require('gulp-stylus'); | |
var globalOpts = { | |
srcDir : './src/', | |
appDir : './src/app/', | |
clientDir : './src/client/', | |
cssFile : './src/styles/main.styl', | |
cssGlob : './src/styles/**/*.styl', | |
assetsGlob : './src/assets/**/*', | |
buildDir: './build/', | |
htdocsDir: './build/htdocs', | |
deps: [ | |
'react', | |
'react/addons', | |
'react-router', | |
'react-dom', | |
'react-bootstrap', | |
'history', | |
'formsy-react', | |
'jquery' | |
] | |
}; | |
/** | |
* The main gulp tasks | |
* taskName:dev for development | |
* taskName:dist for production | |
*/ | |
/** | |
* Builds the app for development, including styles, livereload, server, and watches for changes | |
*/ | |
gulp.task('default', ['dev']); | |
gulp.task('dev', ['app:dev', 'html:dev', 'styles:dev', 'assets', 'watch:styles', 'serve']); | |
/** | |
* Builds the app for production with minified code. | |
*/ | |
// gulp.task('dist', ['app:dist', 'html:dist', 'styles:dist', 'assets', 'server:dist']); | |
//sub tasks below | |
/** | |
* Compiles the ReactJS app for development. | |
* Splits code into 2 bundles: app and development. | |
* Watches app bundle and regenrates on change. | |
* | |
* @see _process_bundle() | |
* @see _get_bundle() | |
*/ | |
gulp.task('app:dev', ['clean'], function(){ | |
var bnls = _get_bundle(true, globalOpts.clientDir + 'main.jsx'), | |
stream = mergeStream(), | |
app, vendor; | |
watchify(bnls.app).on('update', function(){ | |
_process_bundle(bnls.app, 'APP', 'main.js', true); | |
}); | |
app = _process_bundle(bnls.app, 'APP', 'main.jsx', true), | |
vendor = _process_bundle(bnls.vendor, 'VENDOR', 'vendors.jsx', true); | |
stream.add(app); | |
stream.add(vendor); | |
return stream; | |
}); | |
/** | |
* Compiles the ReactJS app for production | |
*/ | |
gulp.task('app:dist', ['clean'], function(){ | |
var bnls = _get_bundle(false, globalOpts.clientDir + 'main.jsx'); | |
return _process_bundle(bnls.app, 'APP', 'main.jsx', false); | |
}); | |
/** Deletes the contents of the build/htdocs dir (except the css)*/ | |
gulp.task('clean', function(){ | |
return del([ | |
'!' + globalOpts.htdocsDir + 'main.css', | |
globalOpts.htdocsDir + '**/*' | |
], { | |
dot: true | |
}); | |
}); | |
/** Deletes the css*/ | |
gulp.task('clean:css', function(){ | |
return del(globalOpts.htdocsDir + 'main.css'); | |
}); | |
/** | |
* Copies the index.html (app entry point) | |
* Injects a live reload script. | |
*/ | |
gulp.task('html:dev', ['clean'], function(){ | |
return gulp.src(globalOpts.clientDir + 'index.html') | |
.pipe(htmlReplace({ | |
'livereload': { | |
src: "document.write('<script src=\"http://' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1\"></' + 'script>')", | |
tpl: "<script>%s</script>" | |
}, | |
'scripts': { | |
src: ['/vendors.js', '/main.js'] | |
} | |
})) | |
.pipe(gulp.dest(globalOpts.htdocsDir)); | |
}); | |
/** | |
* Copies the production index.html to the htdocs folder (app entry point) | |
*/ | |
gulp.task('html:dist', ['clean'], function(){ | |
return gulp.src(globalOpts.clientDir + 'index.html') | |
.pipe(htmlReplace({ | |
'scripts': { | |
src: ['/main.js'] | |
} | |
})) | |
.pipe(gulp.dest(globalOpts.htdocsDir)); | |
}); | |
/** | |
* Runs the development server | |
*/ | |
gulp.task('serve', ['app:dev'], function(){ | |
var server = require( globalOpts.srcDir + 'server/index.js')(true, globalOpts.htdocsDir); | |
livereload(server, { | |
watchDir: globalOpts.htdocsDir | |
}); | |
server = server.listen(8889, function(){ | |
console.log('Development server listening at http://localhost:%s', server.address().port); | |
}); | |
}); | |
/** Copies assets from the assets directory to the destination directory */ | |
gulp.task('assets', ['clean'], function(){ | |
return gulp.src(globalOpts.assetsGlob, {dot: true}) | |
.pipe( gulp.dest(globalOpts.htdocsDir) ); | |
}); | |
/** Compiles un-minified styles for development */ | |
gulp.task('styles:dev', ['clean:css'], function(){ | |
return gulp.src(globalOpts.cssFile) | |
.pipe(styl()) | |
.pipe(gulp.dest(globalOpts.htdocsDir)); | |
}); | |
/** Compiles minified styles for production */ | |
gulp.task('styles:dist', ['clean:css'], function(){ | |
return gulp.src(globalOpts.cssFile) | |
.pipe(styl({ | |
compress: true | |
})) | |
.pipe(gulp.dest(globalOpts.htdocsDir)); | |
}); | |
/** watches styles for changes, runs styles: task */ | |
gulp.task('watch:styles', function(){ | |
return gulp.watch(globalOpts.cssGlob, ['styles:dev']); | |
}); | |
/** | |
* Helper functions below | |
*/ | |
/** | |
* Returns an object with the app bundle and (if dev) the vendor bundle | |
*/ | |
function _get_bundle(dev, src) { | |
var opts = { | |
entries: [src], | |
transform: [babelify], | |
extensions: ['.jsx'], | |
cache: {}, | |
packageCache: {}, | |
debug: dev, | |
fullPaths: dev | |
}, | |
bundle = browserify(opts), | |
bundles = {}; | |
if (dev === true) { | |
globalOpts.deps.forEach(function (dep) { | |
bundle.external(dep); | |
}); | |
bundles.vendor = browserify({ | |
debug: true, | |
require: globalOpts.deps | |
}); | |
} | |
bundles.app = bundle | |
return bundles; | |
} | |
/** | |
* Processes a bundle. Minifies when dev. | |
*/ | |
function _process_bundle(bnl, name, src, dev) { | |
var start = Date.now(); | |
return bnl.bundle() | |
.on('error', gutil.log) | |
.pipe(source(src)) | |
.pipe(gulpif(!dev, streamify(uglify()))) | |
.pipe(extReplace('.js')) | |
.pipe(gulp.dest( globalOpts.htdocsDir ) ) | |
.pipe(notify(function () { | |
console.log(name + ' bundle built in ' + (Date.now() - start) + 'ms'); | |
})); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment