'use strict' // native modules const p = require('path') const fs = require('fs') // 3rd party modules const _ = require('lodash') const browserify = require('browserify') const buffer = require('vinyl-buffer') const chalk = require('chalk') const es = require('event-stream') const gulp = require('gulp') const gutil = require('gulp-util') const rename = require('gulp-rename') const source = require('vinyl-source-stream') const sourcemaps = require('gulp-sourcemaps') const uglify = require('gulp-uglify') const watchify = require('watchify') const babelify = require('babelify') const markoify = require('markoify') require('marko/compiler').defaultOptions.writeToDisk = false process.env.BABEL_ENV = 'client' const config = require('../config').browserify const suffix = config.suffix && ENV === 'production' ? '-' + Date.now().toString(16) : '' const errorHandler = require('../util/error-handler') function formatError(err) { err.task = 'browserify' const matchFileName = err.message.match(/\/[^\s:]*/) if (matchFileName) { let fileName = matchFileName[0] if (fileName.indexOf(PWD) > -1) fileName = './' + p.relative(PWD, fileName) fileName = chalk.yellow(fileName) const matchNumbers = err.message.match(/ \((.*)\)/) if (matchNumbers) { const arr = matchNumbers[1].split(':') err.message = err.message.slice(0, matchNumbers.index) + ' at line ' + arr[0] + ', col ' + arr[1] } err.message = err.message.split(matchFileName[0]).join(fileName) } err.message = err.message.split(/:\s*/).join('\n') errorHandler.call(this, err) } if (typeof config.entries === 'string') config.entries = [config.entries] const TASK_NAME = 'browserify' gulp.task(TASK_NAME, (cb) => { cb = _.after(config.entries.length, cb) if (config.suffix) fs.writeFileSync(config.dest + '.json', JSON.stringify({ suffix })) const tasks = config.entries.map((entry, index) => { function bundler(bundle) { let outputPath = config.outputs && config.outputs[index] || entry let pipe = bundle.bundle() .on('error', formatError) .pipe(source(outputPath)) .pipe(rename((path) => { if (outputPath === entry) { // remove first level of directores, eg `src/` or `src-widget/` path.dirname = path.dirname.replace(/^src[^\/]*\/?/, '') outputPath = path.dirname + path.basename + (path.suffix || '') + path.extname } path.basename += suffix return path })) .on('end', (...args) => { gutil.log(chalk.cyan(TASK_NAME) + ' wrote ' + chalk.magenta(outputPath) + '.') cb() }) if (ENV !== 'development') pipe = pipe.pipe(buffer()) .pipe(sourcemaps.init({ loadMaps: true })) .pipe(uglify()) .pipe(sourcemaps.write('./')) return pipe.pipe(gulp.dest(config.dest)) } const bundle = browserify(_.defaults({ entries: [ entry ], cache: {}, packageCache: {} }, config)) if (ENV !== 'production') bundle.plugin(watchify, { ignoreWatch: [ '/public/**', '**/node_modules/**', '**/bower_components/**'] }) bundle.transform(babelify) bundle.transform(markoify) bundle.on('update', () => bundler(bundle)) return bundler(bundle) }) // return a single stream from all bundle streams return es.merge.apply(null, tasks) })