我的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限制)。
答案 0 :(得分:132)
TL; DR 将output.publicPath
设置为例如,使用资产的绝对路径(包括完整的主机名) " http://example.com/assets/"
问题是当Chrome从动态加载的CSS blob中解析时,网址的解析方式。
当您加载页面时,浏览器会加载您的Webpack包条目JavaScript文件,该文件(当您使用style-loader
时)也包含您的CSS的Base64编码副本,该副本将被加载到页。
对于作为数据URI编码到CSS中的所有图像或字体(即文件的内容嵌入在CSS中),这很好,但是对于 URL ,浏览器必须查找并获取文件。
现在默认情况下,file-loader
(url-loader
代表大型文件的代理人)将使用相对网址来引用资产 - 而是问题!的
当您使用相对网址时,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
}
}
现在,它生成的网址如下所示:
Chrome和其他所有浏览器都会正确解析这些网址。
extract-text-webpack-plugin
值得注意的是,如果您将CSS解压缩到单独的文件中,则您不会遇到此问题,因为您的CSS将在正确的文件中,并且URL将得到正确解析。
答案 1 :(得分:13)
如@mcortesi所述here如果从css加载器查询中删除sourceMaps,将在不使用blob的情况下构建css,并且数据网址将被正确解析
答案 2 :(得分:12)
对我来说问题是我的正则表达式。下面做了引导工作的技巧:
{
test: /\.(woff|ttf|eot|svg)(\?v=[a-z0-9]\.[a-z0-9]\.[a-z0-9])?$/,
loader: 'url-loader?limit=100000'
},
答案 3 :(得分:4)
与上面的@ user3006381一样,我的问题不仅仅是相对URL,而是webpack将文件放置为javascript文件。他们的内容基本上都是:
module.exports = __webpack_public_path__ + "7410dd7fd1616d9a61625679285ff5d4.eot";
在fonts目录中而不是真实字体,字体文件位于哈希码下的输出文件夹中。要解决这个问题,我必须更改我的url-loader(在我的情况下是我的图像处理器)上的测试,以便不加载fonts文件夹。我仍然必须在webpack.config.js中将output.publicPath设置为@ will-madden注意到他的优秀答案。
答案 4 :(得分:2)
我遇到了同样的问题,但出于不同的原因。
在Will Madden的解决方案没有帮助之后,我尝试了通过Intertubes找到的每个替代修复 - 也无济于事。进一步探索,我碰巧打开了一个有争议的字体文件。文件的原始内容在某种程度上被Webpack覆盖,以包含某种配置信息,可能来自之前修改文件加载器。我用原件替换了损坏的文件,瞧,错误消失了(对于Chrome和Firefox)。
答案 5 :(得分:1)
我知道这并没有回答OP的确切问题,但我来到这里的症状相同但原因不同:
我的Slick Slider的.scss文件包含如下:
@import "../../../node_modules/slick-carousel/slick/slick.scss";
仔细观察后发现,它试图从无效位置(<host>/assets/css/fonts/slick.woff
)加载字体,就像从样式表中引用它一样。
我最后只是将/font/
复制到我的assets/css/
,问题就解决了。
答案 6 :(得分:1)
由于您使用url-loader
:
url-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
这样您就不需要指定资产的整个网址。当您希望Webpack不仅从localhost响应时,这可能很难。
只需最后一个考虑因素,不建议将此配置用于生产。这只是为了发展的容易程度。
答案 7 :(得分:1)
我在Font Awesome上遇到了同样的问题。原来这是 是由FTP问题引起的。文件已以文本(ASCII)格式上传 而不是二进制文件,这会损坏文件。我只是更改了我的FTP 软件进行二进制处理,重新上传字体文件,然后将其全部 工作。
https://css-tricks.com/forums/topic/custom-fonts-returns-failed-to-decode-downloaded-font/ 这最终帮助了我 FTP与文本传输文件时遇到了相同的问题
答案 8 :(得分:0)
如果你正在使用Angular ,你需要检查以确保你的
<base href="/">
标签位于样式表包之前。我改变了我的代码:
<script src="~/bundles/style.bundle.js"></script>
<base href="~/" />
到此:
<base href="~/" />
<script src="~/bundles/style.bundle.js"></script>
问题得到解决。 感谢this post让我睁开眼睛。
答案 9 :(得分:0)
截至2018年
use MiniCssExtractPlugin
对于Webpack(> 4.0)将解决此问题。
https://github.com/webpack-contrib/mini-css-extract-plugin
对于Webpack 4.0及更高版本,建议不在接受的答案中使用extract-text-webpack-plugin
。
答案 10 :(得分:0)
最好和最简单的方法是对字体文件进行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"
。
答案 11 :(得分:0)
limit
是我的代码的线索,但是我必须像这样指定它:
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
},
},
],
答案 12 :(得分:0)
在我的情况下,向lambda.js添加以下行{我的部署在AWS Lambda上}解决了该问题。
invoke()