Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

366
Views
Run command after webpack build

I'd like to run webpack in --watch mode, and run a shell command after each build that synchronizes a folder to another one.

I found this plugin that triggers an event after each build. That works, but the last piece of the puzzle is to trigger a shell command (for syncing) from Javascript. Any pointers on how to achieve this are greatly appreciated.

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

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);
});
over 4 years ago · Santiago Trujillo Report

0

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.

over 4 years ago · Santiago Trujillo Report

0

Basically, you can hook into the compiler at various stages of the whole compilation to emitting resources stage etc and run your own script or code as you please.

I like to do it this way -

class CustomPlugin {
  constructor(name, command, stage = 'afterEmit') {
    this.name = name;
    this.command = command;
    this.stage = stage;
  }

  static execHandler(err, stdout, stderr) {
    if (stdout) process.stdout.write(stdout);
    if (stderr) process.stderr.write(stderr);
  }

  apply(compiler) {
    compiler.hooks[this.stage].tap(this.name, () => {
      exec(this.command, CustomPlugin.execHandler);
    });
  }
}

and then use it like so

new CustomPlugin('RunTest', 'jest', 'beforeRun'),
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!