无法在打字稿中导入 svg 文件
Posted
技术标签:
【中文标题】无法在打字稿中导入 svg 文件【英文标题】:Unable to import svg files in typescript 【发布时间】:2022-01-20 08:59:52 【问题描述】:在typescript(*.tsx)
文件中,我无法使用以下语句导入 svg 文件:
import logo from './logo.svg';
转译器说:[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 年,“自动配置”应该成为常态吗?
【参考方案1】:
对我来说,以上解决方案都不能单独工作。因为我在当前项目中没有使用 Webpack。
我调查了日志中的输出,然后以下方式对我有用,无需创建文件 (custom.d.ts)、更改配置或安装新依赖项:
const logo: string = require("../assets/images/logo.svg").default;
<img src=logo />
【讨论】:
【参考方案2】:在 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 文件。【参考方案3】:如果你使用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
【讨论】:
【参考方案4】: 如果您使用的是create-react-app 2+
:docs
添加一个具有正确类型的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)【参考方案5】:希望!这将对某人有所帮助。
实际上,我尝试了所有步骤,但我们必须了解一件事,您必须将 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
为了更好的想法:
【讨论】:
【参考方案6】:如果您使用的是 Create-React-App
启动器,请确保 react-app-env.d.ts
包含以下行:
/// <reference types="react-scripts" />
【讨论】:
这对我有用。还有一点我想指出,最直接的方法是将 create-react-app 与 typescript 模板一起使用,该模板为您配置项目并开箱即用地使用 svgs。【参考方案7】:你可以像create-react-app一样为svgs声明模块:
react-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【参考方案8】:
如果你使用 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.json 的include
部分。
谢谢!我知道它必须包含在某个地方,但我无法想象在哪里。即使我认为它在 tsconfig.json 中,但我不知道该怎么做。感谢您的评论。我搜索了一下,发现:"files": [ "custom.d.ts" ]
您可以通过输入以下内容对 JSX 组件进行类型检查:const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
是否可以让custom.d.ts
文件在全局范围内工作,以便SVG 可以位于与custom.d.ts
文件不同的目录中?我得到一个错误“找不到模块”,除非它在同一个目录中。
这不会在 Angular 中导入文件的内容,而是将文件名作为字符串导入。我需要内容。我们如何获取文件的内容?【参考方案9】:
要将 non-code assets 与 TypeScript 一起使用,我们需要延迟这些 imports 的类型。这需要一个 custom.d.ts 文件,该文件表示我们项目中 TypeScript 的自定义定义。
让我们为 .svg 文件设置一个声明:
custom.d.ts
declare module "*.svg"
const content: any;
export default content;
在这里,我们通过指定任何以 .svg 结尾的导入并将模块的内容定义为 any,从而为 SVG 声明一个新模块。
【讨论】:
【参考方案10】: // eslint-disable-next-line spaced-comment
/// <reference types="react-scripts" />
如果您使用的是 puglin slint,可能是因为他已禁用认为这是评论但不阅读 svg 您需要此类型脚本模块只需禁用该行并开心
【讨论】:
【参考方案11】:我找到的解决方案:在 ReactJS 项目中,在文件 react-app-env.d.ts 中,您只需删除注释中的空格,例如:
之前
// / <reference types="react-scripts" />
之后
/// <reference types="react-scripts" />
希望能帮到你
【讨论】:
对于使用 create-react-app 并配置了 eslint 的人来说,这样可以解决问题 我没有找到任何解释,但就我而言,它似乎有效。任何想法为什么? 这里解释了它的作用:***.com/questions/60628874/…【参考方案12】:我在尝试 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"
,
希望对某人有所帮助。
【讨论】:
【参考方案13】:我们已经实现了另一种方法:制作您的 SVG 组件。我这样做是因为它让我感到困扰,我在 import
s 旁边使用 commonJS require
语句。
【讨论】:
【参考方案14】:感谢smarx 指出使用require()
。所以在我的情况下应该是:
const logo = require("./logo.svg") as string;
在 *.tsx 文件中运行良好
【讨论】:
logo
最好命名为 logoPath
,因为它就是这样。
@DharmaTurtle 我认为这可以讨论。此外,它在问题中称为logo
,因此它是对这个特定问题的更好答案。
@DharmaTurtle 老实说,变量的名称是无关紧要的,为什么要分心这么琐碎的事情?
我喜欢这个答案而不是创建自定义配置规则。唯一的问题是,如果有任何副作用,这在生产构建中的效果如何?
无法完成这项工作——请澄清一下? ***.com/questions/65205211/…以上是关于无法在打字稿中导入 svg 文件的主要内容,如果未能解决你的问题,请参考以下文章