使用 React、Typescript 和 Webpack 显示静态图像
Posted
技术标签:
【中文标题】使用 React、Typescript 和 Webpack 显示静态图像【英文标题】:Displaying a static image using React, Typescript and Webpack 【发布时间】:2017-11-02 21:01:15 【问题描述】:我正在尝试使用 webpack 和 webpack-dev-server 在 React 组件中显示图像作为项目的一部分。
到目前为止,我已经完成了以下步骤:
使用 npm 安装文件加载器 更新了 webpack.config.js 以添加图像文件的加载器 将我想要的图像导入到我的组件中 在我的 img 标签中使用了导入采取这些步骤后,webpack 无法编译并出现“找不到模块”错误:
ERROR in [at-loader] ./src/components/App.tsx:4:26
TS2307: Cannot find module '../images/kitten-header.jpg'.
我的文件夹结构如下:
/dist
/images
kitten-header.jpg
bundle.js
bundle.js.map
/node_modules
(content ignored for brevity)
/src
/components
App.tsx
/images
kitten-header.jpg
/styles
App.less
index.tsx
index.html
package.json
tsconfig.json
webpack.config.js
我添加到 webpack.config.js 的新加载器是:
test: /\.(jpe?g|gif|png|svg)$/, loader: "file-loader?name=./images/[name].[ext]"
我已经在 App.tsx 中导入了图像文件,如下所示:
import kittenHeader from '../images/kitten-header.jpg';
...并像这样在 img 标签中使用导入:
<img src= kittenHeader />
注意:提供了 webpack.config.js 和 App.tsx 的全文,直到我稍微接近答案并意识到它们不相关(请参阅更新 1)。
我假设我在导入的相对路径方面犯了一些非常微不足道的错误。如您所想,我尝试了各种替代方案。
谁能提供一些见解?
作为参考,由于我不断地点击与错误版本的 webpack 相关的文章和问题,以下是我的版本:
反应 15.5.4 Webpack 2.6.1 Webpack-dev-server 2.4.5 TypeScript 2.3.2更新 1: 2017.06.05 所以,看看this SO question 和this post on Medium,我已经能够确定问题不在于我如何使用 webpack,而在于我使用的是 TypeScript。该错误是由于打字稿编译器不知道 .jpg 文件是什么而导致的打字稿错误。
显然,我需要提供一个 d.ts 文件或使用 require 语句。
差不多了……
【问题讨论】:
您是否有我们可以用来重现问题的源存储库?那会很方便。 如果你使用 webpack,你可以安装@types/webpack-env
代替 require
而不是 import
。与导入不同,您传递给 require
的字符串不会被 TypeScript 解析。当然,使用*.d.ts
也可以
谢谢@EvanSebastian,你的评论就在我写答案的时候出现了。如您所见,我的答案不完整。你知道如何为 jpg 写一个 d.ts 吗?是否可以创建一个模块来覆盖 *.jpg 或者每个图像文件都需要一个 d.ts?
我还注意到你推荐了@types/webpack-env
,而我使用了@types/node
。节点类型确实有效。在获得“要求”工作方面,这两者有什么区别?我假设它们只是相同底层“要求”实现的两个 d.ts 定义?
@types/webpack-env
和 @types/node
是不同的,当您需要编写 NodeJS 模块以使标准库类型可用时,您使用 @types/node
。 @types/webpack-env
用于 webpack 捆绑项目中。例如,如果您使用 @types/webpack-env
,require.ensure
将可用
【参考方案1】:
对于常规 require,这是我在 tsx 文件中使用它的方式:
const logo = require('../assets/logo.png');
...
<img alt='logo' style= width: 100 src=String(logo) />
希望这会有所帮助。 import
ing 对我也不起作用。
【讨论】:
【参考方案2】:这就是我的工作方式:
// This declaration can be move in some common .d.ts file, will prevent tslint from throwing error
declare function require(path: string);
const SampleComponent = () => (
<div>
<img src=require('./styles/images/deadline.png') />
</div>
);
您在答案中提出的方式最终将为放置在组件中的每个图像文件编写模块声明。
【讨论】:
【参考方案3】:错误 TS2307: Cannot find module '../images/kitten-header.jpg'
突出显示 TypeScript 编译器不理解 .jpg 文件的导入。
webpack 配置很好,尽管出现编译错误,但图像文件被成功复制到 dist 文件夹就证明了这一点。
我们可以通过两种方式解决此问题。
首先,我们可以通过使用“require”语句绕过 TypeScript 导入。为此,导入...
import kittenHeader from '../images/kitten-header.jpg';
...可以替换为 require...
const kittenHeader = require('../images/kitten-header.jpg');
...这就是我们所需要的。
注意,在我的情况下,我还需要安装一些类型来支持“require”语句。如果没有这些,我会收到 TS2304: Cannot find name 'require'
错误。
最初我使用@types/node
,如this SO answer 中所述,但@EvanSebastian 指出node 旨在支持编写NodeJS 模块,这不是我正在做的事情(参见问题上的cmets)。
我按照建议尝试了@types/webpack-env
,但这导致我的图像标签的 src 属性出现TS2322: Type ' src: ; ' is not assignable to type 'HTMLProps<HTMLImageElement>'.
错误。
最近,我转而使用@types/requirejs
,我希望它足够专注以避免包含大量不适当的附加类型。它目前正在运行:
npm install @types/requirejs --save-dev
或者,我们可以保留导入并提供d.ts
文件,其中包含声明适当模块的类型信息。我无法确切地发现这个文件的样子。
【讨论】:
【参考方案4】:除了 mcku 的回答之外,您还可以通过这种方式使用导入:
// @ts-ignore
import * as kittenHeader from '../images/kitten-header.jpg';
...
<img alt='logo' style= width: 100 src=logo />
尽管您必须忽略警告。
【讨论】:
【参考方案5】:在您的 src 目录中的任何位置添加一个打字稿定义文件,并(将其命名为 image.d.ts) 像这样导出 jpeg 文件的模块定义:
export module "*.jpg";
【讨论】:
【参考方案6】:在你想要的任何 React-Typescript 组件中尝试我的代码
import * as logo from './assests/icon.jpg';
const img = logo.default;
const Comp = ()=>
return <img src=img className="" />
【讨论】:
仅代码答案是不明智的。【参考方案7】:
const logo = require('../../../assets/img/logo.svg')
<img src=logo.default style= width: "100%", height: "50px" />
【讨论】:
考虑添加对代码的解释,以帮助读者理解它如何解决问题。在用其他几个答案回答问题时,说明您的答案与其他答案有何不同或改进也很有用。以上是关于使用 React、Typescript 和 Webpack 显示静态图像的主要内容,如果未能解决你的问题,请参考以下文章
深入浅出TypeScript- 在React项目中使用TypeScript
TypeScript + React + Redux 实战简单天气APP全套完整项目
TypeScript React onChanged:尝试在共享点中执行 Web 部件时出错
如何在基于 Typescript 的 React Web 应用程序中具有参数的 Route 元素中传递其他道具