generate-package-json-webpack-plugin icon indicating copy to clipboard operation
generate-package-json-webpack-plugin copied to clipboard

add support of MultiCompiler mode

Open FranckFreiburger opened this issue 8 years ago • 10 comments

Hi,

I use webpack in MultiCompiler mode to compile my 3 bundles: client-side-bundle, server-side-bundle and server-bundle. server-side-bundle and server-bundle run on the server in the same nodejs instance but does not have the same npm dependencies however, in the final package.json file, I expect to have all deps merged (server-side-bundle and server-bundle).

I tried this:

var genPackage = new GeneratePackageJsonPlugin(basePackageValues, versionsPackageFilename);

var clientSideConfig = require('./build/webpack.client-side.config');
var serverSideConfig = require('./build/webpack.server-side.config');
var serverConfig = require('./build/webpack.server.config');

serverSideConfig.plugins.push(genPackage);
serverConfig.plugins.push(genPackage);

webpack([
	clientSideConfig,
	serverSideConfig,
	serverConfig,
], (err, stats) => { ...

but it seems that the package.json is emitted at the end of each compilation.

Do you think it is possible to optionally emit the package.json at the end of all compilations ?

FranckFreiburger avatar Jul 19 '17 07:07 FranckFreiburger

Interesting... I've never worked with a multi-compile of Webpack like that. I can see why you would like the dependencies merged for those two configs.

This was my first plugin, and the inner workings of Webpack can be quite a joy ride. But I'll be happy to take a closer look and see if it's an easy thing to add in as an option. From my base understand right now, it looks like it might not be that easy.

Do you know of any other plugins which you can pass into individual Webpack configurations, but detects that it is a part of a greater group of configurations and considers them all instead...? Would be a good place to start.

I would think Webpack treats each configuration as an isolated process. But I could be wrong. Interesting problem to look into.

lostpebble avatar Jul 19 '17 09:07 lostpebble

After some investigations, I have found the following clues:

  • Webpack treats each configuration as an isolated process but when multi-compiler is involved, webpack([...]) returns a MultiCompiler instance that supports plugin('done', ... when all compilations are done.

  • MultiCompiler also has a compilers property that contains each individual compiler instance, which can be used normally (with 'emit' plugin, ...)

  • Unfortunately, MultiCompiler plugins have to be set outside the configurations files (which is quite logical)

HIH

FranckFreiburger avatar Jul 19 '17 10:07 FranckFreiburger

... this implies that package.json cannot be emitted on a per-compilation basis

FranckFreiburger avatar Jul 19 '17 10:07 FranckFreiburger

Hmm.. okay. I'll take a closer look soon enough and see if there might be a way specifically for MultiCompiler configurations. Thanks for the clues.

You're welcome to check it out yourself and submit a pull request too, seeing as you know a little more about it at the moment 🙂

I'm curious why you are not combining those two configurations into one though? If they're using the same dependencies, and running on the same Node.js instance, is the configuration not similar? Can see why it might not be possible, but of course that would help with the plugin generating all the dependencies you want for both entry / output points.

lostpebble avatar Jul 19 '17 10:07 lostpebble

Ok, I will post my current implementation.

I am setting up a server-side-rendering framework based on vue.js. client-side-bundle and server-side-bundle are automatically generated according the web application and the server-bundle is the part that run express and handle client-side-bundle and server-side-bundle. Dependencies of server-side-bundle and server-bundle have common entries but are not the same, server-bundle use express, vue-server-renderer, ... whereas server-side-bundle use vue, vue-router and other vue components used by the web application.

FranckFreiburger avatar Jul 19 '17 11:07 FranckFreiburger

Okay I see. I run a lot of server-side rendering stuff as well, only with React. I just bundle all my server-side stuff that does the client rendering stuff along with the regular server bundle - since they are only ever going to be run together anyway. But I'm not too clued up on Vue, so perhaps there is something I'm missing that requires you to bundle that part separately.

You say you are creating a framework? So it should be easily pluggable into other server codebases? I guess that makes sense then to keep things separate.

In any case, this is still an issue that I will still try look into as soon as I can.

lostpebble avatar Jul 19 '17 17:07 lostpebble

I think it is possible for me to bundle all server-side stuff in a single bundle but currently splitting into two bundles allow me to update only the webapp code without restarting the server. My framework is similar to next.js and is not very pluggable since it fits my web application development needs only (at least at the moment)

FranckFreiburger avatar Jul 20 '17 07:07 FranckFreiburger

I think it is possible for me to bundle all server-side stuff in a single bundle but currently splitting into two bundles allow me to update only the webapp code without restarting the server.

Ahhh... I see. Okay that's actually quite a cool use case. I usually just restart the server if I make changes that I would really like to see server-rendered while I'm developing. Mostly I don't restart the server though, and I just let the client code re-hydrate over the stale server-rendered content and continue developing the client stuff on top of that. For me, testing how things are server-rendered is not a common occurrence as it usually just works as it should when I restart the server again. It's cool that you have managed to bridge that restart gap though!

lostpebble avatar Jul 20 '17 08:07 lostpebble

+1

eyaylagul avatar Aug 31 '18 08:08 eyaylagul

I think one of the possible way to handle MultiCompiler mode would be to add fileName optional prop. This way we would have multiple {fileName}.json files. And we can do whatever we want (like merging them into one etc). I forked this plugin with this hack and it worked fine for me.

@lostpebble I could add a PR its basically 2 lines changes

denchiklut avatar Apr 14 '23 14:04 denchiklut