Webpack" OTS parsing error " загрузка шрифтов



мой webpack config указывает, что шрифты должны быть загружены с помощью 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; в обоих случаях я получаю одинаковое поведение в Хром.



Это также происходит с большими изображениями (больше, чем ограничение 10 кб в конфигурации загрузчика изображений).

923   9  

9 ответов:

TL; DR используйте абсолютные пути к вашим активам (включая полное имя хоста), установив output.publicPath например"http://example.com/assets/".

проблема

проблема заключается в том, что URL-адреса разрешаются Chrome, когда они анализируются из динамически загруженного CSS blob.

при загрузке страницы браузер загружает ваш файл JavaScript webpack bundle, который (когда вы используете style-loader) также содержит кодированную копию Base64 вашего CSS, которая загружается на страницу.

Screenshot of embedded CSS in Chrome DevTools Вот как это выглядит в Chrome DevTools

это нормально для всех изображений или шрифтов, которые закодированы в CSS как URI данных (т. е. содержимое файла встроено в CSS), но для активов, на которые ссылается URL браузер должен найти и принести файл.

теперь по умолчанию file-loader (который url-loader делегаты для больших файлов) будет использовать относительные URL для ссылки на активы-и вот в чем проблема!

Relative URLs generated by Webpack это URL-адреса, созданные file-loader по умолчанию - относительные 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-адреса, которые он генерирует будет выглядеть так:

enter image description here Абсолютные URL-Адреса!

эти URL-адреса будут правильно проанализированы Chrome и любым другим браузером.

используя extract-text-webpack-plugin

стоит отметить, что если вы извлекаете свой CSS в отдельный файл, у вас не будет этой проблемы, потому что ваш CSS будет в правильном файле, и URL-адреса будут правильно разрешены.

Как asnwered здесь by @mcortesi если вы удалите исходные карты из запроса загрузчика css, css будет построен без использования blob, а URL-адреса данных будут проанализированы нормально

для меня проблемой было мое регулярное выражение. Ниже сделал трюк, чтобы получить bootstrap работает

        { test: /\.(woff|ttf|eot|svg)(\?v=[a-z0-9]\.[a-z0-9]\.[a-z0-9])?$/, loader: 'url-loader?limit=100000' },

Как и в случае с @user3006381 выше, моя проблема заключалась не только в относительных URL-адресах, но и в том, что webpack размещал файлы, как если бы они были файлами javascript. Их содержание было все в основном:

module.exports = __webpack_public_path__ + "7410dd7fd1616d9a61625679285ff5d4.eot";

в каталоге шрифтов вместо реальных шрифтов и файлов шрифтов были в выходной папке под хэш-кодами. Чтобы исправить это, мне пришлось изменить тест на моем url-загрузчике (в моем случае мой процессор изображений), чтобы не загружать папку шрифтов. Мне все еще нужно было установить выход.publicPath в webpack.конфиг.js as @will-madden отмечает в своем превосходном ответе.

Я испытал ту же проблему, но по разным причинам.

после того, как решение Уилла Мэддена не помогло, я попробовал все альтернативные исправления, которые я мог найти через Intertubes - также безрезультатно. Исследуя дальше, я просто случайно открыл один из файлов шрифтов, о которых идет речь. Исходное содержимое файла каким-то образом было перезаписано Webpack, чтобы включить какую-то информацию о конфигурации, вероятно, от предыдущего возни с загрузчиком файлов. Я заменил поврежденные файлы на оригиналы и вуаля, ошибки исчезли (как для Chrome, так и для Firefox).

Я знаю, что это не отвечает на точный вопрос OPs, но я пришел сюда с тем же симптомом, но по другой причине:

у меня было .scss файлы Slick Slider включены следующим образом:

@import "../../../node_modules/slick-carousel/slick/slick.scss";

при ближайшем рассмотрении оказалось, что он пытался загрузить шрифт из недопустимого места (<host>/assets/css/fonts/slick.woff), как это было указано в таблице стилей.

Я закончил тем, что просто скопировал /font/ мой assets/css/ и вопрос был решен для меня.

так как вы используете url-loader:

url-загрузчик работает как файл-загрузчик, но может возвращать 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.

только одно последнее соображение, эта конфигурация не рекомендуется для производства. Это просто для развития легкости.

если вы используете угловые вы должны проверить, чтобы убедиться, что ваше

<base href="/"> 

тег приходит перед вашим набором таблиц стилей. Я переключил свой код с этого:

 <script src="~/bundles/style.bundle.js"></script>
 <base href="~/" />

для этого:

 <base href="~/" />
 <script src="~/bundles/style.bundle.js"></script>

и проблема была решена. Спасибо этот пост за то, что открыл мне глаза.

по состоянию на 2018 год,

use MiniCssExtractPlugin

для Webpack (>4.0) решит эту проблему.

https://github.com/webpack-contrib/mini-css-extract-plugin

используя extract-text-webpack-plugin в принятом ответе это не рекомендуется для Webpack 4.0+.

Comments

    Ничего не найдено.