Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack runtime conditional module resolution

I have an app that uses a core directory, and besides the core, I have different directories that contain classes that extend core classes and have slightly modified logic.

I got a file tree like below.

app
|-- core
|   |-- x
|   |-- y
|   |-- z
|   `-- plugins
|       |-- xyz-helper.js
|      
|-- slightly-modified-logic
|   `-- plugins
|       |-- xyz-helper.js

I want to use existing Webpack functionality to achieve something similar to a "theming" solution. You have a subtheme where you can override parent theme templates, if you don't override a specific template, it's gonna use the parent theme.

So, in my case, the ideal scenario would be:

1) Mount slightly-modified-logic directory

2) Dependencies in core classes should be resolved using the mounted directory, if the mounted directory does not provide an implementation of its own, only then fall back to core classes themselves.

I checked NormalModuleReplacementPlugin but that seems useful only if you wanna affect the entire build, I want the bundle to include everything, that or module chunk for each non-core directory that I load on demand.

The way I'm thinking of doing this is by building a resolve map, assuming I can chain path custom aliases, and Webpack tries all of those before falling back to normal resolution. But how do I do that @ runtime? The decision to mount a different directory than core should be taken based on runtime parameters.

I only need some hints, thanks.

like image 977
Ravenous Avatar asked Jul 27 '26 16:07

Ravenous


1 Answers

You can use Webpack dynamic imports. You can check the documentation on "Weback - Dynamic expressions in import()" . A part of the modules path should be specified, for example if we have a themes directory, we can load the corresponding theme plugins/code like so:

import(`themes/${themeName}/config.js`);
import(`themes/${themeName}/plugins/plugin.js`);

Assume we have a file structure:

themes
├─ themeA
│  └─ plugins
│     └─ plugin.js
└─ themeB
   └─ plugins
      └─ plugin.js

And the contents for each plugin.js file:

// themeA/plugins/plugin.js
export const thePlugin = () => console.log('Plugin A');

// themeB/plugins/plugin.js
export const thePlugin = () => console.log('Plugin B');

We can use dynamic imports like this:

let theme = 'themeA';

import(`./themes/${theme}/plugins/plugin.js`).then(({ thePlugin }) => {
  thePlugin();
}); 

theme = 'themeB';

import(`./themes/${theme}/plugins/plugin.js`).then(({ thePlugin }) => {
  thePlugin();
}); 

And the output will be:

Plugin A
Plugin B

You can read a nice article about "Webpack and dynamic import".

like image 141
Christos Lytras Avatar answered Jul 30 '26 10:07

Christos Lytras



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!