Meine Webpack-Konfiguration gibt an, dass Schriftarten mit url-loader
geladen werden sollten. Wenn ich versuche, die Seite mit Chrome anzuzeigen, erhalte ich die folgende Fehlermeldung:
OTS parsing error: invalid version tag
Failed to decode downloaded font: [My local URL]
Die relevanten Teile meiner Konfiguration sehen so aus:
{
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]"',
}
],
},
}
In Safari passiert das nicht und ich habe Firefox noch nicht ausprobiert.
In der Entwicklung versende ich Dateien über webpack-dev-server
, in der Produktion werden sie auf die Festplatte geschrieben und in S3 kopiert. In beiden Fällen erhalte ich dasselbe Verhalten in Chrome.
Dies ist auch bei größeren Bildern der Fall (größer als die 10-KB-Grenze in der Image Loader-Konfiguration).
TL; DR Verwenden Sie absolute Pfade zu Ihren Assets (einschließlich Ihres vollständigen Hostnamens), indem Sie Ihren output.publicPath
auf z. " http://example.com/assets/ ".
Das Problem ist die Art und Weise, wie URLs von Chrome gelöst werden, wenn sie aus einem dynamisch geladenen CSS-Blob analysiert werden.
Wenn Sie die Seite laden, lädt der Browser die JavaScript-Datei Ihres Webpack-Bundle-Eintrags, die (wenn Sie den style-loader
verwenden) auch eine Base64-kodierte Kopie Ihres CSS enthält, die in die Seite geladen wird.
Das ist in Ordnung für alle Bilder oder Schriftarten, die als Daten-URIs in das CSS kodiert werden (dh der Inhalt der Datei ist in das CSS eingebettet), aber für Assets, auf die URL verweist, muss der Browser dies tun Finden und holen Sie die Datei.
Standardmäßig verwendet file-loader
(an das url-loader
für große Dateien delegiert wird) relative URLs, um auf Assets zu verweisen - und das ist das Problem!
Dies sind die von
file-loader
standardmäßig generierten URLs - relative URLs
Wenn Sie relative URLs verwenden, löst Chrome diese relativ zur enthaltenen CSS-Datei auf. Normalerweise ist das in Ordnung, aber in diesem Fall befindet sich die enthaltende Datei unter blob://...
und alle relativen URLs werden auf dieselbe Weise referenziert. Das Endergebnis ist, dass Chrome versucht, sie aus der übergeordneten HTML-Datei zu laden, und am Ende versucht, die HTML-Datei als Inhalt der Schriftart zu analysieren, was offensichtlich nicht funktioniert.
Erzwingen Sie die Verwendung von absoluten Pfaden einschließlich des Protokolls ("http" oder "https") für den file-loader
.
Ändern Sie Ihre Webpack-Konfiguration so, dass sie Folgendes enthält:
{
output: {
publicPath: "http://localhost:8080/", // Development Server
// publicPath: "http://example.com/", // Production Server
}
}
Die URLs, die es generiert, sehen nun so aus:
Diese URLs werden von Chrome und allen anderen Browsern korrekt analysiert.
extract-text-webpack-plugin
verwendenWenn Sie Ihr CSS in eine separate Datei extrahieren, wird dieses Problem nicht auftreten, da sich Ihr CSS in einer korrekten Datei befindet und die URLs korrekt aufgelöst werden.
Wenn Sie here von @mcortesi nicht ausgewählt haben, werden die CSS-Dateien ohne Verwendung von BLOB erstellt, wenn Sie die sourceMaps aus der Abfrage des css loader entfernen
Für mich war das Problem mein Regex-Ausdruck. Das Folgende hat den Trick gebracht, um Bootstrap zum Laufen zu bringen:
{
test: /\.(woff|ttf|eot|svg)(\?v=[a-z0-9]\.[a-z0-9]\.[a-z0-9])?$/,
loader: 'url-loader?limit=100000'
},
Wie bei @ user3006381 oben bestand mein Problem nicht nur aus relativen URLs, sondern das Webpack platzierte die Dateien so, als wären es Javascript-Dateien. Ihr Inhalt war alles im Wesentlichen:
module.exports = __webpack_public_path__ + "7410dd7fd1616d9a61625679285ff5d4.eot";
im fonts-Verzeichnis statt der echten Schriftarten befanden sich die Font-Dateien im Ausgabeordner unter Hash-Codes. Um dies zu beheben, musste ich den Test für meinen URL-Loader (in meinem Fall meinen Bildprozessor) ändern, um den Schriftartenordner nicht zu laden. Ich musste output.publicPath in webpack.config.js immer noch als @ will-madden-Notizen in seiner hervorragenden Antwort festlegen.
Ich hatte das gleiche Problem, aber aus verschiedenen Gründen.
Nachdem Will Maddens Lösung nicht geholfen hatte, versuchte ich jede alternative Lösung, die ich über die Intertubes finden konnte - auch ohne Erfolg. Ich erkundigte mich noch einmal, dass ich gerade eine der Schriftdateien geöffnet habe. Der ursprüngliche Inhalt der Datei wurde von Webpack irgendwie überschrieben, um Konfigurationsinformationen einzubeziehen, die wahrscheinlich aus dem vorherigen Basteln mit dem Dateilader stammen. Ich habe die beschädigten Dateien durch die Originale ersetzt, und voilà verschwanden die Fehler (sowohl für Chrome als auch für Firefox).
Ich weiß, dass dies nicht die genaue Frage der OP beantwortet, aber ich bin mit dem gleichen Symptom, aber einer anderen Ursache hierher gekommen:
Ich hatte die .scss-Dateien von Slick Slider wie folgt:
@import "../../../node_modules/slick-carousel/slick/slick.scss";
Bei näherer Betrachtung stellte sich heraus, dass die Schriftart versucht wurde, die Schriftart von einem ungültigen Ort (<Host>/assets/css/fonts/slick.woff
) zu laden, wie sie vom Stylesheet aus referenziert wurde.
Am Ende habe ich einfach den /font/
in meinen assets/css/
kopiert und das Problem wurde für mich gelöst.
Da Sie url-loader
verwenden:
Der URL-Loader funktioniert wie der File-Loader, kann jedoch eine DataURL zurückgeben, wenn die Datei kleiner als ein Byte-Limit ist.
Eine andere Lösung für dieses Problem wäre also, die Grenze so hoch zu setzen, dass die Zeichensatzdateien als DataURL enthalten sind, beispielsweise zu 100000
, die mehr oder weniger 100Kb
sind:
{
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',
},
],
},
}
Berücksichtigen Sie immer, auf was die Begrenzungsnummer steht:
Byte-Limit für Inline-Dateien als Daten-URL
Auf diese Weise müssen Sie nicht die gesamte URL der Assets angeben. Was schwierig sein kann, wenn Webpack nicht nur von localhost aus antworten soll.
Nur eine letzte Überlegung, diese Konfiguration wird für die Produktion NICHT EMPFOHLEN. Dies ist nur für die Entwicklungsfreundlichkeit.
Wenn Sie Angular verwenden, müssen Sie dies überprüfen
<base href="/">
das Tag kommt vor dem Stylesheet-Bundle. Ich habe meinen Code von hier aus geändert:
<script src="~/bundles/style.bundle.js"></script>
<base href="~/" />
zu diesem:
<base href="~/" />
<script src="~/bundles/style.bundle.js"></script>
und das Problem wurde behoben ... Danke an diesen Beitrag für das Öffnen meiner Augen.
Ab 2018
use MiniCssExtractPlugin
für Webpack (> 4.0) wird dieses Problem gelöst.
https://github.com/webpack-contrib/mini-css-extract-plugin
Die Verwendung von extract-text-webpack-plugin
in der akzeptierten Antwort wird NICHT für Webpack 4.0+ empfohlen.
Die beste und einfachste Methode besteht darin, die Schriftartdatei mit base64 zu codieren. Und verwenden Sie es in Schriftart. Wechseln Sie zum Codieren in den Ordner mit der Schriftartdatei und verwenden Sie den Befehl im Terminal:
base64 Roboto.ttf > basecodedtext.txt
Sie erhalten eine Ausgabedatei mit dem Namen basecodedtext.txt. Öffnen Sie diese Datei. Entfernen Sie alle Leerzeichen darin.
Kopieren Sie diesen Code und fügen Sie der CSS-Datei die folgende Zeile hinzu:
@font-face {
font-family: "font-name";
src: url(data:application/x-font-woff;charset=utf-8;base64,<<paste your code here>>) format('woff');
}
Dann können Sie den font-family: "font-name"
in Ihrem CSS verwenden.