parallel-webpack
Advanced tools
Comparing version 1.3.1 to 1.4.0
@@ -9,2 +9,3 @@ #! /usr/bin/env node | ||
chalk = require('chalk'), | ||
findConfigFile = require('../src/findConfigFile'), | ||
argv = require('minimist')(process.argv.slice(2), { | ||
@@ -15,3 +16,4 @@ '--': true, | ||
'max-retries': Infinity, | ||
config: 'webpack.config.js', | ||
// leave off file extension so that we can find the most appropriate one | ||
config: 'webpack.config', | ||
'parallel': require('os').cpus().length, | ||
@@ -36,3 +38,4 @@ json: false, | ||
chalk.enabled = argv.colors; | ||
configPath = path.resolve(argv.config); | ||
configPath = findConfigFile(path.resolve(argv.config)); | ||
run(configPath, { | ||
@@ -58,10 +61,3 @@ watch: argv.watch, | ||
}).catch(function(err) { | ||
if(err.message) { | ||
process.stdout.write(err.message + "\n"); | ||
if(err.error) { | ||
console.error(err.error); | ||
} | ||
} else { | ||
console.error(err); | ||
} | ||
console.log(err.message); | ||
process.exit(1); | ||
@@ -68,0 +64,0 @@ }); |
162
index.js
var workerFarm = require('worker-farm'), | ||
Promise = require('bluebird'), | ||
chalk = require('chalk'), | ||
_ = require('lodash'); | ||
pluralize = require('pluralize'), | ||
loadConfigurationFile = require('./src/loadConfigurationFile'); | ||
function isSilent(options) { | ||
return options && !options.json; | ||
function notSilent(options) { | ||
return !options.json; | ||
} | ||
function startSingleConfigWorker(configPath, options, runWorker) { | ||
if(isSilent(options)) { | ||
process.stdout.write(chalk.blue('[WEBPACK]') + ' Building ' + chalk.yellow('1') + ' configuration' + "\n"); | ||
} | ||
var worker = require('./src/webpackWorker'); | ||
return new Promise(function(resolve, reject) { | ||
worker(configPath, options, 0, 1, function(err, stats) { | ||
if(err) { | ||
return reject(err); | ||
} | ||
resolve([stats]); | ||
}); | ||
}); | ||
} | ||
function startFarm(config, configPath, options, runWorker) { | ||
config = Array.isArray(config) ? config : [config]; | ||
options = options || {}; | ||
function startMultiConfigFarm(config, configPath, options, runWorker) { | ||
if(isSilent(options)) { | ||
process.stdout.write(chalk.blue('[WEBPACK]') + ' Building ' + chalk.yellow(config.length) + ' targets in parallel' + "\n"); | ||
if(notSilent(options)) { | ||
console.log(chalk.blue('[WEBPACK]') + ' Building ' + chalk.yellow(config.length) + ' ' + pluralize('target', config.length)); | ||
} | ||
@@ -35,11 +24,8 @@ var builds = config.map(function (c, i) { | ||
} else { | ||
return Promise.all(builds.map(function(build) { | ||
return build.reflect(); | ||
})).then(function(results) { | ||
return Promise.all(results.map(function(buildInspection) { | ||
if(buildInspection.isFulfilled) { | ||
return buildInspection.value(); | ||
} else { | ||
return Promise.reject(buildInspection.reason()); | ||
return Promise.settle(builds).then(function(results) { | ||
return Promise.all(results.map(function (result) { | ||
if(result.isFulfilled()) { | ||
return result.value(); | ||
} | ||
return Promise.reject(result.reason()); | ||
})); | ||
@@ -50,48 +36,2 @@ }); | ||
function startFarm(config, configPath, options, runWorker) { | ||
// special handling for cases where only one config is exported as array | ||
// unpack and treat as single config | ||
if(_.isArray(config) && config.length === 1) { | ||
config = config[0]; | ||
} | ||
if(!_.isArray(config)) { | ||
return startSingleConfigWorker(configPath, options, runWorker); | ||
} else { | ||
return startMultiConfigFarm(config, configPath, options, runWorker); | ||
} | ||
} | ||
function closeFarm(workers, options, done, startTime) { | ||
return function(err, stats) { | ||
workerFarm.end(workers); | ||
if(isSilent(options)) { | ||
if(err) { | ||
console.log('%s Build failed after %s seconds', chalk.red('[WEBPACK]'), chalk.blue((new Date().getTime() - startTime) / 1000)); | ||
} else { | ||
console.log('%s Finished build after %s seconds', chalk.blue('[WEBPACK]'), chalk.blue((new Date().getTime() - startTime) / 1000)); | ||
} | ||
} | ||
if (done) { | ||
done(err, stats); | ||
} | ||
if(err) { | ||
throw err; | ||
} | ||
return stats; | ||
} | ||
} | ||
function promisify(workers) { | ||
return function(configPath, options, i, configLength) { | ||
return new Promise(function(resolve, reject) { | ||
workers(configPath, options, i, configLength, function(err, res) { | ||
if(err) { | ||
return reject(err); | ||
} | ||
resolve(res); | ||
}); | ||
}); | ||
} | ||
} | ||
/** | ||
@@ -101,7 +41,12 @@ * Runs the specified webpack configuration in parallel. | ||
* @param {Object} options | ||
* @param {Boolean} [options.watch=false] If `true`, Webpack will run in `watch-mode`. | ||
* @param {boolean} [options.maxRetries=Infinity] The maximum amount of retries on build error | ||
* @param {Number} [options.maxConcurrentWorkers=require('os').cpus().length] The maximum number of parallel workers | ||
* @param {Function} [callback] A callback to be invoked once the build has been completed | ||
* @return {Promise} A Promise that is resolved once all builds have been created | ||
* @param {Boolean} [options.watch=false] If `true`, Webpack will run in | ||
* `watch-mode`. | ||
* @param {boolean} [options.maxRetries=Infinity] The maximum amount of retries | ||
* on build error | ||
* @param {Number} [options.maxConcurrentWorkers=require('os').cpus().length] The | ||
* maximum number of parallel workers | ||
* @param {Function} [callback] A callback to be invoked once the build has | ||
* been completed | ||
* @return {Promise} A Promise that is resolved once all builds have been | ||
* created | ||
*/ | ||
@@ -111,20 +56,24 @@ function run(configPath, options, callback) { | ||
argvBackup = process.argv; | ||
options = options || {}; | ||
if(options.colors === undefined) { | ||
options.colors = chalk.supportsColor; | ||
} | ||
if(!options.argv) { | ||
options.argv = []; | ||
} | ||
options.argv = ['node', 'parallel-webpack'].concat(options.argv); | ||
options.argv.unshift(process.execPath, 'parallel-webpack'); | ||
try { | ||
process.argv = options.argv; | ||
config = require(configPath); | ||
config = loadConfigurationFile(configPath); | ||
process.argv = argvBackup; | ||
} catch(e) { | ||
throw { | ||
message: chalk.red('[WEBPACK]') + ' Could not load configuration file ' + chalk.underline(configPath), | ||
error: e | ||
}; | ||
process.argv = argvBackup; | ||
return Promise.reject(new Error( | ||
chalk.red('[WEBPACK]') + ' Could not load configuration file ' + chalk.underline(configPath) + "\n" | ||
+ e | ||
)); | ||
} | ||
var maxRetries = options && parseInt(options.maxRetries, 10) || Infinity, | ||
maxConcurrentWorkers = options | ||
&& parseInt(options.maxConcurrentWorkers, 10) | ||
var maxRetries = parseInt(options.maxRetries, 10) || 0, | ||
maxConcurrentWorkers = parseInt(options.maxConcurrentWorkers, 10) | ||
|| require('os').cpus().length, | ||
@@ -134,20 +83,35 @@ workers = workerFarm({ | ||
maxConcurrentWorkers: maxConcurrentWorkers | ||
}, require.resolve('./src/webpackWorker')), | ||
done = closeFarm(workers, options, callback, +new Date()); | ||
}, require.resolve('./src/webpackWorker')); | ||
process.on('SIGINT', function() { | ||
console.log(chalk.red('[WEBPACK]') + ' Forcefully shutting down'); | ||
done(); | ||
if (notSilent(options)) { | ||
console.log(chalk.red('[WEBPACK]') + ' Forcefully shutting down'); | ||
} | ||
workerFarm.end(workers); | ||
}); | ||
var startTime = Date.now(); | ||
return startFarm( | ||
config, | ||
configPath, | ||
options || {}, | ||
promisify(workers) | ||
).then(function(err, res) { | ||
return done(null, res); | ||
}, function(err) { | ||
throw done(err); | ||
}); | ||
options, | ||
Promise.promisify(workers) | ||
).error(function(err) { | ||
if(notSilent(options)) { | ||
console.log('%s Build failed after %s seconds', chalk.red('[WEBPACK]'), chalk.blue((Date.now() - startTime) / 1000)); | ||
} | ||
return Promise.reject(err); | ||
}).then(function (results) { | ||
if(notSilent(options)) { | ||
console.log('%s Finished build after %s seconds', chalk.blue('[WEBPACK]'), chalk.blue((Date.now() - startTime) / 1000)); | ||
} | ||
results = results.filter(function(result) { | ||
return result; | ||
}); | ||
if(results.length) { | ||
return results; | ||
} | ||
}).finally(function () { | ||
workerFarm.end(workers); | ||
}).asCallback(callback); | ||
} | ||
@@ -154,0 +118,0 @@ |
{ | ||
"name": "parallel-webpack", | ||
"version": "1.3.1", | ||
"version": "1.4.0", | ||
"description": "Builds multiple webpack configurations in parallel and allows you to easily create variants to those configurations.", | ||
@@ -28,4 +28,8 @@ "main": "index.js", | ||
"chalk": "^1.1.1", | ||
"lodash": "^3.10.1", | ||
"interpret": "^1.0.1", | ||
"lodash.assign": "^4.0.8", | ||
"lodash.endswith": "^4.0.1", | ||
"lodash.flatten": "^4.2.0", | ||
"minimist": "^1.2.0", | ||
"pluralize": "^1.2.1", | ||
"supports-color": "^3.1.2", | ||
@@ -32,0 +36,0 @@ "webpack": "^1.12.9", |
@@ -219,2 +219,3 @@ # parallel-webpack - Building multi-configs in parallel | ||
maxRetries: 1, | ||
stats: true, // defaults to false | ||
maxConcurrentWorkers: 2 // use 2 workers | ||
@@ -221,0 +222,0 @@ }); |
/** | ||
* Created by pgotthardt on 07/12/15. | ||
*/ | ||
var _ = require('lodash'); | ||
var assign = require('lodash.assign'); | ||
var flatten = require('lodash.flatten'); | ||
@@ -18,3 +19,3 @@ /** | ||
if(arguments.length === 2) { | ||
if(_.isFunction(variants)) { | ||
if(typeof variants === 'function') { | ||
// createVariants(variants: Object, configCallback: Function) | ||
@@ -37,6 +38,6 @@ configCallback = variants; | ||
// possible combination of the configuration variants specified above. | ||
var transforms = _.map(_.keys(variants), function(key) { | ||
var transforms = Object.keys(variants).map(function(key) { | ||
return function(config) { | ||
return variants[key].map(function(value) { | ||
var result = _.assign({}, config); | ||
var result = assign({}, config); | ||
result[key] = value; | ||
@@ -47,8 +48,8 @@ return result; | ||
}), | ||
configs = _.reduce(transforms, function(options, transform) { | ||
return _.flatten(_.map(options, transform)); | ||
configs = transforms.reduce(function(options, transform) { | ||
return flatten(options.map(transform)); | ||
}, [baseConfig]); | ||
return configCallback && _.map(configs, configCallback) || configs; | ||
return configCallback && configs.map(configCallback) || configs; | ||
}; |
@@ -6,3 +6,4 @@ /** | ||
var Promise = require('bluebird'), | ||
chalk = require('chalk'); | ||
chalk = require('chalk'), | ||
loadConfigurationFile = require('./loadConfigurationFile'); | ||
@@ -54,3 +55,4 @@ /** | ||
* @param {boolean} options.json If `true`, then the webpack watcher will only report the result as JSON but not produce any other output | ||
* @param {Number} index The configuration index | ||
* @param {number} index The configuration index | ||
* @param {number} expectedConfigLength | ||
* @param {Function} done The callback that should be invoked once this worker has finished the build. | ||
@@ -63,3 +65,3 @@ */ | ||
chalk.enabled = options.colors; | ||
var config = require(configuratorFileName), | ||
var config = loadConfigurationFile(configuratorFileName), | ||
watch = !!options.watch, | ||
@@ -70,3 +72,3 @@ silent = !!options.json; | ||
if(config.length !== expectedConfigLength) { | ||
var errorMessage = '[WEBPACK] There is a difference between the amount of the' | ||
var errorMessage = '[WEBPACK] There is a difference between the amount of the' | ||
+ ' provided configs. Maybe you where expecting command line' | ||
@@ -109,3 +111,6 @@ + ' arguments to be passed to your webpack.config.js. If so,' | ||
} | ||
console.log('%s Finished building %s within %s seconds', chalk.blue('[WEBPACK]'), chalk.yellow(getAppName(webpackConfig)), chalk.blue((stats.endTime - stats.startTime) / 1000)); | ||
var timeStamp = watch | ||
? ' ' + chalk.yellow(new Date().toTimeString().split(/ +/)[0]) | ||
: ''; | ||
console.log('%s Finished building %s within %s seconds', chalk.blue('[WEBPACK' + timeStamp + ']'), chalk.yellow(getAppName(webpackConfig)), chalk.blue((stats.endTime - stats.startTime) / 1000)); | ||
} | ||
@@ -112,0 +117,0 @@ if(!watch) { |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
70435
20
424
243
11
5
+ Addedinterpret@^1.0.1
+ Addedlodash.assign@^4.0.8
+ Addedlodash.endswith@^4.0.1
+ Addedlodash.flatten@^4.2.0
+ Addedpluralize@^1.2.1
+ Addedinterpret@1.4.0(transitive)
+ Addedlodash.assign@4.2.0(transitive)
+ Addedlodash.endswith@4.2.1(transitive)
+ Addedlodash.flatten@4.4.0(transitive)
+ Addedpluralize@1.2.1(transitive)
- Removedlodash@^3.10.1
- Removedlodash@3.10.1(transitive)