I'm creating a component library, and I wish to add SVG icons as individual components to be consumed by other apps. I'm using vite-plugin-svgr to generate components from icons, and it seems like it's building them successfully, but it's not doing so at build time, it's doing it in the browser.
I'm trying to build up an object to export all of the icons from a folder.
const svgs: any = import.meta.glob('./assets/icons/*.svg', { eager: true });
const iconComponents: any = {};
for (const path in svgs) {
const component = svgs[path].ReactComponent;
const name: string = component.name.replace(/^Svg/, '') + 'Icon';
iconComponents[name] = component;
}
export default iconComponents;
The iteration and export works in that I can just put the SVGs in a folder, then I can view them in storybook. But when I go to actually build the component library, none of the icons are exported. It seems as though this glob import is actually executed by Vite at runtime somehow, but not on build.
Is there a good way to dynamically generate these components so that I can just put SVGs in a folder and have the components be generated?
Here's my vite config for reference:
import react from '@vitejs/plugin-react';
import { resolve } from 'path';
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
import tsConfigPaths from 'vite-tsconfig-paths';
import * as packageJson from './package.json';
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
import svgr from 'vite-plugin-svgr';
export default defineConfig(() => ({
plugins: [
cssInjectedByJsPlugin(),
svgr({
include: '**/*.svg'
}),
react(),
tsConfigPaths() as any,
dts({
include: ['src'],
}),
],
build: {
lib: {
entry: resolve('src', 'index.ts'),
name: 'red-mist',
formats: ['es', 'cjs'],
fileName: (format) => `my-lib.${format}.js`,
},
rollupOptions: {
external: [...Object.keys(packageJson.peerDependencies)],
input: {
index: resolve('src', 'index.ts'),
css: resolve('src', 'index.css'),
},
},
},
}));
For me, this did the job:
const icons = import.meta.glob('src/static/icons/*.svg', {
query: '?react',
eager: true,
});
In earlier versions of vite, it might also be as: 'react' instead of query.
Then I get back an object and the first value looks like this:
Object { default: SvgIconPathToFile(props), … }
This can be rendered as Jsx as usual.
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