@SuchOP

Почему после сборки webpack'ом появляется битая картинка?

На картинке html файл до сборки, после обработки html-loader появляется битая картинка и итоговый html файл ссылается на её
60e6fb81555dd741483104.png

код вебпака

/* eslint-disable no-undef */
const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin');
const TerserPlugin = require("terser-webpack-plugin");

const isDev = process.env.NODE_ENV === 'development';
const isProd = !isDev;

const filename = (ext) => isDev ? `[name].${ext}` : `[name].[contenthash].${ext}`;

const optimization = () => {
  const configObj = {
    splitChunks: {
      chunks: 'all'
    }
  }
  
  if (isProd) {
    configObj.minimize = true;
    configObj.minimizer = [
      new TerserPlugin(),
      new CssMinimizerPlugin(),
    ]
  }
  
  return configObj;
}

const plugins = () => {
  const basePlugins = [
    new HTMLWebpackPlugin({
      template: path.resolve(__dirname, 'src/index.html'),
      filename: 'index.html',
      minify: {
        collapseWhitespace: isProd 
      },
    }),
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({
      filename: `./css/${filename('css')}`
    }),
    new CopyWebpackPlugin({
      patterns: [{
        from: path.resolve(__dirname, 'src/assets'),
        to: path.resolve(__dirname, 'app/assets')
      }]      
    }),
  ]
  
  if (isProd) {
    basePlugins.push(

      // <-- Image minimaizer here --> 
      
    )
  }

  return basePlugins
}

module.exports = {
  context: path.resolve(__dirname, 'src'),
  mode: 'development',
  entry: './js/main.js',
  output: {
    path: path.resolve(__dirname, 'app'),
    filename: `./js/${filename('js')}`,
  },
  devServer: {
    contentBase: path.resolve(__dirname, 'app'),
    compress: true,
    port: 9000,
    open: true,
    hot: true,
    historyApiFallback: true,
  },
  plugins: plugins(),
  devtool: isProd ? false : 'source-map',
  optimization: optimization(),
  module: {
    rules: [
      {
        test: /\.html$/,
        loader: 'html-loader',
      },
      {
        test: /\.s[ac]ss$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader", 'sass-loader'],
      },
      {
        test: /\.js/,
        exclude: /node_modules/,
        use: ['babel-loader'],
      },
      {
        test: /\.(?:|gif|png|jpg|svg)$/,
        use: [{
          loader: 'file-loader',
          options: {
            name: `./img/${filename('[ext]')}`
          }
        }],
      },
      {
        test: /\.(?:|woff|eot|woff2|ttf|otf|fnt|fon)$/,
        use: [{
          loader: 'file-loader',
          options: {
            name: `./fonts/${filename('[ext]')}`
          }
        }],
      },
    ],
  },
};
  • Вопрос задан
  • 942 просмотра
Решения вопроса 1
@SuchOP Автор вопроса
нашел решение и отказался от file-loader

было:
{
        test: /\.(?:|gif|png|jpg|svg)$/,
        use: [{
          loader: 'file-loader',
          options: {
            name: `./img/${filename('[ext]')}`
          }
        }],
      },


стало:
{
        test: /\.(?:|gif|png|jpg|svg)$/,
        type: 'asset/resource',
        generator: {
          filename: () => {
            return isDev ? 'img/[name][ext]' : 'img/[name].[contenthash][ext]';
          }
        }
      },
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Aetae
@Aetae Куратор тега JavaScript
Тлен
То, что файл ссылается на обработанную картинку - так оно и должно быть, в том и смысл loader'ов. А вот то, что она бьётся - может быть по разным причинам. Обычно такое происходит когда в цепочку loader'ов случайно встраивается левый. Чисто глядя на конфиг сложно что-то сказать, по хорошему нужен полноценный проект-пример на потыкать.
Навскидку разве чтоtest: /\.js/, бросается в глаза, так как нет $ в конце, а значит может цеплять лишнего, но по идее тогда babel должен ругаться...
Ответ написан
Комментировать
TheSnegok
@TheSnegok
const isDev = process.env.NODE_ENV === 'development';
const isProd = !isDev;
const filename = (ext) => isDev ? `[name].${ext}` : `[name].[contenthash].${ext}`;

Твой секрет в этих трёх строчках, оно переименовывает твоё изображение, можешь попробовать сделать вот так:
const filename = (ext) => isDev ? `[name].${ext}` : `[name].${ext}`;
Ответ написан
Ваш ответ на вопрос

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

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