简体   繁体   English

webpack 构建后运行命令

[英]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.我想在--watch模式下运行 webpack,并在每次构建后运行一个 shell 命令,将一个文件夹同步到另一个文件夹。

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.这是可行的,但最后一个难题是从 Javascript 触发 shell 命令(用于同步)。 Any pointers on how to achieve this are greatly appreciated.非常感谢有关如何实现这一目标的任何指示。

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.js file:在你的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 spawn to 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);
});

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.在 MIT 许可下考虑此代码。

Needs node 4.x and up to run, as I use some es6 features here.需要 node 4.x 及更高版本才能运行,因为我在这里使用了一些 es6 功能。

Use webpack-shell-plugin使用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"']})
      ],
      ...
    }

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'),

You can easily run any shell command with built-in child_process module.您可以使用内置的child_process模块轻松运行任何 shell 命令。 Also you can try some shell libraries for node.js, like Shell.js .你也可以尝试一些 node.js 的 shell 库,比如Shell.js It wraps most of default shell for more convenient usage它包装了大部分默认 shell 以方便使用

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希望它可以帮助

webpack-shell-plugin-next plugin webpack-shell-plugin-next插件

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

Using the plugin使用插件

The onAfterDone plugin API : onAfterDone插件 API

onAfterDone : configuration object for scripts that execute after done. onAfterDone :完成后执行的脚本的配置对象。

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.我想在--watch模式下运行 webpack,并在每次构建后运行一个 shell 命令,将一个文件夹同步到另一个文件夹。

Important note : the onAfterDone plugin API will work for (affect) the normal build mode too (ie the webpack command without the --watch option).重要提示onAfterDone插件 API也适用于(影响)正常构建模式(即没有--watch选项的webpack命令)。

Here is an additional reference to the related GitHub issue: onDoneWatch scripts executing before bundle written · Issue #16 · s00d/webpack-shell-plugin-next .这是对相关 GitHub 问题的附加参考: onDoneWatch 脚本在编写包之前执行 · 问题 #16 · s00d/webpack-shell-plugin-next

Example例子

Have just tried to use the plugin: it has worked fine.刚刚尝试使用该插件:它运行良好。

devDependencies (from package.json ) devDependencies (来自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 ) watch npm 运行脚本(来自package.json

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

Webpack configuration file ( webpack.config.js ) Webpack 配置文件( 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在 watch 模式下运行 Webpack 的命令行

npm run watch

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM