Webpack“OTS 解析错误”加载字体
Posted
技术标签:
【中文标题】Webpack“OTS 解析错误”加载字体【英文标题】:Webpack "OTS parsing error" loading fonts 【发布时间】:2016-03-12 01:40:29 【问题描述】:我的 webpack 配置指定应使用 url-loader
加载字体,当我尝试使用 Chrome 查看页面时出现以下错误:
OTS parsing error: invalid version tag
Failed to decode downloaded font: [My local URL]
我的配置的相关部分如下所示:
module:
loaders: [
// ...
test: /\.scss$/,
loaders: ['style', 'css?sourceMap', 'autoprefixer', 'sass?sourceMap'],
,
test: /images\/.*\.(png|jpg|svg|gif)$/,
loader: 'url-loader?limit=10000&name="[name]-[hash].[ext]"',
,
test: /fonts\/.*\.(woff|woff2|eot|ttf|svg)$/,
loader: 'file-loader?name="[name]-[hash].[ext]"',
],
,
在 Safari 中不会发生,我也没有尝试过 Firefox。
在开发中,我通过webpack-dev-server
提供文件,在生产中,它们被写入磁盘并复制到 S3;在这两种情况下,我在 Chrome 中都会得到相同的行为。
这也会发生在较大的图像上(大于图像加载器配置中的 10kB 限制)。
【问题讨论】:
如果您的字体文件为空或损坏,您可能会遇到此问题。所以检查你的字体文件的大小 【参考方案1】:TL;DR 通过将您的 output.publicPath
设置为例如,使用资产的绝对路径(包括您的完整主机名)。 “http://example.com/assets/”。
问题
问题在于当从动态加载的 CSS blob 解析 URL 时,Chrome 解析 URL 的方式。
当您加载页面时,浏览器会加载您的 Webpack 捆绑条目 javascript 文件,该文件(当您使用 style-loader
时)还包含您的 CSS 的 Base64 编码副本,该副本会加载到页面中。
这就是它在 Chrome DevTools 中的样子
这对于所有作为数据 URI 编码到 CSS 中的图像或字体都可以(即文件的内容嵌入在 CSS 中),但对于 URL 引用的资产,浏览器必须找到并获取文件。
现在默认情况下,file-loader
(url-loader
代表大文件)将使用 相对 URL 来引用资产 - 这就是问题所在!
这些是
file-loader
默认生成的 URL - 相对 URL
当您使用相对 URL 时,Chrome 会相对于包含的 CSS 文件来解析它们。通常这很好,但在这种情况下,包含文件位于 blob://...
并且任何相对 URL 都以相同的方式引用。最终结果是 Chrome 尝试从父 html 文件加载它们,并最终尝试将 HTML 文件解析为字体的内容,这显然是行不通的。
解决方案
强制file-loader
使用包括协议(“http”或“https”)在内的绝对路径。
更改您的 webpack 配置以包含与以下内容等效的内容:
output:
publicPath: "http://localhost:8080/", // Development Server
// publicPath: "http://example.com/", // Production Server
现在它生成的 URL 将如下所示:
绝对网址!
Chrome 和其他所有浏览器都会正确解析这些 URL。
使用extract-text-webpack-plugin
值得注意的是,如果您将 CSS 提取到单独的文件中,则不会出现此问题,因为您的 CSS 将位于正确的文件中,并且 URL 将被正确解析。
【讨论】:
哇,上周刚遇到这个问题。当您有许多部署或开发环境时会发生什么情况,手动更改 IP 不是很繁琐吗? @benoror 对于不使用style-loader
的部署来说这不是问题,因为 CSS 将从单独的 CSS 文件提供,Chrome 将能够正确解析资产 URL。所以你应该没问题,例如暂存、测试、QA 环境,您可以在其中将应用程序部署到某处并提取 CSS。但是,如果您有许多开发环境,则可能会出现问题。在我们的团队中,至少我们只在本地运行一次开发服务器,然后从那里开始工作。这并不理想,我不得不通知我的队友关于配置的更改,但这并没有真正影响我们。
顺便说一句,刚刚看到一个可能与此特定问题有关的视频:youtu.be/MzVFrIAwwS8?t=870
谢谢,我从您的回答中找到了我的 SPA 页面重新加载问题的原因。只需注释publicPath: '/',
也可以使用
实际上这个解决方案并没有解决我的环境问题。有没有办法将整个 webpack 配置和 scss(相关块)上传到 CodePen?谢谢!【参考方案2】:
对我来说,问题在于我的正则表达式。下面的技巧可以让引导程序正常工作:
test: /\.(woff|ttf|eot|svg)(\?v=[a-z0-9]\.[a-z0-9]\.[a-z0-9])?$/,
loader: 'url-loader?limit=100000'
,
【讨论】:
从测试中删除 woff2 并且它有效... test: /\.(png|jpe?g|gif|svg|woff|ttf|eot|ico)$/, loader: ' file?name=assets/[name].[hash].[ext]' ,【参考方案3】:正如@mcortesi here 所说,如果您从 css 加载器查询中删除 sourceMaps,则 css 将在不使用 blob 的情况下构建,并且数据 url 将被很好地解析
【讨论】:
这个答案适用于我以及上面更受欢迎的答案。 感谢您的回答。 Storybook 无法加载 Semantic UI 的字体时遇到问题,花了很多时间寻找解决方案。这解决了它。只需从 CSS 加载器中删除?sourceMap
即可。
完美!删除源映射我没有任何问题,我的构建需要在不预先指定域的情况下工作【参考方案4】:
与上面的 @user3006381 一样,我的问题不仅仅是相对 URL,而是 webpack 将文件放置为 javascript 文件。他们的内容基本上都是:
module.exports = __webpack_public_path__ + "7410dd7fd1616d9a61625679285ff5d4.eot";
在字体目录而不是真正的字体中,字体文件位于哈希码下的输出文件夹中。为了解决这个问题,我不得不更改我的 url-loader(在我的情况下是我的图像处理器)上的测试以不加载字体文件夹。我仍然必须在 webpack.config.js 中设置 output.publicPath,正如 @will-madden 在他的出色回答中所指出的那样。
【讨论】:
这是我遇到的问题,但由于我使用的是easy-webpack(实际上可能是错误命名),我不确定如何从url加载器中排除字体文件夹.. @DarrenOster:我认为您必须使用他们的Object generators 将其指定为覆盖,以便您可以修改生成的配置。【参考方案5】:我遇到了同样的问题,但原因不同。
在 Will Madden 的解决方案没有帮助之后,我尝试了所有可以通过 Intertubes 找到的替代解决方案 - 也无济于事。进一步探索,我碰巧打开了一个有问题的字体文件。该文件的原始内容不知何故被 Webpack 覆盖以包含某种配置信息,可能来自之前对文件加载器的修补。我用原始文件替换了损坏的文件,瞧,错误消失了(对于 Chrome 和 Firefox)。
【讨论】:
【参考方案6】:我知道这不能回答 OP 的确切问题,但我来到这里的症状相同,但原因不同:
我有 Slick Slider 的 .scss 文件,如下所示:
@import "../../../node_modules/slick-carousel/slick/slick.scss";
仔细检查后发现,它试图从无效位置 (<host>/assets/css/fonts/slick.woff
) 加载字体,这是从样式表中引用它的方式。
我最后只是简单地将/font/
复制到我的assets/css/
并且问题已为我解决。
【讨论】:
【参考方案7】:既然你用url-loader
:
url-loader 的工作方式与 file-loader 类似,但如果文件小于字节限制,则可以返回 DataURL。
因此,此问题的另一种解决方案是将限制设置得足够高,以便将字体文件作为 DataURL 包含在内,例如 100000
或多或少是 100Kb
:
module:
loaders: [
// ...
test: /\.scss$/,
loaders: ['style', 'css?sourceMap', 'autoprefixer', 'sass?sourceMap'],
,
test: /images\/.*\.(png|jpg|svg|gif)$/,
loader: 'url-loader?limit=10000&name="[name]-[hash].[ext]"',
,
test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
use: 'url-loader?limit=100000&mimetype=application/font-woff',
,
test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
use: 'url-loader?limit=100000&mimetype=application/font-woff',
,
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: 'url-loader?limit=100000&mimetype=application/octet-stream',
,
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
use: 'file-loader',
,
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: 'url-loader?limit=100000&mimetype=image/svg+xml',
,
],
,
始终考虑限制数字所代表的含义:
作为数据 URL 的内联文件的字节限制
这样您就不需要指定资产的整个 URL。当您希望 Webpack 不仅从 localhost 响应时,这可能会很困难。
最后一个注意事项,不建议将此配置用于生产。这只是为了便于开发。
【讨论】:
【参考方案8】:最好和最简单的方法是对字体文件进行 base64 编码。并在字体中使用它。 对于编码,转到具有字体文件的文件夹并在终端中使用命令:
base64 Roboto.ttf > basecodedtext.txt
您将获得一个名为 basecodedtext.txt 的输出文件。打开那个文件。删除其中的所有空格。
复制该代码并将以下行添加到 CSS 文件中:
@font-face
font-family: "font-name";
src: url(data:application/x-font-woff;charset=utf-8;base64,<<paste your code here>>) format('woff');
然后你可以在你的 CSS 中使用font-family: "font-name"
。
【讨论】:
比发布的其他解决方案更混乱,但如果您无法直接访问您的 webpack 配置(例如,如果使用 CRA),它会有效且有用【参考方案9】:我刚刚在 Font Awesome 上遇到了同样的问题。原来这是 由 FTP 问题引起。文件以文本 (ASCII) 形式上传 而不是二进制文件,它损坏了文件。我只是更改了我的 FTP 软件转二进制,重新上传字体文件,然后全部 工作。
https://css-tricks.com/forums/topic/custom-fonts-returns-failed-to-decode-downloaded-font/ 这最终帮助了我 我在 FTP 将文件作为文本传输时遇到了同样的问题
【讨论】:
【参考方案10】:如果您使用的是 Angular,您需要检查以确保您的
<base href="/">
标签位于样式表包之前。我从这里切换了我的代码:
<script src="~/bundles/style.bundle.js"></script>
<base href="~/" />
到这里:
<base href="~/" />
<script src="~/bundles/style.bundle.js"></script>
问题已解决。 感谢this post让我大开眼界。
【讨论】:
【参考方案11】:截至 2018 年,
use MiniCssExtractPlugin
for Webpack(> 4.0) 将解决这个问题。
https://github.com/webpack-contrib/mini-css-extract-plugin
在接受的答案中使用extract-text-webpack-plugin
是不推荐用于 Webpack 4.0+。
【讨论】:
【参考方案12】:limit
是我的代码的线索,但我必须像这样指定它:
use: [
loader: 'url-loader',
options:
limit: 8192,
,
,
],
【讨论】:
【参考方案13】:在我的情况下,将以下行添加到 lambda.js 我的部署是在 AWS Lambda 上 解决了这个问题。
'font/opentype',
'font/sfnt',
'font/ttf',
'font/woff',
'font/woff2'
【讨论】:
以上是关于Webpack“OTS 解析错误”加载字体的主要内容,如果未能解决你的问题,请参考以下文章
创建 React 应用程序:无法解码下载的字体 | OTS 解析错误
自托管 Google 的 Material Design 图标字体 - OTS 解析错误 - 无效的版本标签
Spring Boot - Font Awesome OTS 解析错误:转换失败