Skip to content

API среды для плагинов

Experimental

API окружающей среды экспериментально. Во время Vite 6 мы сохраним конюшню APIS, чтобы позволить экосистеме экспериментировать и построить на ней. Мы планируем стабилизировать эти новые API с потенциальными нарушающими изменениями в Vite 7.

Ресурсы:

Пожалуйста, поделитесь с нами своими отзывами.

Доступ к текущей среде в крючках

Учитывая, что было только две среды до VITE 6 ( client и ssr ), было достаточно ssr -логического, чтобы определить текущую среду в API VITE. Крюки плагинов получили ssr логического параметра в последнем параметре параметров, и несколько API ожидали дополнительного ssr параметра для правильного ассоциирования модулей с правильной средой (например, server.moduleGraph.getModuleByUrl(url, { ssr }) ).

С появлением настраиваемых сред, у нас теперь есть единый способ получить доступ к их параметрам и экземпляру в плагинах. Крюки плагинов теперь обнажают this.environment в своем контексте, и API, которые ранее ожидали ssr логического бака, теперь оказались в соответствующей среде (например, environment.moduleGraph.getModuleByUrl(url) ).

Сервер VITE имеет общий трубопровод плагинов, но когда модуль обрабатывается, он всегда выполняется в контексте данной среды. Экземпляр environment доступен в контексте плагина.

Плагин может использовать экземпляр environment для изменения того, как обрабатывается модуль в зависимости от конфигурации для среды (к которому можно получить доступ с помощью environment.config ).

ts
  transform(code, id) {
    console.log(this.environment.config.resolve.conditions)
  }

Регистрация Новых Средств С Использованием Крючков

Плагины могут добавлять новые среды в крючке config (например, для отдельного графа модуля для RSC ):

ts
  config(config: UserConfig) {
    config.environments.rsc ??= {}
  }

Пустого объекта достаточно, чтобы зарегистрировать среду, значения по умолчанию из конфигурации среды корневого уровня.

Настройка Среды С Использованием Крючков

В то время как config Hook работает, полный список среде еще не известен, и на среды могут влиять как значения по умолчанию из конфигурации среды корневого уровня, либо явно через config.environments запись. Плагины должны устанавливать значения по умолчанию, используя config крючков. Чтобы настроить каждую среду, они могут использовать новый крючок configEnvironment . Этот крючок требуется для каждой среды с его частично разрешенной конфигурацией, включая разрешение окончательных дефолтов.

ts
  configEnvironment(name: string, options: EnvironmentOptions) {
    if (name === 'rsc') {
      options.resolve.conditions = // ...

hotUpdate крючок

  • Тип: (это: {Environment: Devenvironment}, параметры: hotupdateoptions) => массив<EnvironmentModuleNode> | пустота | Обещание <Массив<EnvironmentModuleNode> | void>
  • Смотрите также: HMR API

Крюк hotUpdate позволяет плагинам выполнять пользовательскую обработку обновлений HMR для данной среды. Когда файл меняется, алгоритм HMR запускается для каждой среды последовательно в соответствии с порядком в server.environments , поэтому hotUpdate крючок будет называется несколько раз. Крюк получает объект контекста со следующей подписью:

ts
interface HotUpdateOptions {
  type: 'create' | 'update' | 'delete'
  file: string
  timestamp: number
  modules: Array<EnvironmentModuleNode>
  read: () => string | Promise<string>
  server: ViteDevServer
}
  • this.environment - среда выполнения модуля, в которой в настоящее время обрабатывается обновление файла.

  • modules - это массив модулей в этой среде, которые влияют на измененный файл. Это массив, потому что один файл может отображать несколько обслуживаемых модулей (например, VUE SFCS).

  • read - это асинхронная функция чтения, которая возвращает содержимое файла. Это предусмотрено, потому что в некоторых системах обратный вызов изменения файла может слишком быстро стрелять, прежде чем редактор завершит обновление файла, а Direct fs.readFile вернет пустой контент. Функция чтения передается в нормализации этого поведения.

Крюк может выбрать:

  • Отфильтруйте и сузите список пораженных модулей, чтобы HMR был более точным.

  • Верните пустой массив и выполните полную перезагрузку:

    js
    hotUpdate({ modules, timestamp }) {
      if (this.environment.name !== 'client')
        return
    
      // Недейть модулей вручную
      const invalidatedModules = new Set()
      for (const mod of modules) {
        this.environment.moduleGraph.invalidateModule(
          mod,
          invalidatedModules,
          timestamp,
          true
        )
      }
      this.environment.hot.send({ type: 'full-reload' })
      return []
    }
  • Верните пустой массив и выполните полную пользовательскую обработку HMR, отправив пользовательские события клиенту:

    js
    hotUpdate() {
      if (this.environment.name !== 'client')
        return
    
      this.environment.hot.send({
        type: 'custom',
        event: 'special-update',
        data: {}
      })
      return []
    }

    Клиентский код должен зарегистрировать соответствующий обработчик, используя API HMR (это может быть введено с помощью transform крюка 0 плагина):

    js
    if (import.meta.hot) {
      import.meta.hot.on('special-update', (data) => {
        // Выполните пользовательское обновление
      })
    }

Плагины Для Каждого Оборудования

Плагин может определить, к каким средам он должен применить с функцией applyToEnvironment .

js
const UnoCssPlugin = () => {
  // Общее глобальное государство
  return {
    buildStart() {
      // Инициация по окружающей среде со слабой картой <среда, данные>
      // Используя это. Окружающая среда
    },
    configureServer() {
      // Обычно используйте глобальные крючки
    },
    applyToEnvironment(environment) {
      // вернуть True, если этот плагин должен быть активным в этой среде,
      // или вернуть новый плагин, чтобы заменить его.
      // Если крюк не используется, плагин активен во всех средах
    },
    resolveId(id, importer) {
      // применимы только к средам.
    },
  }
}

Если плагин не осведомлен об окружающей среде и имеет состояние, которое не является ключом к текущей среде, крюк applyToEnvironment позволяет легко сделать его на среду.

js
import { nonShareablePlugin } from 'non-shareable-plugin'

export default defineConfig({
  plugins: [
    {
      name: 'per-environment-plugin',
      applyToEnvironment(environment) {
        return nonShareablePlugin({ outputName: environment.name })
      },
    },
  ],
})

Выберите экспорт помощника perEnvironmentPlugin , чтобы упростить эти случаи, когда другие крючки не требуются:

js
import { nonShareablePlugin } from 'non-shareable-plugin'

export default defineConfig({
  plugins: [
    perEnvironmentPlugin('per-environment-plugin', (environment) =>
      nonShareablePlugin({ outputName: environment.name }),
    ),
  ],
})

Окружающая Среда В Строительных Крючках

Так же, как и во время DEV, крючки плагинов также получают экземпляр среды во время сборки, заменив ssr ванного. Это также работает для renderChunk , generateBundle и других крючков.

Общие Плагины Во Время Сборки

Перед Vite 6 трубопроводы плагинов работали по -другому во время Dev и Build:

  • Во время разработчика: плагины обмениваются
  • Во время сборки: плагины изолированы для каждой среды (в разных процессах: vite build , затем vite build --ssr ).

Это вынуждено обмениваться состоянием между сборкой client и ssr сборкой с помощью манифестных файлов, записанных в файловую систему. В Vite 6 мы сейчас строим все среды в одном процессе, чтобы способность плагинов и взаимосвязь между окружающей средой может быть выровнен с DEV.

В будущем (Vite 7 или 8) мы стремимся иметь полное выравнивание:

Во время сборки также будет один экземпляр ResolvedConfig , позволяющий кэшировать на всем уровне процесса сборки приложения так же, как и с WeakMap<ResolvedConfig, CachedData> во время разработки.

Для Vite 6 нам нужно сделать меньший шаг, чтобы сохранить обратную совместимость. Плагины экосистем в настоящее время используют config.build вместо environment.config.build для доступа к конфигурации, поэтому нам необходимо по умолчанию новое ResolvedConfig для окружающей среды. Проект может принять участие в обмене полной настройкой конфигурации и плагинов builder.sharedConfigBuild true

Сначала эта опция будет работать только небольшой подмножеством проектов, поэтому авторы плагинов могут использовать конкретный плагин, который будет использоваться, установив флаг sharedDuringBuild на true . Это позволяет легко обмениваться состоянием оба для обычных плагинов:

js
function myPlugin() {
  // Поделиться состоянием среди всех среда в разработке и строить
  const sharedState = ...
  return {
    name: 'shared-plugin',
    transform(code, id) { ... },

    // Забрать в один экземпляр для всех средств
    sharedDuringBuild: true,
  }
}

Released under the MIT License. (dev)