#reactjs #babeljs #webpack-4 #preload
#reactjs #babeljs #webpack-4 #предварительная загрузка
Вопрос:
У меня есть настройка пакета webpack4 babel для веб-приложения react. В файле LESS я ссылаюсь на локальный шрифт. Этот шрифт копируется в dist
папку при сборке, а его имя файла хэшируется. Я хочу иметь возможность предварительно загружать этот шрифт.
Вот мой файл LESS:
@font-face {
font-family: 'Test';
src: url('../fonts/test.ttf') format('truetype');
font-weight: 400;
}
Я пробовал следующие подходы, но пока безуспешно:
- Добавьте пользовательский импорт в основной JS-файл моего приложения.
import(/* webpackPreload: true */ "../fonts/test.ttf");
Вот мой .babelrc
файл:
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
"@babel/plugin-syntax-dynamic-import"
]
}
Запуск webpack
нигде, насколько я могу видеть в выводимом html, не выдает указаний по предварительной загрузке — я просмотрел содержимое dist
папки и ничего не нашел.
- предварительная загрузка-webpack-plugin
Я добавляю это в свой webpack.config.js
файл:
plugins: [
new HtmlWebpackPlugin(),
new PreloadWebpackPlugin({
rel: 'preload',
as(entry) {
if (/.css$/.test(entry)) return 'style';
if (/.woff$/.test(entry)) return 'font';
if (/.png$/.test(entry)) return 'image';
return 'script';
}
})
]
Это создает предварительные загрузки для пакетов файлов JS script, но не для CSS и шрифтов.
Есть идеи о том, как заставить это работать?
Ответ №1:
удалось заставить его работать на webpack4, установив версию 3beta и используя опцию while list:
yarn add -D preload-webpack-plugin@3.0.0-beta.3
new PreloadWebpackPlugin({
rel: 'preload',
as: 'font',
include: 'allAssets',
fileWhitelist: [/.(woff2?|eot|ttf|otf)(?.*)?$/i],
}),
Ответ №2:
Публикую это, поскольку я думаю, что это может помочь кому-то в аналогичном положении — я понимаю, что это не решает описанную проблему.
Была та же проблема — не нужно было хэшировать мои файлы шрифтов, но была другая часть URL, которая не была статической. Немного по-хакерски, но решил мою проблему. Возможно, это может кому-то помочь. Теоретически вы можете создать свой собственный хэш-идентификатор и установить его в качестве переменной htmlWebpack-plugin.
В моем index.html
<html>
<head>
<link rel="preload" href="<%= htmlWebpackPlugin.options.woffSrc %>" as="font" type="font/woff" crossorigin>
<link rel="preload" href="<%= htmlWebpackPlugin.options.woff2Src %>" as="font" type="font/woff2" crossorigin>
//rest of html
webpack.prod.conf.js — обновленный HtmlWebpackPlugin
plugins: [
new HtmlWebpackPlugin({
...config,
woffSrc: `https://url.to.my.page.com/${ASSETS_FOLDER}/static/assets/fonts/GilroyRegular.woff`,
woff2Src: `https://url.to.my.page.com/${ASSETS_FOLDER}/static/assets/fonts/GilroyExtraBold.woff2`
})
]
Я рассудил, что файлам шрифтов не обязательно иметь хэш, поскольку он в основном используется для управления кэшем, и я не буду изменять файлы шрифтов, поэтому я включил хэш в моем загрузчике файлов webpack. Пожалуйста, поправьте меня, если я здесь ошибаюсь.
Наличие загрузчика:
{
test: /.(woff2?|eot|ttf|otf)(?.*)?$/,
loader: 'url-loader',
options: {
limit: 2000,
name: utils.assetsPath('assets/fonts/[name].[ext]')
}
}
Не удалось запустить плагин preload-webpack из-за ошибок сборки и устал устранять неполадки через 2 дня.
Ответ №3:
Я нашел обходной путь для этого. Это неприятно, но я думаю, что это не лучше, чем ничего. здесь я хотел только предварительно загрузить woff
и woff2
файлы.
new PreloadWebpackPlugin({
rel: 'preload',
include: 'allAssets',
fileBlacklist: [/.(js|ttf|png|eot|jpe?g|css|svg)/]
}),
Ответ №4:
Я думаю, что смог исправить это, переместив файл шрифта в мою public
папку, а затем переместив мое @font-face
определение в <style>
теги в моем index.html
файле, где я мог бы использовать %PUBLIC_URL%
для указания местоположения для Webpack:
<head>
<!-- Some stuff... -->
<link rel="preload" href="%PUBLIC_URL%/my-font-file.ttf" as="font" />
<style>
@font-face {
font-family: my-font-name;
src: url('%PUBLIC_URL%/my-font-file.ttf');
}
</style>
</head>
(находится my-font-file.ttf
в public
папке моего проекта)
Ответ №5:
Я полагаю, что для предварительной загрузки файла шрифта вы можете просто вручную указать его <link />
в вашем index.html
файле:
<link rel="preload" href="../fonts/test.ttf" as="font" type="font/ttf">
Смотрите Это для получения некоторых подробностей.
Комментарии:
1. Спасибо за ответ, но моя проблема в том, что имена файлов шрифтов хэшируются webpack, и поэтому я не знаю, какими они будут после копирования в
dist
папку. Возможно, есть способ использовать заполнитель в HTML-файле?2. Ваши файлы шрифтов будут часто меняться? Зачем вам нужно включать их в процесс компиляции вашего webpack? Я думаю, вы можете создать другую
assets
папку для размещения статических файлов, которые не нужно компилировать webpack параллельно сdist
папкой, и также обслуживать статические файлы из этой папки3. Это справедливое замечание. Шрифты не изменятся, и даже если они изменятся, копирование их после сборки webpack не потребует слишком больших усилий. Я полагаю, что ссылка на файлы шрифтов в HTML (для предварительной загрузки), а также ссылка с использованием @font-face в CSS (где они фактически будут использоваться) — это нормально, т. Е. Как только они будут предварительно загружены браузером, он не будет беспокоиться о повторном выполнении?
4. Я не думаю, что есть какой-либо другой способ предварительной загрузки шрифтов, кроме использования
link
. Таким образом, даже если вы использовали какое-либо решение для предварительной загрузки Webpack, оно просто вставило быlink
с атрибутом предварительной загрузки, который загрузил бы ваш ресурс. Итак, да, я считаю, что браузеру не следует отправлять другой запрос, если он уже предварительно загрузил ресурс, однако я думаю, вы хотели бы поместить некоторыеcache-control
заголовки, чтобы браузер кэшировал ресурс.5. Приветствия. Ваш рекомендуемый подход теперь внедрен и работает хорошо.