У меня есть приложение, которое использует UIkit, Less для локального стиля и Vite для инструментов внешнего интерфейса (комплектации и многого другого). Я не уверен, что это актуально, но это приложение Vue 2/Webpack, которое я обновляю до Vue 3/Vite.
В соответствии с Документация UIkit Less мы импортируем файл UIkit uikit.theme.less
в файл baseless нашего проекта. Таблицы стилей UIkit имеют некоторые относительные пути к файлам SVG, которые запускаются через data-uri
функция less (примеры ниже). Это отлично работало с Webpack, но с Vite это не совсем работает. Насколько я понимаю, для небольших файлов data-uri
будет кодировать ресурс UTF-8 и, по сути, встраивать его — по крайней мере, это то, что мы получили в наших пакетах Webpack. Но с нашей сборкой Vite кажется, что эти относительные пути изображений не разрешаются, поэтому data-uri
возвращается к url()
, и мы получаем 404 для изображений.
Например, в коде UIkit путь относительный к изображению счетчика определяется как здесь; он используется в select.uk-select
. И здесь этот путь передается миксину .svg-fill
(здесь). Когда мы связываем код с помощью Vite или запускаем локальный сервер разработки, результат будет таким:
background-image: url(../../images/backgrounds/form-select.svg);
Это, конечно, не загружается, потому что каталог «images» относится к файлу form.less
. В Webpack вывод был таким, как ожидалось:
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='24' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23001c30' d='M12 1 9 6h6zM12 13 9 8h6z'/%3E%3C/svg%3E");
Для этого типа вопроса я обычно добавляю фрагмент кода HTML/CSS/JS; однако я не думаю, что SO поддерживает Vite. Таким образом, я включаю небольшой Stackblitz, который минимально демонстрирует проблему: https://stackblitz.com/edit/vite-esqmqc?file=main.js Пожалуйста, посмотрите main.js
, style.less
и обратите внимание, что в консоли есть ошибка 404, жалующаяся на вышеупомянутый файл form-select.svg
.
Если вопрос не ясен, как я могу заставить Vite разрешать изображения, которые относятся к зависимости в node_modules
?
Заранее спасибо.
Обходной путь — настроить resolve.alias
так, чтобы он указывал ../../images
на uikit/src/images
(что разрешает пакет uikit
в node_modules/
). Это говорит Vite, как разрешить ошибку проблемные относительные пути изображений.
Конфигурация resolve.alias
передается @rollup/plugin-alias
как entries
. Каждая запись может иметь пользовательский преобразователь, который можно использовать только для замены импорта из UIKit. Однако для этого требуется, чтобы импорт uikit.theme.less
был в собственном файле, чтобы пользовательский преобразователь мог правильно идентифицировать импортера, чтобы определить, когда заменить импорт.
uikit.theme.less
в отдельный файл и импортируйте его из main.js
(не из style.less
):// style.less
// @import './node_modules/uikit/src/less/uikit.theme.less'; ❌ move to own file
// my-uikit.less
@import './node_modules/uikit/src/less/uikit.theme.less';
// main.js
import './style.less';
import './my-uikit.less';
vite.config.js
со следующей конфигурацией:// vite.config.js
import { defineConfig } from 'vite';
import { fileURLToPath } from 'url';
import { basename } from 'path';
export default defineConfig({
resolve: {
alias: [
{
find: '../../images',
replacement: '',
customResolver(updatedId, importer, resolveOptions) {
// don't replace if importer is not our my-uikit.less
if (basename(importer) !== 'my-uikit.less') {
return '../../images';
}
return fileURLToPath(
new URL(
'./node_modules/uikit/src/images' + updatedId,
import.meta.url
)
);
},
},
],
},
})
Я принимаю это как ответ, поскольку он обеспечивает хороший обходной путь, и это заставило наш проект двигаться. Тем не менее, проблема, IMO, в ошибке в Vite. Я исправил ошибку и подал PR (github.com/vitejs/vite/pull/7400), который был принят и должен быть выпущен в версии 3.0.