DZHAMBULAT-SAMOUCHKA
@DZHAMBULAT-SAMOUCHKA
Frontend разработчик

Почему Webpack не вставляет правильные пути для картинок?

Здрасте! У меня есть проект на react с webpack. Во время работы webpack-dev-server все картинки загружаются, и всё хорошо работает. Но когда я выполняю команду npm run build и запускаю сборку, то пути для картинок webpack подставляет неверные, из-за чего возникают ошибки 404. В css файлах картинки загружаются при запуске и webpack-dev-server, и сборки. Пути для картинок я вставляю в виде строки. Пример:

const Head = ({ className }) => {
  return (
    <div className={classNames(classes.head, {}, [className])}>
      <Button className={classNames(classes.shareBtn)} circle theme='clear'>
        <img src='images/share.svg' alt='share' />
      </Button>
    </div>
  )
}

export default Head


Все асеты у меня подгружаются из папки public в корне проекта. public папка содержит две подпапки images и fonts. Сам исходный код находится в папке src которая тоже в корне.

webpack
import webpack from 'webpack'
import { IWebpackConfig } from './types/config'
import { webpackLoaders } from './webpackLoaders'
import { webpackResolver } from './webpackResolvers'
import { webpackPlugins } from './webpackPlugins'
import type { Configuration as DevServerConfiguration } from 'webpack-dev-server'
import { webpackDevServer } from './webpackServer'

export default ({ mode, port, paths, isDev, isProd, analyze }: IWebpackConfig): webpack.Configuration => {
  return {
    mode: mode ?? 'development',
    entry: paths.entry,
    output: {
      filename: '[name].[contenthash].js',
      path: paths.output,
      clean: true
    },
    module: {
      rules: webpackLoaders({ mode, port, paths, isDev, isProd })
    },
    plugins: webpackPlugins({ mode, port, paths, isDev, isProd, analyze }),
    resolve: webpackResolver({ mode, port, paths, isDev, isProd }),
    devtool: isDev ? 'inline-source-map' : false,
    devServer: webpackDevServer({ mode, port, paths, isDev, isProd })
  }
}


webpack resolve
import { ResolveOptions } from 'webpack'
import { IWebpackConfig } from './types/config'

export const webpackResolver = ({ paths }: IWebpackConfig): ResolveOptions => {
  const resolve = {
    extensions: ['.tsx', '.ts', '.js'],
    modules: [paths.src, 'node_modules'],
    mainFiles: ['index'],
    preferAbsolute: true,
    alias: {
      '*': paths.src
    }
  }
  paths.public && resolve.modules.push(paths.public)
  return resolve
}


webpack loaders
import { IWebpackConfig } from './types/config'
import webpack from 'webpack'
import MiniCssExtractPlugin from 'mini-css-extract-plugin'

export const webpackLoaders = ({ isDev, isProd }: IWebpackConfig): webpack.RuleSetRule[] => {
  const babelLoader = {
    test: /\.(js|jsx|tsx)$/,
    exclude: '/node_modules/',
    use: {
      loader: 'babel-loader',
      options: {
        presets: ['@babel/preset-env']
      }
    }
  }
  const tsLoader = {
    test: /\.tsx?$/,
    use: 'ts-loader',
    exclude: '/node_modules/'
  }
  const cssLoader = {
    test: /\.css$/i,
    use: ['style-loader', 'css-loader'],
    exclude: '/node_modules/'
  }
  const sassLoader = {
    test: /\.s[ac]ss$/,
    use: [
      isProd ? MiniCssExtractPlugin.loader : 'style-loader',
      {
        loader: 'css-loader',
        options: {
          modules: {
            auto: (resPath: string) => Boolean(resPath.includes('.module.')),
            localIdentName: isDev ? '[name]_[local]--[hash:base64:6]' : '[hash:base64:8]'
          }
        }
      },
      'sass-loader'
    ],
    exclude: '/node_modules/'
  }
  const assetImages = {
    test: /\.(png|svg|jpg|jpeg|gif|ico)$/i,
    type: 'asset/resource',
    generator: {
      filename: 'static/[hash][ext]'
    }
  }
  const assetFonts = {
    test: /\.(woff|woff2|eot|ttf|otf)$/i,
    type: 'asset/resource',
    generator: {
      filename: 'static/[hash][ext]'
    }
  }

  return [babelLoader, tsLoader, assetImages, assetFonts, cssLoader, sassLoader]
}


webpack plugins
import { IWebpackConfig } from './types/config'
import webpack from 'webpack'
import HtmlWebpackPlugin from 'html-webpack-plugin'
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'

export const webpackPlugins = ({ paths, isProd, analyze }: IWebpackConfig): webpack.WebpackPluginInstance[] => {
  const result: any[] = [
    new HtmlWebpackPlugin({
      template: paths.html
    }),
    isProd
      ? new MiniCssExtractPlugin({
          filename: 'css/[name].[contenthash:8].css',
          chunkFilename: 'css/[name].[contenthash:8.css]'
        })
      : undefined,
    new webpack.ProgressPlugin(),
    analyze &&
      new BundleAnalyzerPlugin({
        openAnalyzer: false
      })
  ]

  return result
}
  • Вопрос задан
  • 109 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы