Webpack mini-css-extract-plugin @font-face url 解析问题

Posted

技术标签:

【中文标题】Webpack mini-css-extract-plugin @font-face url 解析问题【英文标题】:Webpack mini-css-extract-plugin @font-face url resolution issue 【发布时间】:2020-06-17 10:14:03 【问题描述】:

在使用 mini-css-extract-pluginfile-loader 和配置它们的选项(例如 contextfilename 属性时),我很难理解 URL/路径的性质以及它们是如何解决的。

我正在为 WordPress 开发一个自定义主题,自定义主题的文件夹是我初始化 npm project/package.json 文件和 webpack.config.js 文件的位置。我正在使用浏览器同步插件将本地 WordPress 服务器代理到浏览器同步服务器。

文件加载器正在将文件发送到 dist>assets>fonts 文件夹。但是在编译的 CSS 文件中生成的 URL 没有被正确解析。

输出 CSS,浏览器控制台错误

GET http://localhost:4444/wp-content/themes/test/dist/css/assets/fonts/my-font.ttf net::ERR_ABORTED 404 (Not Found)

GET http://localhost:4444/wp-content/themes/test/dist/css/assets/fonts/my-font.woff 404 (Not Found)

在上面的错误中,url 显示dist/css/assets/fonts/my-font.woff,这不是我所期望的。它应该是dist/assets/fonts/my-font.woff,因为这是 file-loader 在 dist 文件夹中发出文件的地方。 (在文件加载器上下文选项中定义)

我不明白为什么要将css 目录添加到字体网址。 dist/css 路径的唯一提及是在 MiniCSSExtractPlugin 选项的文件名属性中。因为那是我希望输出 css 文件的地方。

这可以通过删除文件名属性上的css 路径前缀来确认。然后url相对于dist路径正确解析,但是编译后的css文件放在dist文件夹的根目录而不是它自己的dist/css子目录中。

迷你 css 提取插件选项

new MiniCSSExtractPlugin(
            filename: 'css/[name].css',
        ),

scss 文件中的字体规则

@font-face 
  font-family: 'my-font';
  src: url("../assets/fonts/my-font.eot");
  src: url("../assets/fonts/my-font.eot") format("embedded-opentype"),
  url("../assets/fonts/my-font.ttf") format("truetype"),
  url("../assets/fonts/my-font.woff") format("woff"),
  url("../assets/fonts/my-font.svg") format("svg");
  font-weight: normal;
  font-style: normal;
  font-display: block;


webpack 配置入口和输出

 entry: 
        'frontend': './src/js/frontend.js',
    ,
    output: 
        path: path.resolve(__dirname, 'dist'),
        filename: "js/[name].js"
    ,

module.rules

module: 
        rules: [
            ...,
            
                test: /\.(sa|sc|c)ss$/,
                use: [
                    
                        loader: MiniCSSExtractPlugin.loader
                    ,
                    
                        loader: "css-loader"
                    ,
                    
                        loader: "sass-loader"
                    ,
                ]
            ,
            
                test: /\.(eot|woff|woff2|svg|ttf)([\?]?.*)$/,
                use: [
                    
                        loader: 'file-loader',
                        options: 
                            context: path.resolve(__dirname, 'src'),
                            name: '[path][name].[ext]'
                        
                    
                ]
            

插件

plugins: [
        new CleanWebpackPlugin(),
        new BrowserSyncWebpackPlugin(...),
        new MiniCSSExtractPlugin(
            filename: 'css/[name].css',
        ),
    ]

我是 webpack 的初学者,我在尝试正确解析字体 URL 时遇到了一些困难。我有一种感觉,我不明白 webpack 配置中的相对/绝对路径、上下文和公共路径的用途。编译后的 CSS 中的 URL 是如何确定的?

【问题讨论】:

你找到解决办法了吗? 【参考方案1】:

当我遇到同样的问题时,我遇到了你的问题。我最终设法通过使用 MiniCssExtractPlugin 的 publicPath 选项来解决它。

我的目录结构如下所示,其中assets 包含工作文件,build 包含已编译文件。我的项目的根目录是/src

/src
  /assets
    /css
    /webfonts
  /build
    /css
    /webfonts

因此,通过为publicPath 设置绝对路径,这意味着我的 CSS 中的字体文件被绝对文件路径引用,而不是相对文件路径。


  loader: MiniCssExtractPlugin.loader,
  options: 
    publicPath: '/build/',
  ,
,

【讨论】:

【参考方案2】:

改变

url("../assets/fonts/my-font.ttf") format("truetype"),

url("../assets/fonts/my-font.ttf") format("ttf"),

【讨论】:

以上是关于Webpack mini-css-extract-plugin @font-face url 解析问题的主要内容,如果未能解决你的问题,请参考以下文章

Webpack:安装 webpack 和 webpack-cli 后运行 webpack 时仍然报错

安装webpack后还是提示webpack不是内部命令

【webpack】--config 的使用

# Webpack 学习Webpack 搭建 Vue项目

# Webpack 学习Webpack 搭建 Vue项目

Webpack教程: Webpack安装