webpack插件中的流水线代码生成

hea*_*den 9 plugins webpack

问题:

我正在尝试编写一个webpack插件,将源代码生成器集成到我的webpack构建中.我的完整场景很复杂,因此我将其分解为更简单的问题进展.

第一部分:

我有一个代码生成器,%.js%.proto文件生成一个文件.例如,源文件foo.protobar.proto,我想我的插件产生以下编译步骤:

                ???????????
    foo.proto ??? codegen ???> foo.js
                ???????????
                ???????????
    bar.proto ??? codegen ???> bar.js
                ???????????
Run Code Online (Sandbox Code Playgroud)

我的意思是在每个%.proto文件上注册这个依赖项(用于文件监视)并%.js在编译对象上声明生成的assets()?

这种情况可以通过使用加载器来实现require('codegen!foo.proto'),但是通过第三部分,您将看到为什么加载器不合适.

我的意图将表达make为:

%.js: %.proto
    codegen $^ $@
Run Code Online (Sandbox Code Playgroud)

第二部分:

%.js我的生成器发出的生成文件现在采用ES6语法,因此需要转换为ES5.我已经babel-loader配置了ES6源的转换,如果这有用的话.继续这个例子,步骤将是:

                ???????????  ?????????
    foo.proto ??? codegen ???? babel ???> foo.js
                ???????????  ?????????
                ???????????  ?????????
    bar.proto ??? codegen ???? babel ???> bar.js
                ???????????  ?????????
Run Code Online (Sandbox Code Playgroud)

即,我想要:

%.js: %.proto
    codegen $^ | babel -o $@
Run Code Online (Sandbox Code Playgroud)

我是不是该:

  • 在我的插件任务中进行转换,将其隐藏在webpack编译中?
  • 通过在编译对象上创建其他任务来获取webpack来进行转换?
  • 以一种允许webpack通过它已经用于其他来源的适当加载器管道转换它的方式发出生成的js?

第三部分:

我的生成器现在需要一个额外的输入文件%.fragment.js.我怎样才能表达对的WebPack编译这种依赖关系,使得无论是在观看文件将重建资产%.proto%.fragment.js改变?这种多源依赖性是我不认为装载机是适当的方向的原因.

                  ???????????  ?????????
      foo.proto ??? codegen ???? babel ???> foo.js
foo.fragment.js ???         ?  ?       ?
                  ???????????  ?????????
                  ???????????  ?????????
      bar.proto ??? codegen ???? babel ???> bar.js
bar.fragment.js ???         ?  ?       ?
                  ???????????  ?????????
Run Code Online (Sandbox Code Playgroud)

我的意图是:

%.js: %.proto %.fragment.js
    codegen $^ | babel -o $@
Run Code Online (Sandbox Code Playgroud)

这篇文章中,我看到提到"儿童汇编".是否有任何webpack文档说明这些是什么或如何使用它们?

或者,这种情况不是webpack打算支持的,即使是通过自定义插件?

Bob*_*nge 1

你的问题可以用loader来解决。我建议在工作前阅读指南

首先的优先级是[loader] do only a single task。所以,你的 proto 文件加载器只会生成 ES6 js 文件。


问:我应该在哪里注册每个 %.proto 文件的依赖关系(用于文件监视)并在编译对象上声明生成的资产 (%.js)?

答:您应该以常见的方式要求您的原始文件(如您所描述的):

require("foo.proto");
Run Code Online (Sandbox Code Playgroud)

并使用emitFile函数生成额外的资源:

emitFile(name: string, content: Buffer|String, sourceMap: {...})
Run Code Online (Sandbox Code Playgroud)

问:我是否应该以允许 webpack 通过已用于其他源的适当加载器管道对其进行转换的方式发出生成的 js?

答:是的,你的加载器必须只执行一个任务:从 proto 文件生成 ES6 js 文件。然后生成的文件将传递给 babel:

{test: /\.proto$/, loader: 'babel-loader!proto-loader'}
Run Code Online (Sandbox Code Playgroud)

问:我的生成器现在需要一个额外的输入文件 %.fragment.js。如何表达对 webpack 编译的这种依赖性,以便在 %.proto 或 %.fragment.js 更改时文件监视将重建资产?

答:您必须使用函数标记依赖项addDependency(文档中的示例):

// Loader adding a header
var path = require("path");
module.exports = function(source) {
    this.cacheable();
    var callback = this.async();
    var headerPath = path.resolve("header.js");
    this.addDependency(headerPath);
    fs.readFile(headerPath, "utf-8", function(err, header) {
        if(err) return callback(err);
        callback(null, header + "\n" + source);
    });
}; 
Run Code Online (Sandbox Code Playgroud)