reactjs - Er det mulig å bruke Vites glob-import for å dynamisk generere React-komponenter?


Jeg lager et komponentbibliotek, og jeg ønsker å legge til SVG-ikoner som individuelle komponenter som kan brukes av andre apper. Jeg bruker vite-plugin-svgr for å generere komponenter fra ikoner, og det ser ut til at det bygger dem vellykket, men det gjør det ikke ved byggetid, det skjer i nettleseren.

Jeg prøver å bygge opp et objekt for å eksportere alle ikonene fra en mappe.

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;

Iterasjonen og eksporten fungerer slik at jeg bare kan legge SVGene i en mappe, og deretter kan jeg se dem i Storybook. Men når jeg faktisk skal bygge komponentbiblioteket, blir ingen av ikonene eksportert. Det virker som om denne glob-importen faktisk blir kjørt av Vite ved kjøretid på en eller annen måte, men ikke under bygging.

Finnes det en god måte å dynamisk generere disse komponentene på slik at jeg bare kan legge SVG-er i en mappe og få komponentene generert?

Her er min Vite-konfigurasjon til referanse:

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'),
      },
    },
  },
}));

Svar #1

For meg gjorde dette susen:

const icons = import.meta.glob('src/static/icons/*.svg', {
  query: '?react',
  eager: true,
});

I tidligere versjoner av vite, kan det også være as: 'react' i stedet for query.

Så får jeg tilbake et objekt, og den første verdien ser slik ut:

Object { default: SvgIconPathToFile(props), … }

Dette kan gjengis som Jsx som vanlig.