I am trying to create a component library wie rollup and Vue that can be tree shakable when others import it. My setup goes as follows:
Relevant excerpt from package.json
{
"name": "red-components-with-rollup",
"version": "1.0.0",
"sideEffects": false,
"main": "dist/lib.cjs.js",
"module": "dist/lib.esm.js",
"browser": "dist/lib.umd.js",
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w"
},
"devDependencies": {
/* ... */
}
And this is my entire rollup.config.js
import resolve from "rollup-plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
import vue from "rollup-plugin-vue";
import pkg from "./package.json";
export default {
input: "lib/index.js",
output: [
{
file: pkg.browser,
format: "umd",
name: "red-components"
},
{ file: pkg.main, format: "cjs" },
{ file: pkg.module, format: "es" }
],
plugins: [resolve(), commonjs(), vue()]
};
I have a fairly simple project structure with an index.js
file and 2 Vue components:
root
∟ lib
∟ index.js
∟ components
∟ Anchor.vue
∟ Button.vue
∟ package.json
∟ rollup.config.js
My index.js
imports the Vue files and exports them:
export { default as Anchor } from "./components/Anchor.vue";
export { default as Button } from "./components/Button.vue";
export default undefined;
If I don't do export default undefined;
somehow any app importing my library cannot find any exports. Weird.
Now when I create another app and I import red-components-with-rollup
like so:
import { Anchor } from "red-components-with-rollup";
and I open the bundle from my app, I will also find the source code of the Button.vue
in my bundle, it has not been eliminated as dead code.
What am I doing wrong?
Tree-shaking is the process of analyzing the code files that are required to run your application and then including only code that is actually used by your application.
In webpack, tree shaking works with both ECMAScript modules (ESM) and CommonJS, but it does not work with Asynchronous Module Definition (AMD) or Universal Module Definition (UMD).
If you're using modern tooling, such as webpack, create-react-app and similars, you already have tree shaking set up. Tree shaking or dead code elimination means that unused modules will not be included in the bundle during the build process.
What is the build result of the ES format? Is it a single file or multiples, similar to your sources?
Considering your Rollup options, I’m guessing it bundles everything into a single file, which is most probably the reason it isn’t able to tree-shake it.
To keep your ES build into multiple files, you should change:
{ file: pkg.module, format: "es" }
Into:
{
format: "es",
// Use a directory instead of a file as it will output multiple
dir: 'dist/esm'
// Keep a separate file for each module
preserveModules: true,
// Optionally strip useless path from source
preserveModulesRoot: 'lib',
}
You’ll need to update your package.json
to point module
to the new build file, something like "module": "dist/esm/index.js"
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With