在webpack构建之后运行命令

时间:2015-05-18 20:58:40

标签: javascript webpack

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

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

7 个答案:

答案 0 :(得分:64)

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

然后在你的webpack配置中:

plugins: [
    new WebpackShellPlugin({ 
         onBuildStart: ['echo "hello world"'], 
         onBuildEnd: ['echo "goodbye world"'] 
    })
]

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

  

在MIT许可下考虑此代码。

     

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

答案 1 :(得分:63)

Webpack 4

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

DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead

很高兴我发现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);
          });
        });
      }
    }
  ]
};

如果您更愿意使用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);
});

答案 2 :(得分:4)

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

答案 3 :(得分:3)

使用webpack-shell-plugin

使用方法:

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


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

答案 4 :(得分:1)

如果guya想要在特定文件被更改时执行此操作,您可以使用我构建的这个小插件:https://www.npmjs.com/package/webpack-noodle-plugin

希望它可以提供帮助

答案 5 :(得分:0)

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

我喜欢这样-

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);
    });
  }
}

然后像这样使用它

new CustomPlugin('RunTest', 'jest', 'beforeRun'),

答案 6 :(得分:0)

webpack-shell-plugin-next插件

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

使用插件

onAfterDone plugin API

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

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

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

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

这里是有关GitHub相关问题的其他参考:onDoneWatch scripts executing before bundle written · Issue #16 · s00d/webpack-shell-plugin-next

示例

刚刚尝试使用该插件:效果很好。

devDependencies(来自package.json

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

watch npm运行脚本(来自package.json

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

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
            }
        })
    ]
};

以监视模式运行Webpack的命令行

npm run watch