Webpack和Typescript图像导入

Cos*_* SD 25 typescript reactjs webpack

我正在使用React应用程序并使用WebpackTypescript.我想在其中一个<img/>标签中使用图像.但是,我没有找到正确的方法来访问图像文件.

webpack.config.js:

 ...
 module: {
        rules: [
            ...
            {
                test: /\.(png|jpe?g|svg)$/,
                loader: 'file-loader',
                options: {
                    name: 'assets/[name].[ext]',
                }
            }
        ]
Run Code Online (Sandbox Code Playgroud)

app.tsx:

...
render() {
    return <img src='/assets/logo-large.png' alt="logo"/>
}
Run Code Online (Sandbox Code Playgroud)

运行应用程序时,assets/logo-large.png找不到资源.

Eri*_*ngs 22

或者,在custom_typings文件夹中(如果有),可以添加新import-png.d.ts文件:

declare module "*.png" {
  const value: any;
  export default value;
}
Run Code Online (Sandbox Code Playgroud)

所以你可以使用以下方法导入图像:

import myImg from 'img/myImg.png';
Run Code Online (Sandbox Code Playgroud)

或者,正如@ mario-petrovic所报告的那样,您有时需要使用不同的导出选项,如下所示(export = syntax).请参阅此处了解两种方法之间的差异:

declare module "*.png" {
  const value: any;
  export = value;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您可能需要将图像导入为:

import * as myImg from 'img/myImg.png';
Run Code Online (Sandbox Code Playgroud)

  • 只是为了补充这个答案.我用这个解决方案尝试了它并没有用.我在这里提出了问题:/sf/ask/3577028101/#51156173.问题是编译时错误.当您将`export default value`更正为`export = value`时,您将获得正确的类型检查并且它将起作用.感谢您提出最终解决方案. (2认同)
  • 如果您像我一样遇到这个问题,并认为为声明创建新文件的部分是一个不重要的细节,请阅读[这个旧问题](https://github.com/microsoft/TypeScript/issues/28097 )并了解为什么需要一个单独的文件来使“declare”生效。 (2认同)

小智 19

设置 Webpack 文件加载器,添加 declaration.d.ts,瞧!

在花了一些时间找出解决方案之后,这就是我所做的......

第1步

确保您已安装file-loader为开发依赖项

npm install -D file-loader, 如果你使用纱线 yarn add -D file-loader

第2步

在Webpack规则中添加文件扩展名对应的loader webpack.config.js,像这样

module: {
    rules: [
      ...,
      {
        test: /\.(png|jpe?g|gif|jp2|webp)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[ext]',
        },
      },
    ],
  },

Run Code Online (Sandbox Code Playgroud)

第 3 步

index.d.ts在您的文件旁边创建一个文件tsconfig.json,实际上您可以随意命名它,但您必须遵循第 4 步。

由于 Webpack 现在将处理多个图像扩展,因此您可以添加file-loader支持的其他图像格式

declare module '*.png';
declare module '*.jpg';
Run Code Online (Sandbox Code Playgroud)

第四步

转到您的tsconfig.json文件并添加index.d.ts到包含数组,如下所示:

{
  "compilerOptions": {
    ...,
    "jsx": "react",
    "esModuleInterop": true,
    "target": "ES2020",
    "moduleResolution": "node"
  },
  "exclude": ["node_modules", "**/*.spec.ts", "**/*.test.ts"],
  "include": ["src", "index.d.ts"] /// <-- Like this!!
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果您尚未定义include数组,则默认情况下打字稿会将所有文件添加到根文件夹中,如果您只定义一个文件而不是包含所有代码的文件,则它不会编译。我认为将所有代码放在 src 文件夹中是一个好习惯。

瞧!!


ahs*_*tro 15

您需要require图像,然后使用该变量作为源,如下所示:

// At the top of the file, with all other imports/requires
const imageSrc = require('/assets/logo-large.png')

...

render() {
    return <img src={String(imageSrc)} alt="logo"/>
}
Run Code Online (Sandbox Code Playgroud)


Bra*_*ler 5

对于Webpack 5,有内置的Assets Modules加载器替换旧的加载器。

如果您要升级,请确保您没有加载资源两次。如果是,您可以将资产模块类型设置为javascript/auto,如下所示:

{
  test: /\.(png|jpg|gif)$/i,
  use: [
     {
       loader: 'url-loader',
       options: {
         limit: 8192,
       }
     },
   ],
   type: 'javascript/auto'
}
Run Code Online (Sandbox Code Playgroud)

如果您从新的 webpack 配置开始,则不再需要安装任何加载器,也不再需要在配置中使用它们。只需按照@Carlos提到的步骤操作,跳过步骤#1并将步骤#2中的代码替换为以下内容:

rules: [ 
  {
    test: /\.(png|jpe?g|gif|jp2|webp)$/,
    type: 'asset/resource'
  },
//further sexiness
]
Run Code Online (Sandbox Code Playgroud)

  • @SamSverko我想也许由于某种原因未能注册 png 文件的模块声明?在我的工作项目中,我可以使用上面的 webpack 配置,前提是我的根项目目录中存在一个“index.d.ts”,并带有以下模块声明: ```declare module "*.png"; ```` (2认同)