Javascript webpack 构建后运行命令
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/30312715/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Run command after webpack build
提问by Monokai
I'd like to run webpack in --watchmode, and run a shell command after each build that synchronizes a folder to another one.
我想在--watch模式下运行 webpack ,并在每次构建后运行一个 shell 命令,将一个文件夹同步到另一个文件夹。
I found this pluginthat 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.
我发现这个插件会在每次构建后触发一个事件。这是可行的,但最后一个难题是从 Javascript 触发 shell 命令(用于同步)。非常感谢有关如何实现这一目标的任何指示。
采纳答案by just-boris
You can easily run any shell command with built-in child_processmodule. Also you can try some shell libraries for node.js, like Shell.js. It wraps most of default shell for more convenient usage
您可以使用内置的child_process模块轻松运行任何 shell 命令。你也可以尝试一些 node.js 的 shell 库,比如Shell.js。它包装了大部分默认 shell 以方便使用
回答by jchook
Webpack 4
网络包 4
As of today (April 11, 2018), most of the plugins I've tried use the deprecated API resulting in this warning:
截至今天(2018 年 4 月 11 日),我尝试过的大多数插件都使用了已弃用的 API,导致出现此警告:
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).
我很高兴地发现您可以轻松地编写一个特别的 webpack 插件 ( docs)。
In your webpack.config.jsfile:
在您的webpack.config.js文件中:
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 spawnto get real-time or "live" data from your script, this illustrates the basic usage:
如果您更愿意使用spawn从脚本中获取实时或“实时”数据,这说明了基本用法:
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);
});
回答by Yair Tavor
I also needed such a thing, so I compiled a super simple plugin to execute shell commands before and after each build.
我也需要这样的东西,所以我编译了一个超级简单的插件,在每次构建前后执行shell命令。
'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:
然后在你的 webpack 配置中:
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.
在 MIT 许可下考虑此代码。
需要 node 4.x 及更高版本才能运行,因为我在这里使用了一些 es6 功能。
回答by Sohail
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'),
回答by Krishan Kumar
How to Use:
如何使用:
const WebpackShellPlugin = require('webpack-shell-plugin');
    module.exports = {
      ...
      ...
      plugins: [
        new WebpackShellPlugin({onBuildStart:['echo "Webpack Start"'], onBuildEnd:['echo "Webpack End"']})
      ],
      ...
    }
回答by Pistolpete .
If you guya want to do it when a specific file gets changed you can use this little plugin I built: https://www.npmjs.com/package/webpack-noodle-plugin
如果您想在更改特定文件时执行此操作,您可以使用我构建的这个小插件:https://www.npmjs.com/package/webpack-noodle-plugin
Hope it can help
希望它可以帮助

