multiparty-meeting/app/gulpfile.js

383 lines
8.9 KiB
JavaScript

'use strict';
/**
* Tasks:
*
* gulp prod
* Generates the browser app in production mode.
*
* gulp dev
* Generates the browser app in development mode.
*
* gulp live
* Generates the browser app in development mode, opens it and watches
* for changes in the source code.
*
* gulp
* Alias for `gulp live`.
*/
const fs = require('fs');
const path = require('path');
const gulp = require('gulp');
const gulpif = require('gulp-if');
const gutil = require('gulp-util');
const plumber = require('gulp-plumber');
const touch = require('gulp-touch');
const rename = require('gulp-rename');
const header = require('gulp-header');
const browserify = require('browserify');
const watchify = require('watchify');
const envify = require('envify/custom');
const uglify = require('gulp-uglify');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const del = require('del');
const mkdirp = require('mkdirp');
const ncp = require('ncp');
const eslint = require('gulp-eslint');
const stylus = require('gulp-stylus');
const cssBase64 = require('gulp-css-base64');
const nib = require('nib');
const browserSync = require('browser-sync');
const PKG = require('./package.json');
const BANNER = fs.readFileSync('banner.txt').toString();
const BANNER_OPTIONS =
{
pkg : PKG,
currentYear : (new Date()).getFullYear()
};
const OUTPUT_DIR = '../server/public';
// Default environment.
process.env.NODE_ENV = 'development';
function logError(error)
{
gutil.log(gutil.colors.red(String(error)));
throw error;
}
function bundle(options)
{
options = options || {};
let watch = !!options.watch;
let bundler = browserify(
{
entries : path.join(__dirname, PKG.main),
extensions : [ '.js', '.jsx' ],
// required for sourcemaps (must be false otherwise).
debug : process.env.NODE_ENV === 'development',
// required for watchify.
cache : {},
// required for watchify.
packageCache : {},
// required to be true only for watchify.
fullPaths : watch
})
.transform('babelify',
{
presets : [ 'es2015', 'react' ],
plugins : [ 'transform-runtime', 'transform-object-assign' ]
})
.transform(envify(
{
NODE_ENV : process.env.NODE_ENV,
_ : 'purge'
}));
if (watch)
{
bundler = watchify(bundler);
bundler.on('update', () =>
{
let start = Date.now();
gutil.log('bundling...');
rebundle();
gutil.log('bundle took %sms', (Date.now() - start));
});
}
function rebundle()
{
return bundler.bundle()
.on('error', logError)
.pipe(source(`${PKG.name}.js`))
.pipe(buffer())
.pipe(rename(`${PKG.name}.js`))
.pipe(gulpif(process.env.NODE_ENV === 'production',
uglify()
))
.pipe(header(BANNER, BANNER_OPTIONS))
.pipe(gulp.dest(OUTPUT_DIR));
}
return rebundle();
}
gulp.task('clean', () => del(OUTPUT_DIR, { force: true }));
gulp.task('env:dev', (done) =>
{
gutil.log('setting "dev" environment');
process.env.NODE_ENV = 'development';
done();
});
gulp.task('env:prod', (done) =>
{
gutil.log('setting "prod" environment');
process.env.NODE_ENV = 'production';
done();
});
gulp.task('lint', () =>
{
let src = [ 'gulpfile.js', 'lib/**/*.js', 'lib/**/*.jsx' ];
return gulp.src(src)
.pipe(plumber())
.pipe(eslint(
{
plugins : [ 'react', 'import' ],
extends : [ 'eslint:recommended', 'plugin:react/recommended' ],
settings :
{
react :
{
pragma : 'React', // Pragma to use, default to 'React'.
version : '15' // React version, default to the latest React stable release.
}
},
parserOptions :
{
ecmaVersion : 6,
sourceType : 'module',
ecmaFeatures :
{
impliedStrict : true,
jsx : true
}
},
envs :
[
'browser',
'es6',
'node',
'commonjs'
],
'rules' :
{
'no-console' : 0,
'no-undef' : 2,
'no-unused-vars' : [ 2, { vars: 'all', args: 'after-used' }],
'no-empty' : 0,
'quotes' : [ 2, 'single', { avoidEscape: true } ],
'semi' : [ 2, 'always' ],
'no-multi-spaces' : 0,
'no-whitespace-before-property' : 2,
'space-before-blocks' : 2,
'space-before-function-paren' : [ 2, 'never' ],
'space-in-parens' : [ 2, 'never' ],
'spaced-comment' : [ 2, 'always' ],
'comma-spacing' : [ 2, { before: false, after: true } ],
'jsx-quotes' : [ 2, 'prefer-single' ],
'react/display-name' : [ 2, { ignoreTranspilerName: false } ],
'react/forbid-prop-types' : 0,
'react/jsx-boolean-value' : 1,
'react/jsx-closing-bracket-location' : 1,
'react/jsx-curly-spacing' : 1,
'react/jsx-equals-spacing' : 1,
'react/jsx-handler-names' : 1,
'react/jsx-indent-props' : [ 2, 'tab' ],
'react/jsx-indent' : [ 2, 'tab' ],
'react/jsx-key' : 1,
'react/jsx-max-props-per-line' : 0,
'react/jsx-no-bind' : 0,
'react/jsx-no-duplicate-props' : 1,
'react/jsx-no-literals' : 0,
'react/jsx-no-undef' : 1,
'react/jsx-pascal-case' : 1,
'react/jsx-sort-prop-types' : 0,
'react/jsx-sort-props' : 0,
'react/jsx-uses-react' : 1,
'react/jsx-uses-vars' : 1,
'react/no-danger' : 1,
'react/no-deprecated' : 1,
'react/no-did-mount-set-state' : 1,
'react/no-did-update-set-state' : 1,
'react/no-direct-mutation-state' : 1,
'react/no-is-mounted' : 1,
'react/no-multi-comp' : 0,
'react/no-set-state' : 0,
'react/no-string-refs' : 0,
'react/no-unknown-property' : 1,
'react/prefer-es6-class' : 1,
'react/prop-types' : 1,
'react/react-in-jsx-scope' : 1,
'react/self-closing-comp' : 1,
'react/sort-comp' : 0,
'react/jsx-wrap-multilines' : [ 1, { declaration: false, assignment: false, return: true } ],
'import/extensions' : 1
}
}))
.pipe(eslint.format());
});
gulp.task('css', () =>
{
return gulp.src('stylus/index.styl')
.pipe(plumber())
.pipe(stylus(
{
use : nib(),
compress : process.env.NODE_ENV === 'production'
}))
.on('error', logError)
.pipe(cssBase64(
{
baseDir : '.',
maxWeightResource : 50000 // So big ttf fonts are not included, nice.
}))
.pipe(rename(`${PKG.name}.css`))
.pipe(gulp.dest(OUTPUT_DIR))
.pipe(touch());
});
gulp.task('html', () =>
{
return gulp.src('index.html')
.pipe(gulp.dest(OUTPUT_DIR));
});
gulp.task('resources', (done) =>
{
let dst = path.join(OUTPUT_DIR, 'resources');
mkdirp.sync(dst);
ncp('resources', dst, { stopOnErr: true }, (error) =>
{
if (error && error[0].code !== 'ENOENT')
throw new Error(`resources copy failed: ${error}`);
done();
});
});
gulp.task('bundle', () =>
{
return bundle({ watch: false });
});
gulp.task('bundle:watch', () =>
{
return bundle({ watch: true });
});
gulp.task('livebrowser', (done) =>
{
const config = require('../server/config');
browserSync(
{
open : 'external',
host : config.domain,
server :
{
baseDir : OUTPUT_DIR
},
https : config.tls,
ghostMode : false,
files : path.join(OUTPUT_DIR, '**', '*')
});
done();
});
gulp.task('browser', (done) =>
{
const config = require('../server/config');
browserSync(
{
open : 'external',
host : config.domain,
server :
{
baseDir : OUTPUT_DIR
},
https : config.tls,
ghostMode : false
});
done();
});
gulp.task('watch', (done) =>
{
// Watch changes in HTML.
gulp.watch([ 'index.html' ], gulp.series(
'html'
));
// Watch changes in Stylus files.
gulp.watch([ 'stylus/**/*.styl' ], gulp.series(
'css'
));
// Watch changes in resources.
gulp.watch([ 'resources/**/*' ], gulp.series(
'resources', 'css'
));
// Watch changes in JS files.
gulp.watch([ 'gulpfile.js', 'lib/**/*.js', 'lib/**/*.jsx' ], gulp.series(
'lint'
));
done();
});
gulp.task('prod', gulp.series(
'env:prod',
'clean',
'lint',
'bundle',
'html',
'css',
'resources'
));
gulp.task('dev', gulp.series(
'env:dev',
'clean',
'lint',
'bundle',
'html',
'css',
'resources'
));
gulp.task('live', gulp.series(
'env:dev',
'clean',
'lint',
'bundle:watch',
'html',
'css',
'resources',
'watch',
'livebrowser'
));
gulp.task('open', gulp.series('browser'));
gulp.task('default', gulp.series('live'));