UNPKG

5.16 kBJavaScriptView Raw
1var workerFarm = require('worker-farm'),
2 Promise = require('bluebird'),
3 chalk = require('chalk'),
4 _ = require('lodash');
5
6function isSilent(options) {
7 return options && !options.json;
8}
9
10function startSingleConfigWorker(configPath, options, runWorker) {
11 if(isSilent(options)) {
12 process.stdout.write(chalk.blue('[WEBPACK]') + ' Building ' + chalk.yellow('1') + ' configuration' + "\n");
13 }
14 var worker = require('./src/webpackWorker');
15 return new Promise(function(resolve, reject) {
16 worker(configPath, options, 0, 1, function(err, stats) {
17 if(err) {
18 return reject(err);
19 }
20 resolve([stats]);
21 });
22 });
23}
24
25function startMultiConfigFarm(config, configPath, options, runWorker) {
26 if(isSilent(options)) {
27 process.stdout.write(chalk.blue('[WEBPACK]') + ' Building ' + chalk.yellow(config.length) + ' targets in parallel' + "\n");
28 }
29 var builds = config.map(function (c, i) {
30 return runWorker(configPath, options, i, config.length);
31 });
32 if(options.bail) {
33 return Promise.all(builds);
34 } else {
35 return Promise.all(builds.map(function(build) {
36 return build.reflect();
37 })).then(function(results) {
38 return Promise.all(results.map(function(buildInspection) {
39 if(buildInspection.isFulfilled) {
40 return buildInspection.value();
41 } else {
42 return Promise.reject(buildInspection.reason());
43 }
44 }));
45 });
46 }
47}
48
49function startFarm(config, configPath, options, runWorker) {
50 // special handling for cases where only one config is exported as array
51 // unpack and treat as single config
52 if(_.isArray(config) && config.length === 1) {
53 config = config[0];
54 }
55 if(!_.isArray(config)) {
56 return startSingleConfigWorker(configPath, options, runWorker);
57 } else {
58 return startMultiConfigFarm(config, configPath, options, runWorker);
59 }
60}
61
62function closeFarm(workers, options, done, startTime) {
63 return function(err, stats) {
64 workerFarm.end(workers);
65 if(isSilent(options)) {
66 if(err) {
67 console.log('%s Build failed after %s seconds', chalk.red('[WEBPACK]'), chalk.blue((new Date().getTime() - startTime) / 1000));
68 } else {
69 console.log('%s Finished build after %s seconds', chalk.blue('[WEBPACK]'), chalk.blue((new Date().getTime() - startTime) / 1000));
70 }
71 }
72 if (done) {
73 done(err, stats);
74 }
75 if(err) {
76 throw err;
77 }
78 return stats;
79 }
80}
81
82function promisify(workers) {
83 return function(configPath, options, i, configLength) {
84 return new Promise(function(resolve, reject) {
85 workers(configPath, options, i, configLength, function(err, res) {
86 if(err) {
87 return reject(err);
88 }
89 resolve(res);
90 });
91 });
92 }
93}
94
95/**
96 * Runs the specified webpack configuration in parallel.
97 * @param {String} configPath The path to the webpack.config.js
98 * @param {Object} options
99 * @param {Boolean} [options.watch=false] If `true`, Webpack will run in `watch-mode`.
100 * @param {boolean} [options.maxRetries=Infinity] The maximum amount of retries on build error
101 * @param {Number} [options.maxConcurrentWorkers=require('os').cpus().length] The maximum number of parallel workers
102 * @param {Function} [callback] A callback to be invoked once the build has been completed
103 * @return {Promise} A Promise that is resolved once all builds have been created
104 */
105function run(configPath, options, callback) {
106 var config,
107 argvBackup = process.argv;
108 if(!options.argv) {
109 options.argv = [];
110 }
111 options.argv = ['node', 'parallel-webpack'].concat(options.argv);
112 try {
113 process.argv = options.argv;
114 config = require(configPath);
115 process.argv = argvBackup;
116 } catch(e) {
117 throw {
118 message: chalk.red('[WEBPACK]') + ' Could not load configuration file ' + chalk.underline(configPath),
119 error: e
120 };
121 }
122
123 var maxRetries = options && parseInt(options.maxRetries, 10) || Infinity,
124 maxConcurrentWorkers = options
125 && parseInt(options.maxConcurrentWorkers, 10)
126 || require('os').cpus().length,
127 workers = workerFarm({
128 maxRetries: maxRetries,
129 maxConcurrentWorkers: maxConcurrentWorkers
130 }, require.resolve('./src/webpackWorker')),
131 done = closeFarm(workers, options, callback, +new Date());
132
133 process.on('SIGINT', function() {
134 console.log(chalk.red('[WEBPACK]') + ' Forcefully shutting down');
135 done();
136 });
137
138 return startFarm(
139 config,
140 configPath,
141 options || {},
142 promisify(workers)
143 ).then(function(err, res) {
144 return done(null, res);
145 }, function(err) {
146 throw done(err);
147 });
148}
149
150module.exports = {
151 createVariants: require('./src/createVariants'),
152 run: run
153};
154