ChatGPT解决这个技术问题 Extra ChatGPT

无法在打字稿中导入 svg 文件

typescript(*.tsx) 文件中,我无法使用以下语句导入 svg 文件:

import logo from './logo.svg';

Transpiler 说:[ts] cannot find module './logo.svg'. 我的 svg 文件只是 <svg>...</svg>

但是在 .js 文件中,我可以使用完全相同的导入语句导入它而不会出现任何问题。我想它与 svg 文件的类型有关,必须以某种方式为 ts 转译器设置。

您能否分享如何在 ts 文件中进行这项工作?

svg 文件不是 javascript,不能像 javascript 模块那样使用。您应该改为使用 http 请求加载这些文件。
你在使用 Webpack 吗?这是我看到的唯一理解这种 import 语句的东西。也许 Webpack 是在你的 JavaScript 中允许这样做的,但它在 TypeScript 文件中并没有发挥同样的魔力。 (我不认为 TypeScript 本身知道在这里做什么。)
如果你使用 Webpack,你可能需要分享你的 Webpack 配置以获得更多帮助。
阅读更多关于此的内容,您可能可以执行 const logo = require("./logo.svg"); 或简单地忽略该错误。 (我相信 TS 仍然应该输出正确的代码。)
为什么,为什么 Webpack/React 必须使事情复杂化?使用 import 导入任何内容不是更简单吗?对于像我这样的新手,这些事情让我很沮丧。我们不是在 2020 年,“自动配置”应该成为常态吗?

N
Niket Pathak

如果你使用 webpack,你可以通过创建一个自定义类型文件来做到这一点。

创建一个名为 custom.d.ts 的文件,其内容如下:

declare module "*.svg" {
  const content: any;
  export default content;
}

custom.d.ts 添加到 tsconfig.json,如下所示

"include": ["src/components", "src/custom.d.ts"]

来源:https://webpack.js.org/guides/typescript/#importing-other-assets


您可能需要将其添加到 tsconfig.jsoninclude 部分。
谢谢!我知道它必须包含在某个地方,但我无法想象在哪里。即使我认为它在 tsconfig.json 中,但我不知道该怎么做。感谢您的评论。我进行了搜索,发现:"files": [ "custom.d.ts" ]
您可以通过键入以下内容对 JSX 组件进行类型检查:const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
是否可以让 custom.d.ts 文件在全局范围内工作,以便 SVG 可以位于与 custom.d.ts 文件不同的目录中?我得到一个错误“找不到模块”,除非它在同一个目录中。
在我将 *.d.ts 的名称更改为完全“custom.d.ts”之前,此解决方案最初对我不起作用。确保这是名称!
A
AngryBoy

感谢 smarx 指出使用 require()。所以在我的情况下应该是:

const logo = require("./logo.svg") as string;

在 *.tsx 文件中工作正常


logo 命名为 logoPath 可能更好,因为它就是这样。
@DharmaTurtle 我认为这可以讨论。此外,它在问题中称为 logo,因此它是对这个特定问题的更好答案。
@DharmaTurtle 老实说,变量的名称是无关紧要的,为什么要为这样一件微不足道的事情分心呢?
我喜欢这个答案而不是创建自定义配置规则。唯一的问题是,如果有任何副作用,这在生产构建中的效果如何?
无法完成这项工作 - 请澄清一下? stackoverflow.com/questions/65205211/…
A
Allenaz

如果您使用的是 create-react-app 2+:文档

添加具有正确类型的 custom.d.ts 文件(我在 src 目录的根路径上创建它)(感谢 RedMatt):

declare module '*.svg' {
  const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
  export default content;
}

安装 svg-react-loader 或一些 other,然后:

将其用作主要的 svg 加载器

或者,如果您正在迁移代码库并且不想接触工作部分 (JS),请在导入时指定加载程序:

import MySVG from '-!svg-react-loader!src/assets/images/name.svg'

然后只需将其用作 JSX 标签:

function f() { 
  return (<MySVG />); 
}

ESLint:意外的“!”在“-!svg-react-loader!src/assets/svg/bg.svg”中。不要使用 import 语法来配置 webpack 加载器。(import/no-webpack-loader-syntax)
j
jilvanx

我找到的解决方案:在 ReactJS 项目中,在文件 react-app-env.d.ts 中,您只需删除注释中的空格,例如:

// / <reference types="react-scripts" />

/// <reference types="react-scripts" />

我希望能帮助你


对于使用 create-react-app 并配置 eslint 的人,这可能会解决问题
我没有找到任何解释,但就我而言,它似乎有效。任何想法为什么?
下面是关于它的作用的解释:stackoverflow.com/questions/60628874/…
如果您使用 CRA 然后配置 eslint 或其他东西(在我的情况下为 vscode 格式)来格式化 react-app-env.d.ts 文件,这将是您的问题。由于间隔注释规则,它会将 /// 更改为 // /。您可以将其改回并添加忽略(/* eslint-disable spaced-comment */),您应该会很好
k
kimbaudi

您可以像 create-react-app 一样为 svgs 声明模块:

反应-app.d.ts

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

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

  const src: string;
  export default src;
}

source


我不明白。为什么它定义 export const ReactComponent 然后使用 export default src ?不应该是 export default ReactComponent 吗?
因为 CRA 在后台使用 SVGR 加载程序,它就是这样做的:npmjs.com/package/@svgr/webpack 另请参阅github.com/gregberge/svgr/issues/546
a
adstwlearn

我搜索了互联网寻找解决此问题的方法。这个 stackoverflow 问题排在首位,但没有一个答案对我有用。

最后,我能够通过尝试几种不同的技术来找到解决方案。

在项目的根目录中创建一个 ./globals.d.ts 文件,位于 ./tsconfig.json 所在的相同位置/级别。在该 ./globals.d.ts 文件中,添加以下内容:

declare module '*.svg' {
  const content: string;
  export default content;
}

这会正确地将 .svg 作为字符串导入,这是我在评分最高的 answer 中注意到的一个问题。

使用以下内容更新您的 tsconfig.json:

{
  "files": ["globals.d.ts"]
}

就是这样 - 这让它在我的情况下工作。我会注意 - 这是在 VanillaJS 应用程序中。


O
Oleksandr Danylchenko

如果您使用 Create-React-App 启动器,请确保 react-app-env.d.ts 包含以下行:

/// <reference types="react-scripts" />

这对我有用。还有一点我想指出,最直接的方法是使用带有 typescript 模板的 create-react-app,它为您配置项目并与 svgs 一起使用。
K
Kiran Mohan

我在尝试 REACT + typescript 教程时遇到了同样的问题。对我有用的是以下导入语句。

import * as logo from 'logo.svg'

这是我在 package.json 中的依赖项。

  "dependencies": {
    "react": "^16.8.4",
    "react-dom": "^16.8.4",
    "react-scripts-ts": "3.1.0"
  },

希望它可以帮助某人。


e
endymion1818

我们已经实现了另一种方法:制作您的 SVG 组件。我这样做是因为它让我觉得我在 import 旁边使用了 commonJS require 语句。


H
Hamidreza Soltani

没有 webpack 和 custom.d.ts 的解决方案

对我来说,上述解决方案都不是单独工作的。因为我在当前项目中没有使用 Webpack。

我调查了日志中的输出,然后以下方式对我有用,无需创建文件(custom.d.ts)、更改配置或安装新的依赖项:

const logo: string = require("../assets/images/logo.svg").default;

<img src={logo} alt="logo" />

对于 svg 格式,您需要添加 .default,但对于 png 格式则不需要。


B
Breno Melo
    // eslint-disable-next-line spaced-comment
/// <reference types="react-scripts" />

如果您使用的是 puglin slint,则可能是他已禁用,认为这是一条评论,但不阅读 svg,您需要此类型的脚本模块,只需禁用该行并开心


P
Premji

希望!这将帮助某人。

实际上,我尝试了所有步骤,但我们必须了解一件事,您必须将 custom.d.ts 文件创建到相应的 SVG 导入文件夹中。

ts 配置文件

{
  "compilerOptions": {
    "target": "ES6",
    "jsx": "react",
    "module": "ESNext",
    "moduleResolution": "Node",
    "baseUrl": "./",
    "paths": {
      "@components/*": ["src/components/*"],
      "@styles/*": ["src/styles/*"],
      "@static/*": ["src/static/*"]
    },
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "isolatedModules": true
  },
  "include": ["src/**/*", "src/static/optional.d.ts"],
  "exclude": ["node_modules", "build"]
}

可选的.d.ts

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

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

    const src: string;
    export default src;
}

最后是通用导出文件:

import Logo from './images/logo.svg';
import BellDot from './images/bell-dot.svg';
import Logout from './images/logout.svg';
import pageNotFound from './images/page-not-found.png';

export {
    Logo,
    BellDot,
    pageNotFound,
    Logout
}

为了更好的主意:

https://i.stack.imgur.com/6vhvm.png


E
Emad Armoun

在 CRA 应用程序中导入 SVG 文件

如果您想在 CRA 应用程序 (create-react-app) 中导入 SVG 文件,而不进行任何配置,您可以使用以下方法之一:

方法一

import { ReactComponent as MyIcon } from "./assets/images/my-icon.svg";
...
<MyIcon />

方法二

import myIconFileName from './assets/images/my-icon.svg';
...    
<img src={myIconFileName} />

是的,这种方法显然适用于 js 文件,但不适用于 ts(x) 文件!问题是在“TypeScrip”中导入 svg 文件。
c
cloxnu

如果您使用 webpack,请安装 svg-inline-loader,在 webpack.config.js 中添加模块:

{
    test: /\.svg$/,
    loader: 'svg-inline-loader',
}

它在构建后运行良好。

如果您的 IDE 报告交互错误,可以通过添加 //@ts-ignore 来解决:

//@ts-ignore
import logo from './logo.svg';

svg-inline-loader webpack docs


这是一个完美的解决方法,但不能解决问题。它只是隐藏了问题。查看其他解决方案,尤其是 stackoverflow.com/posts/45887328/revisions,它提供了一个示例,其中包含最终解决该问题的所有步骤。
J
Josh M.

对我来说,我必须在我的 tsconfig*.json 中包含 react-app-env.d.ts

  "include": [
    "src/Router.tsx",        // my main entry point
    "src/global.d.ts",       // global stuff
    "src/react-app-env.d.ts" // react global stuff
  ]

R
Robert

对我来说,当我将以下行放入 src/types/images.d.ts 时它起作用了

declare module '*.svg';

我正在通过以下方式导入图像

import { ReactComponent as WifiIcon } from '../../../assets/images/Wifi.svg';

在 tsconfig.json

我有以下编译器选项

"compilerOptions": {
    "typeRoots": ["node_modules/@types", "src/types"]
}

希望它可以帮助某人。我使用最新版本的 CRA。