Run command after webpack build
I also needed such a thing, so I compiled a super simple plugin to execute shell commands before and after each build.
'use strict';
var exec = require('child_process').exec;
function puts(error, stdout, stderr) {
console.log(stdout);
}
function WebpackShellPlugin(options) {
var defaultOptions = {
onBuildStart: [],
onBuildEnd: []
};
this.options = Object.assign(defaultOptions, options);
}
WebpackShellPlugin.prototype.apply = function(compiler) {
const options = this.options;
compiler.plugin("compilation", compilation => {
if(options.onBuildStart.length){
console.log("Executing pre-build scripts");
options.onBuildStart.forEach(script => exec(script, puts));
}
});
compiler.plugin("emit", (compilation, callback) => {
if(options.onBuildEnd.length){
console.log("Executing post-build scripts");
options.onBuildEnd.forEach(script => exec(script, puts));
}
callback();
});
};
module.exports = WebpackShellPlugin;
then in your webpack config:
plugins: [
new WebpackShellPlugin({
onBuildStart: ['echo "hello world"'],
onBuildEnd: ['echo "goodbye world"']
})
]
This is super basic, and do not support async scripts properly. but it works. feel free to modify however you see fit.
Consider this code under MIT licence.
Needs node 4.x and up to run, as I use some es6 features here.
Webpack 4
As of today (April 11, 2018), most of the plugins I've tried use the deprecated API resulting in this warning:
DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead
It pleased me to find that you can easily write an ad-hoc webpack plugin (docs).
In your webpack.config.js
file:
const exec = require('child_process').exec;
module.exports = {
// ... other config here ...
plugins: [
// ... other plugins here ...
{
apply: (compiler) => {
compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
exec('<path to your post-build script here>', (err, stdout, stderr) => {
if (stdout) process.stdout.write(stdout);
if (stderr) process.stderr.write(stderr);
});
});
}
}
]
};
If you'd rather use spawn
to get real-time or "live" data from your script, this illustrates the basic usage:
const spawn = require('child_process').spawn;
const child = spawn('<your script here>');
child.stdout.on('data', function (data) {
process.stdout.write(data);
});
child.stderr.on('data', function (data) {
process.stderr.write(data);
});
Use webpack-shell-plugin
How to Use:
const WebpackShellPlugin = require('webpack-shell-plugin');
module.exports = {
...
...
plugins: [
new WebpackShellPlugin({onBuildStart:['echo "Webpack Start"'], onBuildEnd:['echo "Webpack End"']})
],
...
}