Webpack 4: mini-css-extract-plugin + file-loader无法加载资源

14

我试图移动一个.scss文件中使用的资源(图片和字体),但似乎它们被忽略了:

这是我的.scss文件:

@font-face {
    font-family: 'myfont';
    src: url('../../assets/fonts/myfont.ttf') format('truetype');
    font-weight: 600;
    font-style: normal;
}

body {
    color: red;
    font-family: 'myfont';
    background: url('../../assets/images/bg.jpg');
}

这是我的 webpack.config.js 文件:

const path = require('path');
const { CheckerPlugin } = require('awesome-typescript-loader');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    target: 'node',
    entry: path.resolve(__dirname, 'server.tsx'),
    output: {
        filename: 'server_bundle.js',
        path: path.resolve(__dirname, 'build'),
        publicPath: '/build'
    },
    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.jsx']
    },
    module: {
        rules: [{
                test: /\.(tsx|ts)?$/,
                loader: 'awesome-typescript-loader',
                options: {
                    jsx: 'react'
                }
            },
            {
                test: /\.(scss|sass|css)$/,                
                use: [
                    MiniCssExtractPlugin.loader,
                    { loader: 'css-loader', options: { url: false, sourceMap: true } },
                    { loader: 'sass-loader', options: { sourceMap: true } },                    
                ]
            },
            {
                test: /\.(png|svg|jpg|jpeg|gif)$/,
                loader: 'file-loader',
                options: { outputPath: 'public/images' }
            },
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                loader: 'file-loader',
                options: { outputPath: 'public/fonts' }
            }
        ]
    },
    plugins: [
        new CheckerPlugin(),
        new MiniCssExtractPlugin({
            filename: 'public/styles_bundle.css',
            chunkFilename: "public/styles/[id].css"
        })
    ]
}

我在浏览器中以这个图像的名称为输出结果,得到了这个.css文件:

body {
  color: red;
  background: url("../../assets/images/myimage.jpg"); 
}

在我的public目录中,我得到了这个:

public/
    styles_bundle.css

这里有两个问题:

  1. 字体未经编译 (没有 public/fonts/etc…)
  2. 图像未经编译

我已经尝试了很多方法,但是不知道这里可能出了什么问题……有任何想法吗?


1
在您的构建中,默认情况下会对图像名称进行哈希处理以启用缓存(https://webpack.js.org/guides/caching/)。要更改它,请在图像文件规则的选项中添加 name: 'images/[name][hash:8].[ext]' 属性(如果不想使用哈希,则删除 [hash:8])。 - mtx
如果您省略了 outputPath 选项会发生什么? - Slbox
还是没有成功 :( - danielrvt
@danielrvt 有什么解决方案吗? - Rohan Veer
很想看到这个问题的答案。 - quinn
令人难以置信的是,使用webpack加载器的已接受答案数量如此之少。似乎没有人知道发生了什么。 - cda01
6个回答

8

我刚刚解决了一个类似的问题。如果你将 url 选项设置为 true,可能会看到图片 URL 引用失败。

{ loader: 'css-loader', options: { url: false, sourceMap: true } },

或者手动检查路径引用是否正确。

url('../../assets/images/bg.jpg')

我认为图像文件夹没有被创建是因为所有的图像资源链接都不正确。

对于我正在解决的问题,所有的引用都是错误的,我无法修复它们,所以我使用了这个webpack copy 插件将文件复制到正确的 dist 文件夹位置。


4

你需要使用url-loader

           {
               test: /\.(jpg|png|gif|woff|eot|ttf|svg)/,
                use: {
                    loader: 'url-loader', // this need file-loader
                    options: {
                        limit: 50000

                    }
                }
           }

2
请尝试以下配置。
{
    test: /\.s[ac]ss$/i,
    use: [
      {
        loader: MiniCssExtractPlugin.loader, 
        options: {
            publicPath: ''
        }
    },
    {
        loader: "css-loader", 
        options: { sourceMap: true}
    },{
      loader: "sass-loader", 
      options: { sourceMap: true }
    }
    ]
  },
  {
    test: /\.(png|jpg|jpeg|gif)$/i,
    loader: 'file-loader',
    options: { outputPath: 'assets/images', publicPath: '../images', useRelativePaths: true }
  },
  {
    test: /\.(woff|woff2|eot|ttf|otf)$/i,
    loader: 'file-loader',
    options: { outputPath: 'assets/fonts', publicPath: '../fonts', useRelativePaths: true }
  }

enter image description here

此后,我的scss文件开始接受相对URL,并且编译后的文件也使用相对路径进行了映射。

1
mini-css-extract-plugin有一个名为'publicPath'的选项(请参见这里)。它基本上告诉生成的CSS外部资源(如字体、图片等)的位置在哪里。在我的情况下,将其设置为'../'并配置所有文件加载器到其正确的目录,这个方法完美地解决了问题。 基本上看起来像:
rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: '/public/path/to/',  // <-- This is what was helping. 
            },
          },
          'css-loader',
        ],
      },
    ],

0

我曾经遇到过webpack 5的这个问题。答案在资产模块中。

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
   assetModuleFilename: 'images/[hash][ext][query]' //set the pattern for your filename here
  },
  module: {
    rules: [
      {
        test: /\.png/,
        type: 'asset/resource' //replaces file-loader, url-loader etc
      }
    ]
  },
};


0

我也遇到了这个问题。我使用的版本如下:

package.json

"mini-css-extract-plugin": "^0.10.1",
"webpack": "^5.3.1",

对我来说,一切都编译得很好,直到我将以下内容添加到scss文件中:

.xmas {
    background-image: url("./img/Xmas2020/SurveyBanner.png");
    height: 150px;
}

背景图片的URL是问题所在。当我将其更改为绝对路径时,它就可以工作了:

.xmas {
    background-image: url("/img/Xmas2020/SurveyBanner.png");
    height: 150px;
}

webpack.config.js

这只是为了展示我如何将图片放入输出目录。我想有不同的方法可以做到这一点,但我使用的是CopyWebpackPlugin。

plugins: [
   new CopyWebpackPlugin({
        patterns: [
            { from: './src/static/img', to: './img', force: true },
        ]
    }),
  ]

这个链接帮助了我 https://github.com/webpack-contrib/mini-css-extract-plugin/issues/286#issuecomment-455917803


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接