Run command after webpack build

后端 未结 7 1770
名媛妹妹
名媛妹妹 2020-12-04 15:29

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 t

相关标签:
7条回答
  • 2020-12-04 15:44

    You can easily run any shell command with built-in child_process module. Also you can try some shell libraries for node.js, like Shell.js. It wraps most of default shell for more convenient usage

    0 讨论(0)
  • 2020-12-04 15:45

    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);
    });
    
    0 讨论(0)
  • 2020-12-04 15:52

    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"']})
          ],
          ...
        }
    
    0 讨论(0)
  • 2020-12-04 15:58

    webpack-shell-plugin-next plugin

    There is the webpack-shell-plugin-next plugin:

    • GitHub: s00d/webpack-shell-plugin-next: Run shell commands either before or after webpack 4 builds.

      • Please, see the «Webpack compatibility» section.
    • npm: webpack-shell-plugin-next - npm.

    Using the plugin

    The onAfterDone plugin API:

    onAfterDone: configuration object for scripts that execute after done.

    may be used to achieve the desired watch-related behaviour (in addition, please, see the important note below):

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

    Important note: the onAfterDone plugin API will work for (affect) the normal build mode too (i.e. the webpack command without the --watch option).

    Here is an additional reference to the related GitHub issue: onDoneWatch scripts executing before bundle written · Issue #16 · s00d/webpack-shell-plugin-next.

    Example

    Have just tried to use the plugin: it has worked fine.

    devDependencies (from package.json)

    "devDependencies": {
      "webpack": "5.3.2",
      "webpack-cli": "4.1.0",
      "webpack-shell-plugin-next": "2.0.4"
    }
    

    watch npm run script (from package.json)

    "scripts": {
      "watch": "webpack --config webpack.config.js --watch"
    }
    

    Webpack configuration file (webpack.config.js)

    const WebpackShellPluginNext = require('webpack-shell-plugin-next');
    
    module.exports = {
        plugins: [
            new WebpackShellPluginNext({
                onAfterDone: {
                    scripts: ['echo "It works!"'],
                    blocking: true,
                    parallel: false
                }
            })
        ]
    };
    

    Command line to run Webpack in the watch mode

    npm run watch
    
    0 讨论(0)
  • 2020-12-04 15:59

    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'),
    
    0 讨论(0)
  • 2020-12-04 16:05

    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.

    0 讨论(0)
提交回复
热议问题