229 lines
6.5 KiB
JavaScript
229 lines
6.5 KiB
JavaScript
var path = require('path');
|
|
|
|
var packagejs = require('./package.json');
|
|
var conf = require('./conf.js');
|
|
|
|
// Sorted alphabetically!
|
|
var babelify = require('babelify');
|
|
var envify = require('envify/custom');
|
|
var browserify = require('browserify');
|
|
var gulp = require("gulp");
|
|
var eslint = require('gulp-eslint');
|
|
var less = require("gulp-less");
|
|
var livereload = require("gulp-livereload");
|
|
var cleanCSS = require('gulp-clean-css');
|
|
var notify = require("gulp-notify");
|
|
var peg = require("gulp-peg");
|
|
var plumber = require("gulp-plumber");
|
|
var rename = require("gulp-rename");
|
|
var sourcemaps = require('gulp-sourcemaps');
|
|
var gutil = require("gulp-util");
|
|
var _ = require('lodash');
|
|
var uglifyify = require('uglifyify');
|
|
var buffer = require('vinyl-buffer');
|
|
var source = require('vinyl-source-stream');
|
|
var watchify = require('watchify');
|
|
|
|
var vendor_packages = _.difference(
|
|
_.union(
|
|
_.keys(packagejs.dependencies),
|
|
conf.js.vendor_includes
|
|
),
|
|
conf.js.vendor_excludes
|
|
);
|
|
|
|
var handleError = {errorHandler: notify.onError("Error: <%= error.message %>")};
|
|
|
|
/*
|
|
* Sourcemaps are a wonderful way to develop directly from the chrome devtools.
|
|
* However, generating correct sourcemaps is a huge PITA, especially on Windows.
|
|
* Fixing this upstream is tedious as apparently nobody really cares and
|
|
* a single misbehaving transform breaks everything.
|
|
* Thus, we just manually fix all paths.
|
|
*/
|
|
function fixSourceMaps(file) {
|
|
file.sourceMap.sources = file.sourceMap.sources.map(function (x) {
|
|
return path.relative(".", x).split(path.sep).join('/');
|
|
});
|
|
return "/";
|
|
}
|
|
// Browserify fails for paths starting with "..".
|
|
function fixBrowserifySourceMaps(file) {
|
|
file.sourceMap.sources = file.sourceMap.sources.map((x) => {
|
|
return x.replace("src/js/node_modules", "node_modules");
|
|
});
|
|
return fixSourceMaps(file);
|
|
}
|
|
function fixLessSourceMaps(file) {
|
|
file.sourceMap.sources = file.sourceMap.sources.map((x) => {
|
|
if(!x.startsWith("..")){
|
|
return "../src/css/" + x;
|
|
}
|
|
return x.replace("src/js/node_modules", "node_modules");
|
|
});
|
|
return fixSourceMaps(file);
|
|
}
|
|
|
|
function styles(files, dev){
|
|
return gulp.src(files)
|
|
.pipe(dev ? plumber(handleError) : gutil.noop())
|
|
.pipe(sourcemaps.init())
|
|
.pipe(less())
|
|
.pipe(dev ? gutil.noop() : cleanCSS())
|
|
.pipe(sourcemaps.write(".", {sourceRoot: fixLessSourceMaps}))
|
|
.pipe(gulp.dest(conf.static))
|
|
.pipe(livereload({auto: false}));
|
|
}
|
|
gulp.task("styles-app-dev", function () {
|
|
return styles(conf.css.app, true);
|
|
});
|
|
gulp.task("styles-vendor-dev", function () {
|
|
return styles(conf.css.vendor, true);
|
|
});
|
|
gulp.task("styles-app-prod", function () {
|
|
return styles(conf.css.app, false);
|
|
});
|
|
gulp.task("styles-vendor-prod", function () {
|
|
return styles(conf.css.vendor, false);
|
|
});
|
|
|
|
|
|
function buildScript(bundler, filename, dev) {
|
|
if (dev) {
|
|
bundler = watchify(bundler);
|
|
} else {
|
|
bundler = bundler.transform(envify({ _: 'purge', NODE_ENV: 'production' }), { global: true });
|
|
bundler = bundler.transform({global: true}, uglifyify);
|
|
}
|
|
|
|
function rebundle() {
|
|
return bundler.bundle()
|
|
.on('error', function(error) {
|
|
gutil.log(error + '\n' + error.codeFrame);
|
|
this.emit('end');
|
|
})
|
|
.pipe(dev ? plumber(handleError) : gutil.noop())
|
|
.pipe(source('bundle.js'))
|
|
.pipe(buffer())
|
|
.pipe(sourcemaps.init({loadMaps: true}))
|
|
.pipe(rename(filename))
|
|
.pipe(sourcemaps.write('.', {sourceRoot: fixBrowserifySourceMaps}))
|
|
.pipe(gulp.dest(conf.static))
|
|
.pipe(livereload({auto: false}));
|
|
}
|
|
|
|
// listen for an update and run rebundle
|
|
bundler.on('update', rebundle);
|
|
bundler.on('log', gutil.log);
|
|
bundler.on('error', gutil.log);
|
|
|
|
// run it once the first time buildScript is called
|
|
return rebundle();
|
|
}
|
|
|
|
function vendor_stream(dev) {
|
|
var bundler = browserify({
|
|
entries: [],
|
|
debug: true,
|
|
cache: {}, // required for watchify
|
|
packageCache: {} // required for watchify
|
|
});
|
|
for (var vp of vendor_packages) {
|
|
bundler.require(vp);
|
|
}
|
|
return buildScript(bundler, "vendor.js", dev);
|
|
}
|
|
gulp.task("scripts-vendor-dev", function () {
|
|
return vendor_stream(true);
|
|
});
|
|
gulp.task("scripts-vendor-prod", function () {
|
|
return vendor_stream(false);
|
|
});
|
|
|
|
function app_stream(dev) {
|
|
var bundler = browserify({
|
|
entries: [conf.js.app],
|
|
debug: true,
|
|
extensions: ['.jsx'],
|
|
cache: {}, // required for watchify
|
|
packageCache: {} // required for watchify
|
|
});
|
|
for (var vp of vendor_packages) {
|
|
bundler.external(vp);
|
|
}
|
|
bundler = bundler.transform(babelify);
|
|
return buildScript(bundler, "app.js", dev);
|
|
}
|
|
gulp.task('scripts-app-dev', function () {
|
|
return app_stream(true);
|
|
});
|
|
gulp.task('scripts-app-prod', function () {
|
|
return app_stream(false);
|
|
});
|
|
|
|
|
|
gulp.task("eslint", function () {
|
|
return gulp.src(conf.js.eslint)
|
|
.pipe(plumber(handleError))
|
|
.pipe(eslint())
|
|
.pipe(eslint.format())
|
|
});
|
|
|
|
gulp.task("copy", function () {
|
|
return gulp.src(conf.copy, {base: conf.src})
|
|
.pipe(gulp.dest(conf.static));
|
|
});
|
|
|
|
|
|
gulp.task('templates', function(){
|
|
return gulp.src(conf.templates, {base: conf.src})
|
|
.pipe(gulp.dest(conf.dist));
|
|
});
|
|
|
|
gulp.task("peg", function () {
|
|
return gulp.src(conf.peg, {base: conf.src})
|
|
.pipe(plumber(handleError))
|
|
.pipe(peg())
|
|
.pipe(gulp.dest("src/"));
|
|
});
|
|
|
|
gulp.task(
|
|
"dev",
|
|
gulp.series(
|
|
"copy",
|
|
"styles-vendor-dev",
|
|
"styles-app-dev",
|
|
"scripts-vendor-dev",
|
|
"peg",
|
|
"scripts-app-dev",
|
|
"templates"
|
|
)
|
|
);
|
|
gulp.task(
|
|
"prod",
|
|
gulp.series(
|
|
"copy",
|
|
"styles-vendor-prod",
|
|
"styles-app-prod",
|
|
"scripts-vendor-prod",
|
|
"peg",
|
|
"scripts-app-prod",
|
|
"templates"
|
|
)
|
|
);
|
|
|
|
gulp.task("default", gulp.series(
|
|
"dev",
|
|
function () {
|
|
livereload.listen({auto: true});
|
|
gulp.watch(["src/css/vendor*"], gulp.series("styles-vendor-dev"));
|
|
gulp.watch(["src/css/**"], gulp.series("styles-app-dev"));
|
|
|
|
gulp.watch(conf.templates, gulp.series("templates"));
|
|
gulp.watch(conf.peg, gulp.series("peg"));
|
|
gulp.watch(["src/js/**"], gulp.series("eslint"));
|
|
// other JS is handled by watchify.
|
|
gulp.watch(conf.copy, gulp.series("copy"));
|
|
})
|
|
);
|