In this post, I will try to explain how to handle situations when you need to use Webpack with a lot of small apps that share one codebase.
If you want to jump straight to the code, check out my repository on GitHub.
NOTE: Despite the fact that this happened to me already five times, I still consider this as a not typical case. Perhaps I was just lucky.
This is what we’ll try to do:
I can talk a lot about how awesome Webpack is, but to do this I need a whole new post, so let’s focus on it and its configuration.
Imagine that you have two main folders:
apps folder contains 50 micro SAPs. To make things easier, we’ll call them widgets. Each widget is grouped by domain, thus one more level of nesting.
The folder structure may look like this, but it can be completely different:
And that is what we want to get:
The very first thing we need for bundling is to get a list of entry points. You can find some documentation about multiple entry points in Webpack here.
In our case entry points are these multiple
index.js files, from which your application starts functioning. Webpack’s multiple entry points object follows:
path_to_result_file_name is a path to the file we want to get as a result of bundling and
path_to_entry_point is a path to the file OR a module name which we want to bundle.
For example, assume we have the following configuration:
The result of the
webpack will be:
If you have a wtf-face, that’s fine.
In our case
[name] was resolved as a
./one/cool/stuff/bundle.js, the path relative to
path.join(__dirname, 'dist'). So webpack has written a file to
path.join(__dirname, 'dist') + './one/cool/stuff/bundle.js', what will result in
So, if we take our initial folder structure, then we can easily create the following entries:
Looks good and we already know what will be the result of running this.
The bad part is that in this case, all the shared stuff from
core and all the modules will be duplicated in each
bundle.js. To solve this problem and leave these bundles as slim as possible, we should add one more entry point and utilize one plugin:
If we want to extract our
core, we can write another entry point with name
core and use CommonsChunkPlugin one more time. If you want to know more about this plugin, you can check here.
Now we’re done with bundling things, but there is always “one more thing”.
The only thing I’d like to tell here is what you need to do to get all that cool functionality working with a webpack config as we have made earlier.
To start listening to the HMR plugin you have two options: use
--inline --hot, kind of Live Reload thing, or add two more items to each entry point:
Doing so enables HMR on each entry. But there is still one more thing to do. If you run Webpack Dev Server and try to change a file, you’ll see, that HMR expects the changes chunk to be available from the current folder, e.g.
http://localhost:8080/apps/weather/temperature/[hash].hot-update.json, what will result in 404 error because by default Webpack does this:
So the needed chunk is available from root path, not from the current directory. The default values are fine when you’re developing one app. But while we’re dealing with multiple apps, we need to override these settings by understanding where this chunk is:
You can check all default values here.
Don’t forget to extract CSS.
Instead of a conclusion, I’d like to say a few good words about Webpack.
“Just a tool” is great when it does dull and predictable things well. “The Tool” is great when you can use it in uncommon cases.
Although the documentation is meh, I really encourage you to read the sources, so you’ll get the whole picture of how it works and probably find more tricks.
If you know better ways of handling such cases, I’d love to see them in the comments. And don’t hesitate to share the post if you find it useful.
Why when it comes to more or less complex cases, each and every tutorial/boilerplate/template project is focused on just simple things?
One may say it’s up to a developer to find out what to do with his own complicated case. I agree, but I find the fact, that you have close to none information about dealing with this kind of stuff, really disappointing.
I made an example project on GitHub. Let me know in the comments’ section if it’s still unclear how to make things work.
A tip on how to fix issue when using connected React Router v4 and Redux in React
Want to use Elm in your project, but a bit hesitant going cold turkey? In this blog post I'll try to show how you can use the best from both worlds bulletproof Elm logic and ridiculously rich React components library.
I'm starting a new open-source project "Open RSS Reader" that will be modular app so if you don't like the existing clients, you'll be able to quickly build your own. It's gonna be both open source and free to use.
`pet` is a simple command-line snippet manager. It allows you to write and store snippets for the command-line, so you don't need to remember all the commands you frequently use in you terminal. It can sync your snippets to the GitHub Gist, so you can always take your snippets with you.