Skip to content

Instantly share code, notes, and snippets.

@chrisbuttery
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrisbuttery/faf8f763a08141e3a9ed to your computer and use it in GitHub Desktop.
Save chrisbuttery/faf8f763a08141e3a9ed to your computer and use it in GitHub Desktop.
Gulp + Browserify
This example uses Browserify and expects a stucture like
|- gulpfile.js
|
|- package.json
|
|- [javascript]
| |
| | - app.js
| |
| |- [local package]
| |
| |- index.js
| |
| |- [test]
| |
| |- test.js
| |
| |- mocha.js
| |
| |- index.html
| |
| | - (any other mocha shiz)
|
|- [stylesheets]
|
|- [images]
"use strict";
var gulp = require('gulp');
/**
* Build configurations.
*/
var path = require('path');
var Config = {
scriptsDir: path.resolve('./javascript'),
stylesDir: path.resolve('./stylesheets'),
imagesDir: path.resolve('./images'),
publicDir: path.resolve('./public')
};
/**
* Clean
* Empty '/public/' dir
*/
var clean = require('gulp-clean');
gulp.task('clean', function () {
return gulp.src(Config.publicDir, {read: false})
.pipe(clean());
});
/**
* Error handler
* Writes to terminal
*/
var notify = require('gulp-notify');
var handleErrors = function() {
var args = [].slice.call(arguments);
notify.onError({
title: 'Compile error',
message: "<%= error.message %>"
}).apply(this, args);
this.emit('end');
};
/**
* browserify
*/
var browserify = require('browserify');
var source = require('vinyl-source-stream');
gulp.task('browserify', function() {
return browserify({
entries: [Config.scriptsDir + '/app.js'],
extensions: ['.coffee', '.js', '.jsx']
})
.bundle({debug: true})
.on('error', handleErrors)
.pipe(source('app.js'))
.pipe(gulp.dest(Config.publicDir));
});
/**
* images
* Minify images
*/
var changed = require('gulp-changed');
var imagemin = require('gulp-imagemin');
gulp.task('images', function() {
return gulp.src(Config.imagesDir + '/**')
.pipe(changed(Config.publicDir + '/images/'))
.pipe(imagemin())
.pipe(gulp.dest(Config.publicDir + '/images/'));
});
/**
* lint JS
* Ignore mocha.js and build.js from test directories
*/
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
gulp.task('lint', function() {
gulp.src([
Config.scriptsDir + '/**/*.js',
'!' + Config.scriptsDir + '/**/test/mocha.js',
'!' + Config.scriptsDir + '/**/test/build.js'
])
.pipe(jshint('.jshintrc'))
.pipe(jshint.reporter(stylish));
});
/**
* styles
* Concat and Autoprefix any CSS
* Ensure 'normalise.css' is loaded first
*/
var minifyCSS = require('gulp-minify-css');
var concat = require('gulp-concat');
var autoprefix = require('gulp-autoprefixer');
gulp.task('styles', function() {
gulp.src([Config.stylesDir + '/normalize.css', Config.stylesDir + '/*.css'])
.pipe(concat('styles.css'))
.pipe(autoprefix('last 2 versions'))
.pipe(minifyCSS())
.pipe(gulp.dest(Config.publicDir));
});
/**
* buildTests
* This task is called from 'tests'.
* This task (buildTests) will traverse the folders (referenced as 'bundles')
* inside of /javascript/
* If this 'bundle' is a file or doesnt have a child 'test' directory, return.
* otherwise, pass the bundle name to buildTest()
*
* The buildTest() will browserify the test.js file and output as build.js which
* the test runner (index.html) can reference
*/
var buildTest = function(bundle) {
return browserify('./javascript/' + bundle + '/test/tests.js')
.bundle()
.pipe(source('build.js'))
.pipe(gulp.dest('./javascript/' + bundle + '/test/'));
};
var fs = require('fs');
var bundles = fs.readdirSync(Config.scriptsDir);
gulp.task('buildTests', function () {
bundles.forEach(function(bundle) {
var bundlePath = Config.scriptsDir + "/" + bundle;
var bundleTests = bundlePath + "/test/";
if(fs.statSync(bundlePath).isFile() || !fs.statSync(bundleTests)) return;
buildTest(bundle);
});
});
/**
* Tests
* First run 'buildTests' to browserify each test file inside its test dir
* then run the test runner (index.html) in each test directory
*/
var mochaPhantomJS = require('gulp-mocha-phantomjs');
gulp.task('tests', ['buildTests'], function () {
return gulp
.src(Config.scriptsDir + '/**/test/index.html')
.pipe(mochaPhantomJS({
reporter: 'dot'
}));
});
/**
* Watch
* - Run middleman
* - Watch JS, CSS and Images for changes
*/
gulp.task('watch', function() {
gulp.watch(Config.scriptsDir + '/**/*.js', ['lint', 'browserify']);
gulp.watch(Config.stylesDir + '/app.css', ['styles']);
gulp.watch(Config.imagesDir + '/**', ['images']);
});
/**
* Default
* - Clean /public/ dir
* - Lint, Browserify, Run tests, Autoprefix CSS and Minify images
*/
gulp.task('default', ['clean'], function() {
gulp.start('lint', 'browserify', 'tests', 'styles', 'images');
});
{
"name": "my-project",
"version": "0.1.0",
"description": "Gulp project",
"browserify": {
"transform": [
"coffeeify"
]
},
"devDependencies": {
"browserify": "^4.1.9",
"browserify-shim": "^3.5.0",
"chai": "^1.9.1",
"coffeeify": "^0.6.0",
"connect": "^2.14.3",
"gulp": "^3.8.0",
"gulp-autoprefixer": "^0.0.7",
"gulp-browserify": "^0.5.0",
"gulp-changed": "^0.4.0",
"gulp-clean": "^0.3.0",
"gulp-concat": "^2.2.0",
"gulp-imagemin": "^0.6.1",
"gulp-jshint": "^1.6.2",
"gulp-minify-css": "^0.3.4",
"gulp-mocha-phantomjs": "^0.2.2",
"gulp-notify": "^1.3.1",
"gulp-watch": "^0.6.6",
"jshint-stylish": "^0.2.0",
"vinyl-source-stream": "^0.1.1"
},
"dependencies": {}
}
@chrisbuttery
Copy link
Author

Feel free to suggest improvements.

@chrisbuttery
Copy link
Author

When using the component package manager its pretty easy to define a 'local' set of components.
Using NPM/Browserify this isn't as clear.
Im just wondering if anyone has some insight on better ways it can be done?

@chrisbuttery
Copy link
Author

@juliocesar I took bits from your recent gulpfile gist. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment