CSS Webpack“OTS解析错误”加载字体
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34133808/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Webpack "OTS parsing error" loading fonts
提问by Will Madden
My webpack config specifies that fonts should be loaded using url-loader
, and when I try to view the page using Chrome I get the following error:
我的 webpack 配置指定应使用 加载字体url-loader
,当我尝试使用 Chrome 查看页面时,出现以下错误:
OTS parsing error: invalid version tag
Failed to decode downloaded font: [My local URL]
The relevant parts of my config look like this:
我的配置的相关部分如下所示:
{
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]"',
}
],
},
}
It doesn't happen in Safari, and I haven't tried Firefox.
它不会在 Safari 中发生,我还没有尝试过 Firefox。
In development I'm serving files through webpack-dev-server
, in production they're written to disk and copied to S3; in both cases I get the same behaviour in Chrome.
在开发中,我通过 提供文件webpack-dev-server
,在生产中,它们被写入磁盘并复制到 S3;在这两种情况下,我在 Chrome 中都得到了相同的行为。
This also happens to larger images (greater than the 10kB limit in the image loader config).
这也会发生在较大的图像上(大于图像加载器配置中的 10kB 限制)。
回答by Will Madden
TL;DRUse absolute paths to your assets (including your complete hostname) by setting your output.publicPath
to e.g. "http://example.com/assets/".
TL;DR通过将您设置output.publicPath
为例如“ http://example.com/assets/”,使用您的资产的绝对路径(包括您的完整主机名)。
The problem
问题
The problem is the way that URLs are resolved by Chrome when they're parsed from a dynamically loaded CSS blob.
问题在于 Chrome 在从动态加载的 CSS blob 解析 URL 时解析 URL 的方式。
When you load the page, the browser loads your Webpack bundle entry JavaScript file, which (when you're using the style-loader
) also contains a Base64 encoded copy of your CSS, which gets loaded into the page.
当您加载页面时,浏览器会加载您的 Webpack 包入口 JavaScript 文件,该文件(当您使用 时style-loader
)还包含您的 CSS 的 Base64 编码副本,该副本将被加载到页面中。
That's fine for all the images or fonts which are encoded into the CSS as data URIs (i.e. the content of the file is embedded in the CSS), but for assets referenced by URL, the browser has to find and fetch the file.
对于作为数据 URI 编码到 CSS 中的所有图像或字体(即文件的内容嵌入在 CSS 中)来说,这很好,但对于由URL引用的资产,浏览器必须查找并获取文件。
Now by default the file-loader
(which url-loader
delegates to for large files) will use relativeURLs to reference assets - and that's the problem!
现在默认情况下file-loader
(url-loader
委托给大文件)将使用相对URL 来引用资产——这就是问题所在!
These are the URLs generated by
file-loader
by default - relative URLs
When you use relative URLs, Chrome will resolve them relative to the containing CSS file. Ordinarily that's fine, but in this case the containing file is at blob://...
and any relative URLs are referenced the same way. The end result is that Chrome attempts to load them from the parent HTML file, and ends up trying to parse the HTML file as the content of the font, which obviously won't work.
当您使用相对 URL 时,Chrome 将相对于包含的 CSS 文件解析它们。通常这很好,但在这种情况下,包含文件位于blob://...
并且任何相对 URL 都以相同的方式引用。最终结果是 Chrome 尝试从父 HTML 文件加载它们,并最终尝试将 HTML 文件解析为字体的内容,这显然不起作用。
The Solution
解决方案
Force the file-loader
to use absolute paths including the protocol ("http" or "https").
强制file-loader
使用绝对路径,包括协议(“http”或“https”)。
Change your webpack config to include something equivalent to:
更改您的 webpack 配置以包含等效于以下内容的内容:
{
output: {
publicPath: "http://localhost:8080/", // Development Server
// publicPath: "http://example.com/", // Production Server
}
}
Now the URLs that it generates will look like this:
现在它生成的 URL 将如下所示:
These URLs will be correctly parsed by Chrome and every other browser.
Chrome 和其他所有浏览器都会正确解析这些 URL。
Using extract-text-webpack-plugin
使用 extract-text-webpack-plugin
It's worth noting that if you're extracting your CSS to a separate file, you won't have this problem because your CSS will be in a proper file and URLs will be correctly resolved.
值得注意的是,如果您将 CSS 提取到单独的文件中,则不会出现此问题,因为您的 CSS 将位于正确的文件中并且 URL 将被正确解析。
回答by Nadav SInai
回答by Waihibeachian
For me the problem was my regex expression. The below did the trick to get bootstrap working:
对我来说,问题是我的正则表达式。下面做了让引导程序工作的技巧:
{
test: /\.(woff|ttf|eot|svg)(\?v=[a-z0-9]\.[a-z0-9]\.[a-z0-9])?$/,
loader: 'url-loader?limit=100000'
},
回答by Adam McCormick
As with @user3006381 above, my issue was not just relative URLs but that webpack was placing the files as if they were javascript files. Their contents were all basically:
与上面的@user3006381 一样,我的问题不仅仅是相对 URL,而是 webpack 将文件当作 javascript 文件放置。他们的内容基本上都是:
module.exports = __webpack_public_path__ + "7410dd7fd1616d9a61625679285ff5d4.eot";
in the fonts directory instead of the real fonts and the font files were in the output folder under hash codes. To fix this, I had to change the test on my url-loader (in my case my image processor) to not load the fonts folder. I still had to set output.publicPath in webpack.config.js as @will-madden notes in his excellent answer.
在字体目录中,而不是真正的字体,字体文件位于哈希码下的输出文件夹中。为了解决这个问题,我不得不更改我的 url-loader(在我的例子中是我的图像处理器)上的测试,以不加载字体文件夹。我仍然必须在 webpack.config.js 中将 output.publicPath 设置为@will-madden 在他的出色回答中的注释。
回答by user3006381
I experienced the same problem, but for different reasons.
我遇到了同样的问题,但原因不同。
After Will Madden's solution didn't help, I tried every alternative fix I could find via the Intertubes - also to no avail. Exploring further, I just happened to open up one of the font files at issue. The original content of the file had somehow been overwritten by Webpack to include some kind of configuration info, likely from previous tinkering with the file-loader. I replaced the corrupted files with the originals, and voilà, the errors disappeared (for both Chrome and Firefox).
在 Will Madden 的解决方案没有帮助之后,我尝试了所有可以通过 Intertubes 找到的替代解决方案 - 也无济于事。进一步探索,我碰巧打开了一个有问题的字体文件。该文件的原始内容已被 Webpack 以某种方式覆盖以包含某种配置信息,这可能来自之前对文件加载器的修改。我用原件替换了损坏的文件,瞧,错误消失了(对于 Chrome 和 Firefox)。
回答by bpylearner
I know this doesn't answer OPs exact question but I came here with the same symptom but a different cause:
我知道这不能回答 OP 的确切问题,但我带着相同的症状来到这里,但原因不同:
I had the .scss files of Slick Slider included like this:
我有 Slick Slider 的 .scss 文件,如下所示:
@import "../../../node_modules/slick-carousel/slick/slick.scss";
On closer inspection it turned out that the it was trying to load the font from an invalid location (<host>/assets/css/fonts/slick.woff
), the way it was referenced from the stylesheet.
仔细检查后发现,它试图从无效位置 ( <host>/assets/css/fonts/slick.woff
)加载字体,这是从样式表引用它的方式。
I ended up simply copying the /font/
to my assets/css/
and the issue was resolved for me.
我最终只是简单地将 复制/font/
到我的assets/css/
,问题就为我解决了。
回答by Roc
Since you use url-loader
:
由于您使用url-loader
:
The url-loader works like the file-loader, but can return a DataURL if the file is smaller than a byte limit.
url-loader 的工作方式与 file-loader 类似,但如果文件小于字节限制,则可以返回 DataURL。
So another solution to this problem would be making the limit higher enough that the font files are included as DataURL, for example to 100000
which are more or less 100Kb
:
因此,此问题的另一种解决方案是将限制设置得足够高,以便将字体文件包含为 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',
},
],
},
}
Allways taking into account on what the limit number represents:
始终考虑限制数字代表的含义:
Byte limit to inline files as Data URL
作为数据 URL 的内联文件的字节限制
This way you don't need to specify the whole URL of the assets. Which can be difficult when you want Webpack to not only respond from localhost.
这样您就不需要指定资产的整个 URL。当您希望 Webpack 不仅从本地主机响应时,这可能会很困难。
Just one last consideration, this configuration is NOT RECOMMENDED for production. This is just for development easiness.
最后一个考虑因素是,不建议将此配置用于生产。这只是为了便于开发。
回答by Luqman Khalid
I just had the same issue with Font Awesome. Turned out this was caused by a problem with FTP. The file was uploaded as text (ASCII) instead of binary, which corrupted the file. I simply changed my FTP software to binary, re-uploaded the font files, and then it all worked.
我刚刚在使用 Font Awesome 时遇到了同样的问题。原来这是由FTP问题引起的。该文件以文本 (ASCII) 而不是二进制文件的形式上传,这会损坏文件。我只是将我的 FTP 软件更改为二进制文件,重新上传字体文件,然后一切正常。
https://css-tricks.com/forums/topic/custom-fonts-returns-failed-to-decode-downloaded-font/this helped me in the end I had the same issue with FTP transferring files as text
https://css-tricks.com/forums/topic/custom-fonts-returns-failed-to-decode-downloaded-font/这最终帮助了我我在 FTP 将文件作为文本传输时遇到了同样的问题
回答by Patrick Graham
If you're using Angularyou need to check to make sure your
如果您使用的是 Angular,则需要检查以确保您的
<base href="/">
tag comes before your style sheet bundle. I switched my code from this:
标签出现在您的样式表包之前。我从这个切换了我的代码:
<script src="~/bundles/style.bundle.js"></script>
<base href="~/" />
to this:
对此:
<base href="~/" />
<script src="~/bundles/style.bundle.js"></script>
and the problem was fixed. Thanks to this postfor opening my eyes.
问题得到解决。感谢这篇文章让我大开眼界。
回答by dsignr
As of 2018,
截至 2018 年,
use MiniCssExtractPlugin
use MiniCssExtractPlugin
for Webpack(> 4.0) will solve this problem.
for Webpack(> 4.0) 将解决这个问题。
https://github.com/webpack-contrib/mini-css-extract-plugin
https://github.com/webpack-contrib/mini-css-extract-plugin
Using extract-text-webpack-plugin
in the accepted answer is NOTrecommended for Webpack 4.0+.
不建议在 Webpack 4.0+ 中使用extract-text-webpack-plugin
已接受的答案。