'Individual component exports with Rollup instead of one massive index.js file?
I’m working on a proprietary component library built with React and using Rollup to bundle everything. Currently, it’s bundling everything into these files:
dist
├ cjs
│ └ index.js (1.7mb)
└ esm
└ index.js (1.7mb)
My hope is that I could instead have every component be bundled individually so the consuming app doesn’t have to download a huge index.js
file, but this may be where my inexperience with Rollup kicks in.
I currently have a single entrypoint for Rollup:
input: [
'src/index.js',
],
My index.js
file looks something like this (but with many more components):
import { Badge } from './components/Badge';
import { Button } from './components/Button';
import { CardFooter } from './components/CardFooter';
import { CardHeader } from './components/CardHeader';
import { CardTagList } from './components/CardTagList';
import { CardToolbar } from './components/CardToolbar';
import { CartAnimation } from './components/CartAnimation';
export {
Badge,
BasePrice,
Button,
CardFooter,
CardHeader,
CardTagList,
CardToolbar,
CartAnimation,
};
What do I have to do to ensure that components are each bundled separately and can still be imported in the apps that use the library with:
import { Button } from '@company/component-library';
Here is my full config as it stands today:
import { babel } from '@rollup/plugin-babel';
import { terser } from 'rollup-plugin-terser';
import commonjs from '@rollup/plugin-commonjs';
import dynamicImportVars from '@rollup/plugin-dynamic-import-vars';
import eslint from '@rollup/plugin-eslint';
import json from '@rollup/plugin-json';
import resolve from '@rollup/plugin-node-resolve';
import stylelint from 'rollup-plugin-stylelint';
import styles from 'rollup-plugin-styles';
require('dotenv').config();
export default {
external: [
'react',
'react-dom',
'styled-components',
],
input: [
'src/index.js',
],
output: [
{
// Bundle into ESM for modern consumers.
// Only ESM build can currently be tree-shaken.
dir: 'dist/esm',
format: 'esm',
},
{
// Bundle into CJS for other consumers.
dir: 'dist/cjs',
format: 'cjs',
},
],
plugins: [
eslint({
include: '**/*.js',
throwOnError: true,
}),
stylelint(),
babel({
babelHelpers: 'bundled',
exclude: 'node_modules/**',
}),
resolve({
browser: true,
}),
styles(),
commonjs(),
json(),
dynamicImportVars({}),
terser(),
],
};
Note: Probably not important, but this project is published to npm as a private repo, but currently the app that uses it installs it using a commit hash.
Solution 1:[1]
You could try adding the preserveModule
export default {
preserveModules: true,
...
}
Solution 2:[2]
I have done some tweek to the rollup config. My problem statement was to export custom elements seperately. Find my custom solution below:
function generateComponentConfig() {
const dir = fs.readdirSync("./src/web-components");
return dir.map(folderName => {
return {
input: [`src/web-components/${folderName}/index.js`],
output: [
{ file: `public/build/wc/${folderName}.mjs`, 'format': 'es' },
{ file: `public/build/wc/${folderName}.js`, 'format': 'umd', name: folderName }
],
plugins: [
svelte({ compilerOptions:{customElement: true}, emitCss: false, include: /\.wc\.svelte$/ }),
svelte({ compilerOptions: {customElement: false}, emitCss: false, exclude: /\.wc\.svelte$/ }),
resolve()
]
};
})};
Use the above function in your export as below
export default [
...generateComponentConfig(), {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/bundle.js',
},
plugins: plugins(),
watch: {
clearScreen: false,
}}];
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Dharman |
Solution 2 | Shivang Gupta |