Webpack: How can I combine two completely separate bundles using dynamic bundling
Did I understand you correctly: you have essentially got
- a library of custom React components (built by Webpack build #1)
- a React app that needs to use some (all) of these components (built by Webpack build #2, totally separate from #1)
?
If yes, then read on.
The "Is this possible in react?" question should instead be "Is this possible in Webpack?", and the answer is "Yes". The following is tested with Webpack 2, but should also work with v.1.
Let's call your projects Lib
(your React component library) and App
(the library consumer).
In the Lib
project:
Create an entry point file, say
index.js
, that exports all the custom React components like this:import {Button} from './button';import {DatePicker} from './DatePicker';import {TextBox} from './textBox';export const MyComponentLib = { Button, DatePicker, TextBox};
Update
webpack.config.js
to make the project's bundle a UMD library (could also be 'var'), and set the entry point to the aboveindex.js
file. Doing so will make your library available via a global variable namedMyComponentLib
(the name comes from theexport
above) in the consuming app later on:... output: { path: './dist', filename: 'mylib.bundle.js', libraryTarget: 'umd' }, ... entry: './index.js', ...
On to the App
project:
In the
index.html
file you will have two<script>
tags: one formylib.bundle.js
(the output of theLib
project), and another for the bundle of theApp
project itself. You might have more bundles (app, vendor etc.), I'm just simplifying things here.Update
webpack.config.js
to mark the component library as external dependency. Here,MyComponentLib
is, again, the name of the global variable the library is available at, andmyComponents
is the name to use inimport
statements:...externals: { myComponents: 'MyComponentLib'}, ...
Now, in App
you can import a component like this:
import {DatePicker} from 'myComponents';
This will dynamically load DatePicker from the component library at run time via the global variable.
Bonus: if you use eslint
, you don't want it to complain about missing modules that you know are external; add this to your .eslintrc
:
..."settings": { "import/core-modules": ["myComponents"]},...