Reputation: 13211
Is it possible to make webpack load another module based on some context information?
For example I've two versions of my React application: desktop and mobile
In my index.js I decide which application to load:
if (isMobile()) {
loadMobile().then(({default: App}) => render(App))
}
Now I would like to reuse some modules, but some I would like to override it. So by default it should load index.js, but if the context isMobile
and next to the index.js
a mobile.js
file exists, it should load the mobile
variant.
components/
Button/
index.js
mobile.js
In the mobile context, webpack should load mobile.js instead of index.js
I could't find anything that I could use to solve it, any ideas?
PS: I've already created an issue on github, it also demonstrates the problem and what I want to achieve even better:
https://github.com/webpack/enhanced-resolve/issues/180
Upvotes: 11
Views: 2002
Reputation: 4987
I guess that you have to create two builds: one with default resolve.mainFiles and one with
resolve: {
mainFiles: ['mobile', 'index']
}
You will need to decide which bundle to load inside your html. Or create two different html files and move isMobile
logic to the webserver config so it'll decide which html to return to user.
Some chunks might be the same between both builds. But it is very likely that you will end up with two different apps. You might reduce the built code duplication between two apps with DllPlugin.
Upvotes: 0
Reputation: 466
You can use dynamic loading function and dynamic importing syntax for this problem.
Install Babel plugin plugin-syntax-dynamic-import
:
npm install --save-dev @babel/plugin-syntax-dynamic-import
and use it in .babelrc
{
"plugins": ["@babel/plugin-syntax-dynamic-import"]
}
You need to create a component called load
with the following
codes:
export default const load = (platform="index") => componentName =>
import(`components/${componentName}/${platform}.js`);
Then use dynamic import with loading function like the following code:
const { Button } = await import("components/Loader.jsx").then(load => {
load(${platform})(${componentName})
})
These articles may help you:
https://medium.com/front-end-weekly/webpack-and-dynamic-imports-doing-it-right-72549ff49234
https://blog.jscrambler.com/how-to-make-your-app-faster-with-webpack-dynamic-imports/
Upvotes: 5
Reputation: 801
There are two different ways you can achieve this.
require/import
the Mobile code inside loadMobile()
webpack automatically splits the code into 2 bundles. The mobile bundle is loaded only if it is necessary.Upvotes: 0