How can a plugin inject a “virtual” module into the compilation?

My use case is for server side rendering where I have two Webpack compilations.

One of them produces a client bundle with an index.html file as an asset.

And I’d like to inject that as a module for the second compilation so that the server side files can do something like:

const generated_index_file = require('./index.html');

(where index.html has been injected from the other compile)

More information about my workflow:

I’m using webpack-dev-server for these two compilations. I have an after-emit custom plugin on the server bundle compiler and in there I pull out the asset source of server.jsx from compilation.assets and use child_process.spawn to – kill the existing process and – spawn a fresh new node process and pipe the new server.jsx into it.

So I need a way to hook into the first compile, to pull out the freshly built index.html out of the first compile and to provide it to the second compile as a module.

In this way I can achieve a smooth development workflow using webpack-dev-server with watch and auto-reload benefits.

See related issues: #2270 #1122

I’m aware of virtual-module-webpack-plugin. But I don’t think it can get me there.

I’m aware of the inputFileSystem but don’t know if that’s the right way to go about it.

Edit:

I guess it’s possible to ask this question in a different way as well,

Given something like this:

const compiler = webpack([config1, config2]);

Can config2 require an asset from config1?

Again as mentioned before the use case here is for server side rendering where a client-side bundle is generated and immediately after client-side bundle is generated you’d want to also generate a server-side bundle that is consistent with the client-side bundle.

In other words from your perspective as a developer ideally it should be a single compile since you never want client and server bundle to drift away from each other.

However this implies you somehow have to wait for the client bundle to finish, and then will have to consume the assets of the client bundle for spitting out the HTML file with appropriate script/style tags and sub-resource integrity hashes and so on.

This is not particularly difficult to do for a passive filesystem based build you can just script it step by step to achieve what you want however I’m interested in a smooth development experience that is hopefully fully compatible with webpack-dev-server and is based on memory-filesystem.

In a dev environment you need to use hooks and you need to maintain a single node process that gets killed and re-created as the server bundle gets re-generated.

Author: Fantashit

1 thought on “How can a plugin inject a “virtual” module into the compilation?

  1. currently not. In a MultiCompiler compilation cannot depend on each other. But this would be a useful feature that is worth adding.

    btw. the webpack-dev-server cannot be used for the server build. There need to be something similar for a server-build (i. e. the webpack-dev-runner, which compiles a server bundle in memory and runs it). I think this doesn’t exist yet. It could also handle the HMR signaling for server HMR.

    Another part of the puzzle is to attach the output file system of one compilation to the input and watch file system of another compilation.

    That would be the best solution but with many missing pieces. Until there you propably need to use the normal filesystem…

Comments are closed.