I have a component library that is published to npm, and installed in other projects.
The library doesn't use dynamic imports. The components are exported in the library as follows:
import {
Component1
} from '@/modules/component1';
import {
Component2
} from '@/modules/component2';
import {
Component3
} from '@/modules/component3';
export {
Component1,
Component2,
Component3,
};
the components are imported as follows:
import {Component1, Component2} from 'myLibrary';
When building the component library, without any code splitting, it works properly, but the whole library is imported and affects the size of the page.
When using webpack's splitChunks
the main entry point of the library doesn't export the components, and exports show as undefined
.
As I understood splitChunks
works best in scenarios when using it with HtmlWebpackPlugin
to add script tags for all the chunks. This doesn't work in my case since I am building it as a library.
Also, I tried building each component as an entry point separately, but the files were still too big. When I used splitChunks
the file sizes were very convenient, but the components were not exported.
How should I achieve this? I want to split the library into multiple files but still being able to import it in my code and access all the exported components.
Note: The main goal of this is to reduce file size, this is bundled into a browser extension so network performance doesn't matter since the files are available offline.
While it's hard to give more concrete advice without seeing your library and how you bundle it. But usually, you don't want to do much of bundling and lazy loading on the library itself. Ideally, it should be just tree-shakable. What it means is bundler (webpack in your case) will include in final bundle only parts of library which you use in app. So if you import only
Component2
in your app, webpack will include onlyComponent2
itself and parts required for it to work (but notComponent1
orComponent3
). For your library to support this you need to do a bit of extra work. Webpack has guide about tree shaking which will be good starting point. I would also recommend to read about ESM vs CommonJS (for example this article) and make sure that webpack compiles your library into separate ESM files.And later in the app (browser extension in your case) you can optimize code splitting. This can be in for of pre-defined code chunks. For example, you could split your code in pre-defined
ui.js
(all ui related code like components) andlibs.js
(all other used libraries) chunks and then load only chunks you need (e.g.ui.js
won't be needed in background worker so no need to load it there). I used this approach for some time in my browser extension template, you can find example here.Alternatively, with a bit of tweaking webpack configuration you can make
import()
function work in extension context. In this case webpack will automatically optimize chunks so every entrypoint (popup / contentscript / background worker) will load a minimal amount of unnecessary code. I currently use this approach in my projects and very satisfied with the results (though it might not work in older browsers). You can find example configuration here or check this plugin.As additional bonus, you will be able to use dynamic import in your code, which allows you to lazy load parts of extension (though this will require adapting your app a bit) which also will reduce size of initial bundle.