Как можно настроить vite для загрузки относительных изображений в таблицах стилей, импортированных из node_modules?

У меня есть приложение, которое использует 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?

Заранее спасибо.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обходной путь — настроить resolve.alias так, чтобы он указывал ../../images на uikit/src/images (что разрешает пакет uikit в node_modules/). Это говорит Vite, как разрешить ошибку проблемные относительные пути изображений.

Конфигурация resolve.alias передается @rollup/plugin-alias как entries. Каждая запись может иметь пользовательский преобразователь, который можно использовать только для замены импорта из UIKit. Однако для этого требуется, чтобы импорт uikit.theme.less был в собственном файле, чтобы пользовательский преобразователь мог правильно идентифицировать импортера, чтобы определить, когда заменить импорт.

  1. Поместите импорт 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';
  1. Создайте 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.

benbotto 05.04.2022 23:00

Другие вопросы по теме