Webpack loader to lazy load your components, wrapping them into preloader component
Inspired by https://github.com/lavrton/Progressive-Web-App-Loading
npm install --save-dev react-async-component-loader
// HomePage.js
import HugeHeavyComponent from "react-async-component!./HugeHeavyComponent.js"
...
<HomePage>
<HugeHeavyComponent />
</HomePage>
It loads target module via bundle-loader with lazy
option.
The resulting chunk loader function is passed to a special component, which will call that function when mounted. And while chunk is loading, it will render a progress indicator of your choice.
It is passed directly to bundle-loader. Defines chunk name for your async module. Use it to group modules.
If not specified, each module goes to own chunk.
Example:
import MyComponent from "react-async-component?name=my-chunk!./MyComponent.js"
Path to module, containing your preloader indicator component.
If not specified, just a div with "Loading" text will be rendered.
Path is resolved in exactly same way as any other module in project, i.e., depending on your webpack config. Which means, you can refer either your custom component or some package from node_modules
– for example, use react-loader.
Example:
import MyComponent from "react-async-component?loader=./components/MySuperLoader!./MyComponent.js"
import MyComponent from "react-async-component?loader=react-loader!./MyComponent.js"
NOTE: On practice, unlikely you will use this inline option, as it's looks quite bad and hard to read. Also, unlikely you will ever have different preloaders for different modules, so you may want to once define a default preloader and forget about it. See how to do this below.
It is possible to define default options directly in webpack config.
For this, add asyncComponentLoader
section:
// webpack.config.js
module.exports = {
asyncComponentLoader: {
defaults: {
loader: String,
// Note, that by defining this, you will put all async modules
// with no explicit name specified to the same chunk
name: String,
},
},
}
On my view, this section should be used to define default preloader component, and module.loaders
section should be used to define name
parameter for specific modules.
Example:
// webpack.config.js
module.exports = {
module: {
loaders: [
{
test: /\/containers\/Profile/,
loader: "react-async-component",
query: {
name: "Profile",
},
},
{
test: /\/containers\/Inbox/,
loader: "react-async-component",
query: {
name: "Inbox",
},
},
],
},
asyncComponentLoader: {
defaults: {
loader: "react-loader",
},
},
}
You can't put same module in two different chunks, importing it with different name
option. Webpack knows that it's the same module, and the first chunk name it met will be used in all other cases.
I.e., with code like this:
// file1.js
import Component from "react-async-component?name=Foo!./Component";
// file2.js
import Component from "react-async-component?name=Bar!./Component";
// main.js
import "file1"
import "file2"
only Foo
chunk will be created, and both file1 and file2 will refer to it.
Same for name
, defined in module.loaders
: inline option will override it.