问题:
我正在尝试编写一个 webpack 插件,将源代码生成器集成到我的 webpack 构建中。我的完整场景很复杂,因此我将其分解为一系列更简单的问题。
第一部分:
我有一个代码生成器,可以从 %.proto
文件生成 %.js
文件。例如,对于源文件 foo.proto
和 bar.proto
,我希望我的插件生成以下编译步骤:
┌─────────┐
foo.proto ──┤ codegen ├──> foo.js
└─────────┘
┌─────────┐
bar.proto ──┤ codegen ├──> bar.js
└─────────┘
我打算在哪里注册每个 %.proto
文件的依赖关系(用于文件监视)并在编译对象上声明生成的 Assets (%.js
) ?
可以通过使用 require('codegen!foo.proto')
使用加载器来实现此场景,但到了第三部分,您将了解为什么加载器不合适。
我的意图将在 make
中表达为:
%.js: %.proto
codegen $^ $@
第二部分:
我的生成器发出的生成的 %.js
文件现在采用 ES6 语法,因此需要转换为 ES5。我已经配置了 babel-loader 来转译 ES6 源代码(如果有帮助的话)。继续这个例子,步骤是:
┌─────────┐ ┌───────┐
foo.proto ──┤ codegen ├──┤ babel ├──> foo.js
└─────────┘ └───────┘
┌─────────┐ ┌───────┐
bar.proto ──┤ codegen ├──┤ babel ├──> bar.js
└─────────┘ └───────┘
也就是说,我想要:
%.js: %.proto
codegen $^ | babel -o $@
我应该:
- 在我的插件任务中进行转译,将其隐藏在 webpack 编译中吗?
- 要让 webpack 通过在编译对象上创建附加任务来进行转译吗?
- 以某种方式发出生成的 js,允许 webpack 通过已用于其他源的适当加载器管道对其进行转换?
第三部分:
我的生成器现在需要一个额外的输入文件 %.fragment.js
。如何表达对 webpack 编译的这种依赖关系,以便在更改 %.proto
或 %.fragment.js
时文件监视将重建 Assets ?这种多源依赖性就是为什么我认为加载器不是一个合适的方向。
┌─────────┐ ┌───────┐
foo.proto ──┤ codegen ├──┤ babel ├──> foo.js
foo.fragment.js ──┤ │ │ │
└─────────┘ └───────┘
┌─────────┐ ┌───────┐
bar.proto ──┤ codegen ├──┤ babel ├──> bar.js
bar.fragment.js ──┤ │ │ │
└─────────┘ └───────┘
我的意图是:
%.js: %.proto %.fragment.js
codegen $^ | babel -o $@
在 this post ,我看到有提到“ child 合辑”。是否有任何 webpack 文档说明它们是什么或如何使用它们?
或者,这种场景不是 webpack 想要支持的,即使是通过自定义插件也是如此?
最佳答案
你的问题可以通过加载器来解决。我建议阅读guidelines上类前。
首先,优先级是[loader]只执行一项任务
。因此,您的 proto 文件加载器将只生成 ES6 js 文件。
问:我应该在哪里注册每个 %.proto 文件的依赖关系(用于文件监视)并在编译对象上声明生成的 Assets (%.js)?
答:您应该以常见的方式要求您的原型(prototype)文件(如您所描述的):
require("foo.proto");
并通过emitFile生成额外的 Assets 功能:
emitFile(name: string, content: Buffer|String, sourceMap: {...})
<小时/>
问:我是否应该以允许 webpack 通过已用于其他源的适当加载器管道对其进行转换的方式发出生成的 js?
A:是的,你的加载器必须只执行一个任务:从 proto 文件生成 ES6 js 文件。然后生成的文件将传递给 babel:
{test: /\.proto$/, loader: 'babel-loader!proto-loader'}
<小时/>
问:我的生成器现在需要一个额外的输入文件 %.fragment.js。如何表达对 webpack 编译的依赖,以便在 %.proto 或 %.fragment.js 更改时文件监视将重建资源?
答:你必须mark dependencies使用 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);
});
};
关于plugins - webpack 插件中的流水线代码生成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34064488/