nest中使用svg的一种模式

介绍

  1. nest中没法使用变量形式集体引入图标(非public中资源),所以说本文是在一个文件里面集体引用的。然后对此进行了代码简洁处理,支持模块多元化。

实现流程

  1. 下载相关依赖
npm i @svgr/webpack@7.0.0 -D
  1. next.config.js中配置
const nestConfig = {
  // ... 其他配置项
  webpack: (config) => {
    const { options: loaderOptions } = config.module.rules.find(
      (rule) => rule.test && rule.test.test('.svg')
    );
    config.module.rules.push({
      test: /\.svg$/i,
      issuer: /\.[jt]sx?$/,
      resourceQuery: { not: [/url/] },
      use: [
        {
          loader: '@svgr/webpack',
          options: {
            svgoConfig: {
              plugins: [
                {
                  name: 'removeViewBox',
                  active: false,
                },
                {
                  name: 'prefixIds',
                },
              ],
            },
          },
        },
      ],
    });
    config.module.rules.push({
      test: /\.svg$/i,
      issuer: /\.[jt]sx?$/,
      resourceQuery: /url/,
      loader: 'next-image-loader',
      options: loaderOptions,
    });

    return config;
  },
}
  1. 全局svg组件代码(如果需要js模式的,可以评论留言)
import { chakra, ChakraStyledOptions } from '@chakra-ui/react';
export const SvgIcon = <
  T extends { [key: string]: { default: any } }
>(
  svgImgsMap: T
) => {
  const typeList = Object.entries(svgImgsMap).reduce(
    (pre, [key, value]) => ({
      ...pre,
      // 这里我这边使用chakra-ui去把value.default这个组件格式话成 css-in-js模式了;如果没有使用chakra-ui只需要返回value.default即可
      [key]: chakra(value.default, {
        baseStyle: { fill: 'var(--blaze-base-color)' },
      }),
    }),
    {} as any
  );

  type IconSvgBatchProps = { type: keyof T } & ChakraStyledOptions['baseStyle'];
  const IconSvgBatch = ({ type, ...props }: IconSvgBatchProps) => {
    const CurrentIcon = typeList[type] || (() => <></>);
    return <CurrentIcon {...props} />;
  };

  return IconSvgBatch;
};
  1. 局部svg组件代码(components/SvgIcon/Goods/index.tsx)
import * as iconSvg from './utils';
import { SvgIcon } from '@/src/components/common/SvgIcon';

const SvgIconGoods = SvgIcon(iconSvg);
export default SvgIconGoods;

  1. 局部svg的utils.ts文件(components/SvgIcon/Goods/utils.ts)
export * as testIcon from '@/src/assets/imgs/goods/test-icon.svg';
export * as nameIcon from '@/src/assets/imgs/goods/name-icon.svg';
export * as titleIcon from '@/src/assets/imgs/goods/title-icon.svg';
  1. 使用
import SvgIcon from '@/src/components/SvgIcon/Goods';

const Page = () => {
	return <> 
		<SvgIcon type="testIcon " />
		<SvgIcon type="nameIcon " />
		<SvgIcon type="titleIcon " />
	</>
}

最后(划重点)

  1. 如果有更好的实现方案可以探讨探讨

你可能感兴趣的:(js系列,react,组件库,前端)