-
Notifications
You must be signed in to change notification settings - Fork 3
gulp
Chunliang Lyu edited this page Dec 18, 2015
·
22 revisions
Stack
- ES6 with babel
- liveroading
- browsersync for web project, provides more features
- gulp-livereload for browser extension projects, (since it only requires WebSocket, while browser-sync use socket.io)
- require-dir and then split tasks into files
- libsass via gulp-sass for speed (instead of gulp-ruby-sass)
- webpack instead of browserify
Install dependencies:
npm install --save-dev babel babel-core babel-eslint babel-loader babel-runtime del eslint eslint-loader glob gulp gulp-if gulp-imagemin gulp-livereload gulp-minify-css gulp-sass gulp-sequence gulp-sourcemaps gulp-util gulp-zip json-loader lodash require-dir webpack yargs
Directory structure:
.
├── README.md
├── app
│ ├── _locales
│ ├── fonts
│ ├── images
│ ├── index.html
│ ├── scripts
│ └── styles
├── dist
├── .eslintrc
├── gulpfile.babel.js
├── tasks
│ ├── styles.js
│ ├── scripts.js
│ ├── livereload.js
│ ├── default.js
│ ├── images.js
│ ├── fonts.js
│ └── clean.js
└── package.json
- Definition of gulp tasks will be put in
./tasks/
directory - use
--watch
to enable watching - use
--production
to enable compression etc - use
--verbose
to show verbose logs
Gulp supports ES6, create a file named gulpfile.babel.js
:
import requireDir from 'require-dir';
requireDir('./tasks');
import gulp from 'gulp';
import del from 'del';
gulp.task('clean', (cb) => {
del('dist/**/*').then(() => {
cb();
});
});
import gulp from 'gulp';
import gulpSequence from 'gulp-sequence';
gulp.task('default', gulpSequence(
'clean', [
'manifest',
'scripts',
'styles',
'html',
'locales',
'images',
'fonts',
'livereload'
]
));
import gulp from 'gulp';
import gulpif from 'gulp-if';
import livereload from 'gulp-livereload';
import yargs from 'yargs';
let argv = yargs.argv;
let production = !!argv.production;
let watch = !!argv.watch;
gulp.task('html', () => {
return gulp.src('app/pages/**/*.html')
.pipe(gulp.dest('dist/pages'))
.pipe(gulpif(watch, livereload()));
});
import gulp from 'gulp';
import gutil from 'gulp-util';
import path from 'path';
import glob from 'glob';
import _ from 'lodash';
import webpack from 'webpack';
import livereload from 'gulp-livereload';
import yargs from 'yargs';
let argv = yargs.argv;
let production = !!argv.production;
let watch = !!argv.watch;
let verbose = !!argv.verbose;
let appDir = path.resolve(__dirname, '../app');
function globToEntryMap(...args) {
var files = glob.sync(...args)
return _(files)
.map(function(filePath) {
var bundleName = path.basename(filePath, '.js');
return [bundleName, `./${filePath}`];
})
.zipObject()
.value();
}
function createWebpackConfig() {
return {
devtool: production ? null : 'inline-source-map',
watch: watch,
context: appDir,
entry: globToEntryMap('scripts/*.js', {
cwd: appDir
}),
output: {
path: 'dist/scripts',
filename: '[name].js'
},
plugins: [
new webpack.DefinePlugin({
'ENV': JSON.stringify(production ? 'production' : 'development')
}),
].concat(production ? [
new webpack.optimize.UglifyJsPlugin()
] : []),
module: {
loaders: [{
test: /\.js$/,
loaders: ['babel-loader?optional=runtime'],
exclude: /node_modules/
}, {
test: /\.json$/,
loader: 'json-loader'
}],
preLoaders: [{
test: /\.js$/,
loader: 'eslint-loader',
exclude: /node_modules/
}],
},
eslint: {
configFile: '.eslintrc'
},
node: {
console: true,
fs: 'empty',
tls: 'empty',
net: 'empty'
}
};
};
gulp.task('scripts', (cb) => {
let styledName = gutil.colors.cyan(`'webpack'`);
gutil.log('Starting', styledName);
webpack(createWebpackConfig(), (err, stats) => {
if (err) throw new gutil.PluginError('webpack', err);
gutil.log('Finished', styledName + ':\n', stats.toString({
colors: true,
reasons: verbose,
hash: verbose,
version: verbose,
timings: verbose,
chunks: verbose,
chunkModules: verbose,
cached: verbose,
cachedAssets: verbose,
children: verbose
}));
if (watch) {
livereload.reload()
} else {
cb();
}
});
});
I choose scss for css preprocessor.
import gulp from 'gulp';
import gulpif from 'gulp-if';
import gutil from 'gulp-util';
import sourcemaps from 'gulp-sourcemaps';
import sass from 'gulp-sass';
import minifyCSS from 'gulp-minify-css';
import livereload from 'gulp-livereload';
import yargs from 'yargs';
let argv = yargs.argv;
let production = !!argv.production;
let watch = !!argv.watch;
gulp.task('styles:css', function() {
return gulp.src('app/styles/*.css')
.pipe(gulpif(production, minifyCSS()))
.pipe(gulp.dest('dist/styles'))
.pipe(gulpif(watch, livereload()));
});
gulp.task('styles:sass', function() {
return gulp.src('app/styles/*.scss')
.pipe(gulpif(!production, sourcemaps.init()))
.pipe(sass().on('error', function(error) {
gutil.log(gutil.colors.red('Error (' + error.plugin + '): ' + error.message));
this.emit('end');
}))
.pipe(gulpif(production, minifyCSS()))
.pipe(gulpif(!production, sourcemaps.write()))
.pipe(gulp.dest('dist/styles'))
.pipe(gulpif(watch, livereload()));
});
gulp.task('styles', [
'styles:css',
'styles:sass'
]);
import gulp from 'gulp';
import gutil from 'gulp-util';
import gulpSequence from 'gulp-sequence';
import livereload from 'gulp-livereload';
import yargs from 'yargs';
let argv = yargs.argv;
let watch = !!argv.watch;
let verbose = !!argv.verbose;
gulp.task('livereload', (cb) => {
// This task runs only if the
// watch argument is present!
if (!watch) return cb();
// Start livereload server
livereload.listen({
reloadPage: 'Extension',
quiet: !verbose
});
gutil.log('Starting', gutil.colors.cyan('\'livereload-server\''));
// Hint: Scripts are being watched by webpack!
// For more info checkout ./webpack.js
gulp.watch('app/styles/**/*.css', ['styles:css']);
gulp.watch('app/styles/**/*.less', ['styles:less']);
gulp.watch('app/styles/**/*.scss', ['styles:sass']);
gulp.watch('app/pages/**/*.html', ['pages']);
gulp.watch('app/_locales/**/*', ['locales']);
gulp.watch('app/images/**/*', ['images']);
gulp.watch('app/fonts/**/*.{woff,ttf,eot,svg}', ['fonts']);
});
images are assumed to located at app/images
, it will be copied to dist/images
. If in production, imagemin
will be used to compress images.
import gulp from 'gulp';
import gulpif from 'gulp-if';
import imagemin from 'gulp-imagemin';
import livereload from 'gulp-livereload';
import yargs from 'yargs';
let argv = yargs.argv;
let production = !!argv.production;
let watch = !!argv.watch;
gulp.task('images', () => {
return gulp.src('app/images/**/*')
.pipe(gulpif(production, imagemin()))
.pipe(gulp.dest('dist/images'))
.pipe(gulpif(watch, livereload()));
});
fonts are located at app/fonts
, it would be copied to dist/fonts
import gulp from 'gulp';
import gulpif from 'gulp-if';
import imagemin from 'gulp-imagemin';
import livereload from 'gulp-livereload';
import yargs from 'yargs';
let argv = yargs.argv;
let watch = !!argv.watch;
gulp.task('fonts', () => {
return gulp.src('app/fonts/**/*.{woff,ttf,eot,svg}')
.pipe(gulp.dest('dist/fonts'))
.pipe(gulpif(watch, livereload()));
});
import gulp from 'gulp';
import zip from 'gulp-zip';
import packageDetails from '../package.json';
gulp.task('package', () => {
let name = packageDetails.name;
let version = packageDetails.version;
let filename = `${name}-${version}.zip`;
gulp.src('dist/*')
.pipe(zip(filename))
.pipe(gulp.dest('./packages'));
});
import gulp from 'gulp';
import gulpif from 'gulp-if';
import livereload from 'gulp-livereload';
import yargs from 'yargs';
let argv = yargs.argv;
let watch = !!argv.watch;
gulp.task('manifest', () => {
gulp.src('app/manifest.json')
.pipe(gulp.dest('dist'))
.pipe(gulpif(watch, livereload()));
});
import gulp from 'gulp';
import gulpif from 'gulp-if';
import livereload from 'gulp-livereload';
import yargs from 'yargs';
let argv = yargs.argv;
let watch = !!argv.watch;
gulp.task('locales', () => {
gulp.src('app/_locales/**/*')
.pipe(gulp.dest('dist/_locales'))
.pipe(gulpif(watch, livereload()));
});
Make sure there is an orphan branch gh-pages
first (gulp-gh-pages does not create an orphan branch for us):
git checkout --orphan gh-pages
git rm -rf .
touch README.md
git add README.md
git commit -m "Init gh-pages"
git push --set-upstream origin gh-pages
git checkout master
var fs = require('fs');
import gulp from 'gulp';
import ghPages from 'gulp-gh-pages';
import config from './config';
gulp.task('cname', () => {
fs.writeFileSync('dist/CNAME', config.deploy.cname);
})
gulp.task('deploy', ['cname'], function() {
return gulp.src('./dist/**/*')
.pipe(ghPages(config.deploy));
});