Creating pipelined code in webpack plugin

Problem:

I am trying to write a webpack plugin to integrate a source code generator into my webpack assembly. My full scenario is complicated, so I broke it up into a simpler flow of questions.

Part I:

I have a code generator that generates a %.js file from a %.proto file. For example, with the source files foo.proto and bar.proto , I want my plugin to perform the following compilation steps:

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” foo.proto ─── codegen β”œβ”€β”€> foo.js β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” bar.proto ─── codegen β”œβ”€β”€> bar.js β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ 

Where should I register this dependency for each %.proto file (to view files) and declare the generated assets ( %.js ) in the compilation object?

This scenario can be achieved using the loader using require('codegen!foo.proto') , but in part III you will see why the loaders do not work.

My intention would be expressed in make as:

 %.js: %.proto codegen $^ $@ 

Part II:

The generated %.js files released by my generator are now in ES6 syntax, so they need to be converted to ES5. I already have a babel-loader configured to broadcast the ES6 source, if that is useful. Continuing the example, follow these steps:

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β” foo.proto ─── codegen β”œβ”€β”€β”€ babel β”œβ”€β”€> foo.js β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β” bar.proto ─── codegen β”œβ”€β”€β”€ babel β”œβ”€β”€> bar.js β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”˜ 

ie, I want:

 %.js: %.proto codegen $^ | babel -o $@ 

Should I:

  • do transpiling inside my plugin task, hiding it from compiling webpack?
  • get webpack to do the transpilation by creating additional tasks for the compilation object?
  • to emit js created in a way that allows webpack to convert it through the appropriate loader pipeline that it already uses for another source?

Part III:

Now my generator receives the additional input file %.fragment.js . How can I express this dependency on webpack compilation so that file browsing will restore assets when %.proto or %.fragment.js ? This dependency on multiple sources is why I don't think boot loaders are the right direction to enter.

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β” foo.proto ─── codegen β”œβ”€β”€β”€ babel β”œβ”€β”€> foo.js foo.fragment.js ─── β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β” bar.proto ─── codegen β”œβ”€β”€β”€ babel β”œβ”€β”€> bar.js bar.fragment.js ─── β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”˜ 

My intention:

 %.js: %.proto %.fragment.js codegen $^ | babel -o $@ 

In this post, I saw the mention of "child compilation." Is there any webpack documentation about what it is or how they are intended to be used?

Or is this a scenario not for the web package to be supported, even through custom plugins?

+7
plugins webpack
source share
1 answer

Your problem can be solved with the help of bootloaders. I recommend reading the guidelines before starting work.

First, priorrity [loader] do only a single task . Thus, your proto loader will simply generate an ES6 js file.


Q: Where should I register this dependency for each% .proto file (to view files) and declare the generated assets (% .js) for the compilation object?

A: You must require that your proto files be in the usual way (as described):

 require("foo.proto"); 

and creating additional assets using emitFile :

 emitFile(name: string, content: Buffer|String, sourceMap: {...}) 

Q: Should I emit generated js so that webpack can convert it through the appropriate loader pipeline, which it already uses for another source?

A: Yes, your loader should only perform one task: generate the ES6 js file from the proto file. And then the resulting file will be transferred to babel:

 {test: /\.proto$/, loader: 'babel-loader!proto-loader'} 

Q: My generator now receives the additional input file% .fragment.js. How can I express this dependency on webpack compilation so that file browsing will restore assets when% .proto or% .fragment.js changes?

A: you should track the dependencies using the addDependency function (example from the docs):

 // 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); }); }; 
0
source share

All Articles