UNPKG

pp-parachute

Version:
153 lines (133 loc) 4.66 kB
var browserify = require('browserify'); var Promise = require('bluebird'); var Bundler = require('./bundler'); var inherits = require('util').inherits; var path = require('path'); var through = require('through2'); var xtend = require('xtend'); var tsify = require('tsify'); var ScriptBundler = function (assetGlobs) { Bundler.call(this, assetGlobs); this.transforms = []; this.scriptBuilder = null; this.requires = []; this.externals = []; this.standaloneFile = ''; this.fileCache = {}; this.tscOptions = { noImplicitAny: true, target: "es5" }; this.debug = true; }; inherits(ScriptBundler, Bundler); ScriptBundler.prototype.browserifyArgs = function () { return { debug: this.debug, detectGlobals: false, cache: this.fileCache, packageCache: {}, fullPaths: true, standalone: (typeof this.standaloneFile === 'string' && this.standaloneFile || '') }; }; ScriptBundler.prototype.require = function (req) { this.requires.push(req); return this; }; ScriptBundler.prototype.external = function (ext) { this.externals.push(ext); return this; }; ScriptBundler.prototype.createSourceMaps = function (debug) { this.debug = debug; return this; }; ScriptBundler.prototype.transform = function (transform) { this.transforms.push(transform); return this; }; ScriptBundler.prototype.standalone = function (filename) { this.standaloneFile = filename; return this; }; ScriptBundler.prototype.typeScriptOptions = function(options) { this.tscOptions = options; return this; }; ScriptBundler.prototype.ensureBrowserify = function (filePaths) { if (!this.scriptBuilder || this.dirtyFileList) { this.dirtyFileList = false; // reset cache when files are added / removed, build times will be longer // because of this but I think thats tolerable. this.fileCache = {}; this.scriptBuilder = browserify(filePaths, this.browserifyArgs()); try { this.scriptBuilder.plugin(tsify, this.tscOptions); } catch(e) { console.log('Failed to load tsify plugin'); console.log(e.stack); } var self = this; //this is basically 80% of what watchify does, but I dont want to have execss watchers //since we already have them for all the files watchify cares about. this.scriptBuilder.on('reset', function () { var stream = through.obj(function (row, enc, next) { var file = row.expose ? self.scriptBuilder._expose[row.id] : row.file; self.fileCache[file] = { source: row.source, deps: xtend({}, row.deps) }; this.push(row); next(); }); self.scriptBuilder.pipeline.get('deps').push(stream); }); this.scriptBuilder.on('transform', function (transform) { transform.on('file', function (file) { if (file.indexOf('node_modules') === -1 && self.assetWatcher) { self.assetWatcher.ensureFileIsWatched(file); } }); }); this.scriptBuilder.on('file', function (file) { if (file.indexOf('node_modules') === -1 && self.assetWatcher) { self.assetWatcher.ensureFileIsWatched(file); } }); this.scriptBuilder.on('package', function (pkg) { if (pkg.__dirname.indexOf('node_modules') === -1) { self.assetWatcher && self.assetWatcher.ensureFileIsWatched(path.join(pkg.__dirname, 'package.json')); } }); } }; ScriptBundler.prototype.bundle = function (filePaths) { this.ensureBrowserify(filePaths); var self = this; var fn = function (resolve, reject) { self.requires.forEach(function (req) { self.scriptBuilder.require(req); }); self.externals.forEach(function (ext) { self.scriptBuilder.external(ext); }); self.transforms.forEach(function (transform) { self.scriptBuilder.transform(transform); }); self.scriptBuilder.bundle(function bundleCallback(error, result) { if (error) { reject(error.message); } else { resolve(result.toString()); } }); }; return new Promise(fn); }; ScriptBundler.prototype.onFileChanged = function (file) { if (this.fileCache[file]) { delete this.fileCache[file]; } }; module.exports = ScriptBundler;