Home > OS >  Problems with images in react application
Problems with images in react application

Time:11-26

When using images in react, there is either a problem with typescript, or the image breaks on the site.

To solve the problem, I tried:

  1. Add url-loader and file-loader to the webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const BUILD_PATH = path.resolve(__dirname, './build');
const SRC_PATH = path.resolve(__dirname, './src/');
const PUBLIC_PATH = path.resolve(__dirname, './public')

module.exports = {
  entry: SRC_PATH   '/index.tsx',

  output: {
    path: BUILD_PATH,
    filename: 'bundle.js',
  },

  mode: process.env.NODE_ENV || 'development',

  resolve: {
    modules: [path.resolve(__dirname, 'src'), 'node_modules'],
    extensions: [ '.tsx', '.ts', '.js' ],
  },

  devServer: {
    static: PUBLIC_PATH,
  },

  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: ['babel-loader']
      },
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        loader: 'ts-loader'
      },
      {
        test: /\.(css|scss)$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
      },
      {
        test: /\.module.css$/,
        use: [
          {
            loader: "css-loader",
            options: {
              modules: true,
            },
          },
        ],
      },
      {
        test: /\.(jpg|png|svg)$/,
        loader: 'url-loader',
        options: {
          limit: 8192,
        },
      },
      {
        test: /\.(jpg|jpeg|png|gif|mp3|svg)$/,
        use: ['file-loader']
      },
    ],
  },

  plugins: [
    new HtmlWebpackPlugin({
      template: path.join(__dirname, 'public', 'index.html'),
    }),
  ],
};
  1. Import images as components
import React from 'react';

import logo from './header-logo.svg';

import styles from './Header.module.scss';

export const Header = () => {
  return <header className={styles.header}>
    <img src={logo} />
  </header>
};
  1. Create the images.d.ts file in the src/types directory
declare module "*.svg" {
  const content: any;
  export default content;
}
  1. And I even tried svgr..

But nothing helped. If I delete the images.d.ts file, typescript cannot detect the module when importing. When using images.d.ts, vscode does not show errors, but the picture is not displayed in the browser, and instead of the normal path, something strange data:image/svg xml;base64,ZXhwb3J0IGRlZmF1bHQgX193ZWJwYWNrX3B1YmxpY19wYXRoX18gKyAiZWMzYzM1Nzg3YTljZTMyMzE4M2NmMzM2Y2EzMDBkOTkuc3ZnIjs=

And just in case, I attach tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./build/",
    "noImplicitAny": true,
    "module": "es6",
    "target": "es5",
    "jsx": "react",
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "moduleResolution": "node",
    "plugins": [
      {
        "name": "typescript-plugin-css-modules"
      },
    ],
  },
}

I'm new to react so please don't judge strictly for stupid mistakes. I would appreciate any advice!

CodePudding user response:

You can use svg-url-loader npm module. in webpack.config,js

{
        test: /\.svg$/,
        use: [
          {
            loader: "svg-url-loader",
            options: {
              limit: 10000,
            },
          },
        ],
      },

in your component

// pass a correct path
import logo from './header-logo.svg';

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

CodePudding user response:

After some thought, I came to the conclusion that perhaps the problem occurred due to a loaders conflict. Leaving only the file-loader and deleting the url-loader, I was able to solve the problem. I hope my solution can help someone in the future.

My files now look like this:

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');

const SRC_PATH = path.resolve(__dirname, './src');
const BUILD_PATH = path.resolve(__dirname, './build');
const PUBLIC_PATH = path.resolve(__dirname, './public')

module.exports = {
  entry: SRC_PATH   '/index.tsx',

  output: {
    path: BUILD_PATH,
    filename: 'bundle.js',
  },

  mode: process.env.NODE_ENV || 'development',

  resolve: {
    modules: [SRC_PATH, 'node_modules'],
    extensions: [ '.tsx', '.ts', '.js' ],
  },

  devServer: {
    static: PUBLIC_PATH,
  },

  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: ['babel-loader']
      },
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        loader: 'ts-loader'
      },
      {
        test: /\.(css|scss)$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
      },
      {
        test: /\.module.css$/,
        use: [
          {
            loader: "css-loader",
            options: {
              modules: true,
            },
          },
        ],
      },
      {
        test: /\.(jpg|jpeg|png|gif|mp3|svg)$/,
        use: ['file-loader']
      },
    ],
  },

  plugins: [
    new HtmlWebpackPlugin({
      template: PUBLIC_PATH   '/index.html',
    }),
  ],
};

A imges.d.ts file for type resolution for typescript

declare module "*.jpg";
declare module "*.png";
declare module "*.svg";
  • Related