在webpack构建之后运行命令

Mon*_*kai 47 javascript webpack

我想在--watch模式下运行webpack ,并在每次构建之后运行一个shell命令,将文件夹同步到另一个文件夹.

我发现这个插件在每次构建后触发一个事件.这是有效的,但最后一个难题是从Javascript触发shell命令(用于同步).任何有关如何实现这一点的指示都非常感谢.

jch*_*ook 89

Webpack 4

截至今天(2018年4月11日),我尝试过的大多数插件都使用了弃用的API,导致出现此警告:

DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead
Run Code Online (Sandbox Code Playgroud)

我很高兴地发现ad-hoc webpack插件看起来非常简单.

在您的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);
          });
        });
      }
    }
  ]
};
Run Code Online (Sandbox Code Playgroud)

如果您更愿意使用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);
});
Run Code Online (Sandbox Code Playgroud)

  • 只是一个抬头,如果你正在寻找**之前**等价的钩子,你可以尝试`beforeCompile`.有关哪些钩子的文档可以在[这里]找到(https://webpack.js.org/api/compiler-hooks/) (7认同)
  • 这应该成为公认的答案. (6认同)
  • 很好,也适用于手表构建,Yair Tavor 的解决方案似乎并非如此。 (2认同)

小智 70

我也需要这样的东西,所以我编译了一个超级简单的插件来在每次构建之前和之后执行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;
Run Code Online (Sandbox Code Playgroud)

然后在你的webpack配置中:

plugins: [
    new WebpackShellPlugin({ 
         onBuildStart: ['echo "hello world"'], 
         onBuildEnd: ['echo "goodbye world"'] 
    })
]
Run Code Online (Sandbox Code Playgroud)

这是超级基本的,并且不能正确支持异步脚本.但它的确有效.你可以随意修改,但你觉得合适.

在MIT许可下考虑此代码.

需要节点4.x然后运行,因为我在这里使用了一些es6功能.

  • 如果你需要访问bundle文件,最好使用`after-emit`,因为当Webpack开始发出文件时会触发`emit`. (13认同)
  • 它已打包在:https://www.npmjs.com/package/webpack-shell-plugin (2认同)

小智 6

使用webpack-shell-plugin

如何使用:

const WebpackShellPlugin = require('webpack-shell-plugin');


    module.exports = {
      ...
      ...
      plugins: [
        new WebpackShellPlugin({onBuildStart:['echo "Webpack Start"'], onBuildEnd:['echo "Webpack End"']})
      ],
      ...
    }
Run Code Online (Sandbox Code Playgroud)

  • @Olga 将解决方案减少到绝对必要的程度是实际的贡献,值得赞扬。Krishna,您可以通过解释与 Yair Tavor 答案的差异来增强您的答案。据我了解,Yair Tavor的解决方案已经封装在webpack-shell-plugin中,您建议的是如何使用它。值得一提的是帮助别人了解情况。 (2认同)

jus*_*ris 5

您可以使用内置的child_process模块轻松运行任何shell命令.您也可以尝试一些node.js的shell库,比如Shell.js.它包装了大多数默认shell以便于使用

  • 谢谢,那是缺失的环节。我不知何故一直在兜圈子,完全错过了这个选择。 (2认同)
  • 对于仅使用webpack的用户来说,将是一个示例。 (2认同)

Soh*_*ail 5

基本上,您可以在整个编译的各个阶段连接到编译器以发出资源阶段等,并根据需要运行您自己的脚本或代码。

我喜欢这样做 -

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);
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它

new CustomPlugin('RunTest', 'jest', 'beforeRun'),
Run Code Online (Sandbox Code Playgroud)


Ser*_*nov 5

webpack-shell-plugin-next插入

\n

有一个webpack-shell-plugin-next插件:

\n\n

使用插件

\n

插件onAfterDone API

\n
\n

onAfterDone:完成后执行的脚本的配置对象。

\n
\n

可用于实现所需的手表相关行为(此外,请参阅下面的重要说明):

\n
\n

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

\n
\n

重要提示onAfterDone插件 API也适用于(影响)正常构建模式(即webpack不带选项的命令--watch)。

\n

以下是相关 GitHub 问题的附加参考:onDoneWatch 脚本在捆绑写入 \xc2\xb7 之前执行问题 #16 \xc2\xb7 s00d/webpack-shell-plugin-next

\n

例子

\n

刚刚尝试使用该插件:它运行良好。

\n

devDependencies(从package.json

\n
"devDependencies": {\n  "webpack": "5.3.2",\n  "webpack-cli": "4.1.0",\n  "webpack-shell-plugin-next": "2.0.4"\n}\n
Run Code Online (Sandbox Code Playgroud)\n

watchnpm 运行脚本(来自package.json

\n
"scripts": {\n  "watch": "webpack --config webpack.config.js --watch"\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Webpack 配置文件 ( webpack.config.js)

\n
const WebpackShellPluginNext = require(\'webpack-shell-plugin-next\');\n\nmodule.exports = {\n    plugins: [\n        new WebpackShellPluginNext({\n            onAfterDone: {\n                scripts: [\'echo "It works!"\'],\n                blocking: true,\n                parallel: false\n            }\n        })\n    ]\n};\n
Run Code Online (Sandbox Code Playgroud)\n

在监视模式下运行 Webpack 的命令行

\n
npm run watch\n
Run Code Online (Sandbox Code Playgroud)\n