繁体   English   中英

React/Typescript 无法将 svg 文件作为组件导入

[英]React/Typescript cannot import svg file as component

在 React/Typescript/Webpack 5 项目中导入 svg 时出现此错误:

Cannot find module '../path' or its corresponding type declarations.

然后我补充说:

declare module '*.svg' {
    import * as React from 'react';

    export const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement> & { title?: string }>;

    const src: string;
    export default src;
}

custom.d.ts文件。 如果我使用 svg 作为图像src ,它将起作用。 但我需要使用 svg 作为 ReactElement,因为我需要根据用户点击来更改其内容。

我尝试将 svg 导入为

import DislikeIcon from '../../media/icons/dislike.svg';

const Component = () => (<> <DislikeIcon /> </>)

然后我收到了这个错误:

<data:image/svg... /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.

然后我尝试了:

import { ReactComponent as DislikeIcon } from '../../media/icons/dislike.svg';

并得到:

Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

我的 webpack.config.js 文件

module.exports = {
    ...
    module: {
        rules: [
            {
                test: /\.[jt]sx?$/,
                use: ['babel-loader'],
                exclude: /node_modules/,
            },
            {
                test: /\.scss$/,
                exclude: /node_modules/,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader'],
            },
            {
                test: /\.svg$/,
                loader: 'url-loader',
            },
            {
                test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
                type: 'asset/resource',
            },
            {
                test: /\.(woff(2)?|eot|ttf|otf)$/,
                type: 'asset/inline',
            },
        ],
    },
    ...
};

我的 custom.d.ts 文件:

declare module '*.png' {
    const value: string;
    export = value;
}
declare module '*.jpg' {
    const value: string;
    export = value;
}
declare module '*.svg' {
    import * as React from 'react';

    export const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement> & { title?: string }>;

    const src: string;
    export default src;
}

我的 tsconfig.json 文件:

{
    "compilerOptions": {
      "target": "ES5",
      "module": "ESNext",
      "moduleResolution": "node",
      "lib": [
        "DOM",
        "ESNext"
      ],
      "jsx": "react-jsx",
      "noEmit": true,
      "isolatedModules": true,
      "esModuleInterop": true,
      "strict": true,
      "skipLibCheck": true,
      "forceConsistentCasingInFileNames": true,
      "resolveJsonModule": true,
      "allowJs": true,
      "checkJs": true,
    },
    "include": ["src/**/*", "./custom.d.ts"],
    "exclude": ["node_modules", "build"],
  }

我搜索了很多答案,但每个人都说类似的话。 这花费了我没有的时间。 有人有什么建议吗?

感谢您的关注!

我在这里找到了解决方案: https://duncanleung.com/typescript-module-declearation-svg-img-assets/感谢( Duncan Leung )解决方案是创建一个./src/@types/assets/ index.d.ts TypeScript 媒体资产的模块声明文件。

关于 TypeScript 模块声明文件的一个主要问题是如何使用 typeRoots 属性将它们包含在 tsconfig.json 中。

属性 typeRoots 定义将包含类型声明的类型文件夹,但 index.d.ts 模块声明文件必须位于子文件夹中,因为 typeRoots 下的每个子文件夹都被视为“包”并添加到您的项目中。

我们错误地尝试将 .svg 模块声明放在 ./src/@types/index.d.ts 下。

将 index.d.ts for.svg 文件移动到它自己的./src/@types/assets 子文件夹允许 TypeScript 正确识别 .svg 模块声明。

./src/@types/assets/index.d.ts

declare module "\*.svg" {
  import React = require("react");
  export const ReactComponent: React.SFC<React.SVGProps<SVGSVGElement>>;
  const src: string;
  export default src;
}

declare module "\*.jpg" {
  const content: string;
  export default content;
}

declare module "\*.png" {
  const content: string;
  export default content;
}

declare module "\*.json" {
  const content: string;
  export default content;
}

这是一个示例 tsconfig.json:

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "target": "es5",
    "module": "esnext",
    "types": ["node"],
    "moduleResolution": "node",
    "esModuleInterop": true,
    "typeRoots": ["./src/@types", "./node_modules/@types"],
    "lib": ["dom", "es2015", "es2017"],
    "jsx": "react",
    "sourceMap": true,
    "strict": true,
    "resolveJsonModule": true,
    "noUnusedLocals": true,
    "noImplicitAny": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "allowSyntheticDefaultImports": true,
    "downlevelIteration": true,
    "baseUrl": "./",
    "paths": {
      "~/*": ["src/*"],
      "@turn/styled": ["src/styled"]
    }
  },
  "include": ["./src/**/*", "./test-utils/**/*", "./__mocks__/**/*"],
  "exclude": ["node_modules"]
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM