From a30f22f827a4eb145102b4cd93f1ce979d242d38 Mon Sep 17 00:00:00 2001 From: Ruslan Roskoshny Date: Mon, 5 Feb 2018 00:13:18 +0300 Subject: [PATCH] Add `sync` option: resolve 1337programming/webpack-shell-plugin#48 --- lib/index.js | 64 +++++++++++++++++++++++++------------ src/webpack-shell-plugin.js | 37 +++++++++++++++------ webpack.config.js | 2 +- 3 files changed, 71 insertions(+), 32 deletions(-) diff --git a/lib/index.js b/lib/index.js index d6c468e..144c625 100644 --- a/lib/index.js +++ b/lib/index.js @@ -151,7 +151,8 @@ var defaultOptions = { onBuildExit: [], dev: true, verbose: false, - safe: false + safe: false, + sync: false }; var WebpackShellPlugin = function () { @@ -192,17 +193,42 @@ var WebpackShellPlugin = function () { } }, { key: 'handleScript', - value: function handleScript(script) { + value: function handleScript(script, next) { + var proc = null; if (os.platform() === 'win32' || this.options.safe) { - this.spreadStdoutAndStdErr(exec(script, this.puts)); + proc = exec(script, this.puts); + this.spreadStdoutAndStdErr(proc); } else { var _serializeScript = this.serializeScript(script), command = _serializeScript.command, args = _serializeScript.args; - var proc = spawn(command, args, { stdio: 'inherit' }); + proc = spawn(command, args, { stdio: 'inherit' }); proc.on('close', this.puts); } + + if (this.options.sync) { + proc.on('close', next); + } else { + next(); + } + } + }, { + key: 'handleScriptsOn', + value: function handleScriptsOn(data) { + var _this = this; + + var next = function next(inbound) { + if (inbound.length > 0) { + var head = inbound[0]; + var tail = inbound.slice(1); + + _this.handleScript(head, function () { + next(tail); + }); + } + }; + next(data); } }, { key: 'validateInput', @@ -231,42 +257,38 @@ var WebpackShellPlugin = function () { }, { key: 'apply', value: function apply(compiler) { - var _this = this; + var _this2 = this; compiler.plugin('compilation', function (compilation) { - if (_this.options.verbose) { + if (_this2.options.verbose) { console.log('Report compilation: ' + compilation); console.warn('WebpackShellPlugin [' + new Date() + ']: Verbose is being deprecated, please remove.'); } - if (_this.options.onBuildStart.length) { + if (_this2.options.onBuildStart.length) { console.log('Executing pre-build scripts'); - for (var i = 0; i < _this.options.onBuildStart.length; i++) { - _this.handleScript(_this.options.onBuildStart[i]); - } - if (_this.options.dev) { - _this.options.onBuildStart = []; + _this2.handleScriptsOn(_this2.options.onBuildStart); + if (_this2.options.dev) { + _this2.options.onBuildStart = []; } } }); compiler.plugin('after-emit', function (compilation, callback) { - if (_this.options.onBuildEnd.length) { + if (_this2.options.onBuildEnd.length) { console.log('Executing post-build scripts'); - for (var i = 0; i < _this.options.onBuildEnd.length; i++) { - _this.handleScript(_this.options.onBuildEnd[i]); - } - if (_this.options.dev) { - _this.options.onBuildEnd = []; + _this2.handleScriptsOn(_this2.options.onBuildEnd); + if (_this2.options.dev) { + _this2.options.onBuildEnd = []; } } callback(); }); compiler.plugin('done', function () { - if (_this.options.onBuildExit.length) { + if (_this2.options.onBuildExit.length) { console.log('Executing additional scripts before exit'); - for (var i = 0; i < _this.options.onBuildExit.length; i++) { - _this.handleScript(_this.options.onBuildExit[i]); + for (var i = 0; i < _this2.options.onBuildExit.length; i++) { + _this2.handleScript(_this2.options.onBuildExit[i]); } } }); diff --git a/src/webpack-shell-plugin.js b/src/webpack-shell-plugin.js index b287508..b3c0418 100644 --- a/src/webpack-shell-plugin.js +++ b/src/webpack-shell-plugin.js @@ -8,7 +8,8 @@ const defaultOptions = { onBuildExit: [], dev: true, verbose: false, - safe: false + safe: false, + sync: false }; export default class WebpackShellPlugin { @@ -36,14 +37,34 @@ export default class WebpackShellPlugin { return {command, args}; } - handleScript(script) { + handleScript(script, next) { + let proc = null; if (os.platform() === 'win32' || this.options.safe) { - this.spreadStdoutAndStdErr(exec(script, this.puts)); + proc = exec(script, this.puts); + this.spreadStdoutAndStdErr(proc); } else { const {command, args} = this.serializeScript(script); - const proc = spawn(command, args, {stdio: 'inherit'}); + proc = spawn(command, args, {stdio: 'inherit'}); proc.on('close', this.puts); } + + if (this.options.sync) { + proc.on('close', next); + } else { + next() + } + } + + handleScriptsOn(data) { + let next = (inbound) => { + if (inbound.length > 0) { + let head = inbound[0]; + let tail = inbound.slice(1); + + this.handleScript(head, () => {next(tail)}); + } + }; + next(data) } validateInput(options) { @@ -77,9 +98,7 @@ export default class WebpackShellPlugin { } if (this.options.onBuildStart.length) { console.log('Executing pre-build scripts'); - for (let i = 0; i < this.options.onBuildStart.length; i++) { - this.handleScript(this.options.onBuildStart[i]); - } + this.handleScriptsOn(this.options.onBuildStart); if (this.options.dev) { this.options.onBuildStart = []; } @@ -89,9 +108,7 @@ export default class WebpackShellPlugin { compiler.plugin('after-emit', (compilation, callback) => { if (this.options.onBuildEnd.length) { console.log('Executing post-build scripts'); - for (let i = 0; i < this.options.onBuildEnd.length; i++) { - this.handleScript(this.options.onBuildEnd[i]); - } + this.handleScriptsOn(this.options.onBuildEnd); if (this.options.dev) { this.options.onBuildEnd = []; } diff --git a/webpack.config.js b/webpack.config.js index 95ef485..ece2de7 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -19,7 +19,7 @@ module.exports = { ] }, plugins: [ - new WebpackShellPlugin({onBuildStart:['node test.js'], onBuildEnd:['echo "Webpack End"'], safe: true, verbose: true}), + new WebpackShellPlugin({onBuildStart:['node test.js', 'echo "end node.test"'], onBuildEnd:['echo "Webpack End"'], safe: true, verbose: true, sync: true}), new webpack.HotModuleReplacementPlugin() ] };