Webpack5 在 运行 时无法编译图像并引发错误

Webpack5 is unable to compile images while is running and raise an error

我正在使用 webpack5 配置来 运行 一个 React 存储库,除了加载图像之外一切似乎都工作正常,我有一个我不明白的错误:

ERROR in ./src/assets/styles/main.scss
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleNotFoundError: Module not found: Error: Can't resolve 'file-loader' in '/Users/user.user/Desktop/react-boilerplate-master'

我已经尝试重新安装 mini-css-extract-plugin 但是没有用,不确定这里可能是什么问题。

这是 webpack 配置:

const webpack = require('webpack');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

const {
  NODE_ENV: nodeEnv = 'development'
} = process.env;
const devMode = nodeEnv !== "production";
const pkg = require("./package.json");

module.exports = {
  entry: {
    app: "./src/index.js",
    vendor: Object.keys(pkg.dependencies)
  },
  output: {
    filename: devMode ? "[name].js" : "[name].[hash].js",
    path: path.resolve(__dirname, "dist"),
    chunkFilename: devMode ? "[name].js" : "[name].[chunkhash].js",
    publicPath: "/"
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
        commons: {
          test: /[\/]node_modules[\/]/,
          chunks: "all"
        }
      }
    }
  },
  devServer: {
    historyApiFallback: {
      index: "/index.html",
      port: 3001
    }
  },
  watchOptions: {
    poll: true
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: {
          loader: "babel-loader"
        }
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[path][name].[ext]?[contenthash]',
              outputPath: 'images/',
            },
          },
        ],
      },
      {
        test: /\.(woff(2)?|ttf|eot|otf|svg)(\?v=\d+\.\d+\.\d+)?$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              outputPath: "fonts/",
            },
          },
        ],
      },
      {
        test: /\.scss|css$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: { url: false }
          },
          {
            loader: "sass-loader",
            options: {
              sassOptions: {
                includePaths: ["src/styles/"]
              }
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({
      filename: devMode ? "[name].css" : "[name].[hash].css",
      chunkFilename: devMode ? "[id].css" : "[id].[hash].css"
    }),
    new HtmlWebpackPlugin({
      filename: "index.html",
      chunks: ["vendor", "app"],
      template: path.join(__dirname, "public", "index.html")
    }),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(nodeEnv),
      'process.env.API_PATH': JSON.stringify(process.env.API_PATH)
    })
  ]
};



and the package.json scripts:

``` "scripts": {
    "start": "./node_modules/webpack/bin/webpack.js --mode development",
    "build": "./node_modules/webpack/bin/webpack.js --mode production",
    "start:watch": "./node_modules/webpack/bin/webpack.js --mode development --watch",
    "dev": "webpack serve --mode development --open",
    "test": "./node_modules/jest/bin/jest.js --env=jsdom",
    "test:watch": "./node_modules/jest/bin/jest.js --watch --env=jsdom --verbose",
    "test:watch:log": "TERM=dumb ./node_modules/jest/bin/jest.js --watch --env=jsdom --verbose",
    "coverage": "npm test -- --coverage",
    "eslint": "eslint ./src",
    "profile": "./node_modules/webpack/bin/webpack.js --profile --json > stats.json",
    "profile:analyze": "./node_modules/.bin/webpack-bundle-analyzer ./stats.json"
  },```

[![enter image description here][1]][1]


  [1]: https://i.stack.imgur.com/AZH7s.png

看来我可以使用上述设置重现您的问题。在 webpack 5.

中使用 file-loader 很可能是个问题

基本上 webpack 敦促使用 asset module 以支持像 file-loader 这样的传统加载程序。

简而言之,如果您将 file-loader 替换为资产模块,它应该可以正常工作:

{
  test: /\.(png|jpg|gif|svg)$/,
  type: 'asset/resource',
  // use: [
  //   {
  //     loader: 'file-loader',
  //     options: {
  //       name: '[path][name].[ext]?[contenthash]',
  //       // outputPath: 'images/',
  //     },
  //   },
  // ],
},