Русский
Функции
На самом базовом уровне разработка с использованием Vite не сильно отличается от использования статического файлового сервера. Тем не менее, Vite предоставляет множество улучшений по сравнению с собственным импортом ESM для поддержки различных функций, которые обычно используются в настройках на основе сборщиков.
Разрешение зависимостей NPM и предварительное связывание
Собственный импорт ES не поддерживает импорт голых модулей, например:
js
import { someMethod } from 'my-dep'
Приведенное выше вызовет ошибку в браузере. Vite обнаружит такой импорт голых модулей во всех обслуживаемых исходных файлах и выполнит следующее:
Pre-bundle их для повышения скорости загрузки страницы и преобразования модулей CommonJS / UMD в ESM. Этап предварительной сборки выполняется с помощью esbuild и значительно ускоряет время холодного запуска Vite по сравнению с любым сборщиком на основе JavaScript.
Перепишите импорт на действительные URL-адреса, такие как
/node_modules/.vite/deps/my-dep.js?v=f3sf2ebd
, чтобы браузер мог их правильно импортировать.
Зависимости сильно кэшируются
Vite кэширует запросы зависимостей через заголовки HTTP, поэтому, если вы хотите локально отредактировать/отладить зависимость, выполните шаги здесь.
Горячая Замена Модуля (HMR)
Vite предоставляет HMR API поверх собственного ESM. Платформы с возможностями HMR могут использовать API для предоставления мгновенных и точных обновлений без перезагрузки страницы или стирания состояния приложения. Vite предоставляет сторонние интеграции HMR для Vue Single File Components и React Fast Refresh. Также существуют официальные интеграции для Preact через @prefresh/vite.
Обратите внимание, что вам не нужно настраивать их вручную — когда вы создаете приложение с помощью create-vite
, в выбранных шаблонах они уже будут предварительно настроены для вас.
TypeScript
Vite поддерживает импорт файлов .ts
из коробки.
Vite выполняет транспиляцию только для файлов .ts
и НЕ выполняет проверку типов. Предполагается, что о проверке типов заботится ваша IDE и процесс сборки (вы можете запустить tsc --noEmit
в сценарии сборки или установить vue-tsc
и запустить vue-tsc --noEmit
, чтобы также проверить свой тип файлов *.vue
).
Vite использует esbuild для преобразования TypeScript в JavaScript, что примерно в 20–30 раз быстрее, чем ванильный tsc
, а обновления HMR могут отображаться в браузере менее чем за 50 мс.
Используйте синтаксис Импорт и экспорт только для типа, чтобы избежать потенциальных проблем, таких как неправильный пакет импорта только для типа, например:
ts
import type { T } from 'only/types'
export type { T }
Параметры компилятора TypeScript
Некоторые поля конфигурации в разделе compilerOptions
в tsconfig.json
требуют особого внимания.
isolatedModules
Должно быть установлено значение true
.
Это связано с тем, что esbuild
выполняет транспиляцию только без информации о типе, он не поддерживает некоторые функции, такие как const enum и неявный импорт только типов.
Вы должны установить "isolatedModules": true
в вашем tsconfig.json
в разделе compilerOptions
, чтобы TS предупредил вас о функциях, которые не работают с изолированной транспиляцией.
Однако некоторые библиотеки (например, vue
) плохо работают с "isolatedModules": true
. Вы можете использовать "skipLibCheck": true
, чтобы временно подавить ошибки, пока они не будут исправлены вышестоящим.
useDefineForClassFields
Начиная с Vite 2.5.0, значением по умолчанию будет true
, если целью TypeScript является ESNext
. Это соответствует поведению tsc
4.3.2 и более поздних версий. Это также стандартное поведение среды выполнения ECMAScript.
Но это может быть нелогичным для тех, кто работает с другими языками программирования или более старыми версиями TypeScript. Подробнее о переходе можно прочитать в примечаниях к выпуску TypeScript 3.7.
Если вы используете библиотеку, которая сильно зависит от полей класса, будьте осторожны с ее предполагаемым использованием библиотекой.
Большинство библиотек ожидают "useDefineForClassFields": true
, например MobX, Компоненты класса Vue 8.x, и т. д.
Но несколько библиотек еще не перешли на это новое значение по умолчанию, в том числе lit-element
. В этих случаях явно установите для useDefineForClassFields
значение false
.
Другие параметры компилятора, влияющие на результат сборки
Если перенос вашей кодовой базы на "isolatedModules": true
является непреодолимым усилием, вы можете обойти это с помощью стороннего плагина, такого как rollup-plugin-friendly-type-imports. Однако этот подход официально не поддерживается Vite.
Клиентские типы
Типы Vite по умолчанию предназначены для его API Node.js. Чтобы изменить среду кода на стороне клиента в приложении Vite, добавьте файл объявления d.ts
:
typescript
/// <reference types="vite/client" />
Кроме того, вы можете добавить vite/client
в compilerOptions.types
вашего tsconfig
:
json
{
"compilerOptions": {
"types": ["vite/client"]
}
}
Это обеспечит следующие типы прокладок:
- Импорт ассетов (например, импорт файла
.svg
) - Типы для Vite-injected переменных env в
i
mport.meta.env - Типы для HMR API в
i
mport.meta.hot
TIP
Чтобы переопределить ввод по умолчанию, объявите его перед ссылкой с тройной косой чертой. Например, чтобы сделать импорт *.svg
компонентом React по умолчанию:
ts
declare module '*.svg' {
const content: React.FC<React.SVGProps<SVGElement>>
export default content
}
/// <reference types="vite/client" />
Vue
Vite обеспечивает первоклассную поддержку Vue:
- Поддержка Vue 3 SFC через @vitejs/plugin-vue
- Поддержка Vue 3 JSX через @vitejs/plugin-vue-jsx
- Поддержка Vue 2.7 через @vitejs/plugin-vue2
- Поддержка Vue < 2.7 через vite-plugin-vue2
JSX
Файлы .jsx
и .tsx
также поддерживаются по умолчанию. Транспиляция JSX также выполняется через esbuild.
Пользователи Vue должны использовать официальный плагин @vitejs/plugin-vue-jsx, который предоставляет специальные функции Vue 3, включая HMR, глобальное разрешение компонентов, директивы и слоты.
Если JSX не используется с React или Vue, пользовательские jsxFactory
и jsxFragment
можно настроить с помощью параметра esbuild
. Например, для Preact:
js
// vite.config.js
import { defineConfig } from 'vite'
export default defineConfig({
esbuild: {
jsxFactory: 'h',
jsxFragment: 'Fragment'
}
})
Подробнее в документации esbuild.
Вы можете внедрить помощники JSX с помощью jsxInject
(это опция только для Vite), чтобы избежать ручного импорта:
js
// vite.config.js
import { defineConfig } from 'vite'
export default defineConfig({
esbuild: {
jsxInject: `import React from 'react'`
}
})
CSS
При импорте файлов .css
их содержимое будет внедрено на страницу с помощью тега <style>
с поддержкой HMR. Вы также можете получить обработанный CSS в виде строки в качестве экспорта модуля по умолчанию.
@import
Inlining и Rebasing
Vite предварительно настроен для поддержки встраивания CSS @import
через postcss-import
. Псевдонимы Vite также учитываются для CSS @import
. Кроме того, все ссылки CSS url()
, даже если импортированные файлы находятся в разных каталогах, всегда автоматически переустанавливаются для обеспечения корректности.
Псевдонимы @import
и перебазирование URL-адресов также поддерживаются для файлов Sass и Less (смотрите Препроцессоры CSS).
PostCSS
Если проект содержит допустимую конфигурацию PostCSS (любой формат, поддерживаемый postcss-load-config, например, postcss.config.js
), он будет автоматически применяется ко всем импортированным CSS.
CSS модули
Любой файл CSS, оканчивающийся на .module.css
, считается файлом модулей CSS. Импорт такого файла вернет соответствующий объект модуля:
css
/* example.module.css */
.red {
color: red;
}
js
import classes from './example.module.css'
document.getElementById('foo').className = classes.red
Поведение модулей CSS можно настроить с помощью параметра css.modules
.
Если css.modules.localsConvention
настроен на включение локальных переменных camelCase (например, localsConvention: 'camelCaseOnly'
), вы также можете использовать именованный импорт:
js
// .apply-color -> applyColor
import { applyColor } from './example.module.css'
document.getElementById('foo').className = applyColor
Препроцессоры CSS
Поскольку Vite предназначен только для современных браузеров, рекомендуется использовать собственные переменные CSS с плагинами PostCSS, которые реализуют черновики CSSWG (например, postcss-nesting) и создавать простой CSS, соответствующий будущим стандартам.
Тем не менее, Vite обеспечивает встроенную поддержку файлов .scss
, .sass
, .less
, .styl
и .stylus
. Для них не нужно устанавливать специфичные для Vite плагины, но сам соответствующий препроцессор должен быть установлен:
bash
# .scss and .sass
npm add -D sass
# .less
npm add -D less
# .styl and .stylus
npm add -D stylus
При использовании однофайловых компонентов Vue это также автоматически включает <style lang="sass">
и др.
Vite улучшает разрешение @import
для Sass и Less, так что псевдонимы Vite также учитываются. Кроме того, относительные ссылки url()
внутри импортированных файлов Sass/Less, которые находятся в каталогах, отличных от корневого файла, также автоматически переустанавливаются для обеспечения корректности.
Перемещение псевдонимов и URL-адресов @import
не поддерживается для Stylus из-за ограничений его API.
Вы также можете использовать модули CSS в сочетании с препроцессорами, добавив .module
к расширению файла, например, style.module.scss
.
Отключение внедрения CSS на страницу
Автоматическое внедрение содержимого CSS можно отключить с помощью параметра запроса ?inline
. В этом случае обработанная строка CSS возвращается как экспорт модуля по умолчанию, как обычно, но стили не внедряются на страницу.
js
import styles from './foo.css' // will be injected into the page
import otherStyles from './bar.css?inline' // will not be injected into the page
Статические ресурсы
Импорт статического ресурса вернет разрешенный общедоступный URL-адрес при его обслуживании:
js
import imgUrl from './img.png'
document.getElementById('hero-img').src = imgUrl
Специальные запросы могут изменить способ загрузки ресурсов:
js
// Explicitly load assets as URL
import assetAsURL from './asset.js?url'
js
// Load assets as strings
import assetAsString from './shader.glsl?raw'
js
// Load Web Workers
import Worker from './worker.js?worker'
js
// Web Workers inlined as base64 strings at build time
import InlineWorker from './worker.js?worker&inline'
Дополнительные сведения см. в разделе Обработка статических ресурсов.
JSON
Файлы JSON можно импортировать напрямую — также поддерживается именованный импорт:
js
// import the entire object
import json from './example.json'
// import a root field as named exports - helps with tree-shaking!
import { field } from './example.json'
Импорт Glob
Vite поддерживает импорт нескольких модулей из файловой системы с помощью специальной функции i
:
js
const modules = import.meta.glob('./dir/*.js')
Вышеупомянутое будет преобразовано в следующее:
js
// code produced by vite
const modules = {
'./dir/foo.js': () => import('./dir/foo.js'),
'./dir/bar.js': () => import('./dir/bar.js')
}
Затем вы можете перебирать ключи объекта modules
для доступа к соответствующим модулям:
js
for (const path in modules) {
modules[path]().then((mod) => {
console.log(path, mod)
})
}
Совпадающие файлы по умолчанию загружаются с помощью динамического импорта и будут разделены на отдельные фрагменты во время сборки. Если вы предпочитаете импортировать все модули напрямую (например, полагаясь на то, что побочные эффекты в этих модулях будут применены в первую очередь), вы можете передать { eager: true }
в качестве второго аргумента:
js
const modules = import.meta.glob('./dir/*.js', { eager: true })
Вышеупомянутое будет преобразовано в следующее:
js
// code produced by vite
import * as __glob__0_0 from './dir/foo.js'
import * as __glob__0_1 from './dir/bar.js'
const modules = {
'./dir/foo.js': __glob__0_0,
'./dir/bar.js': __glob__0_1
}
Глобальный импорт как
i
также поддерживает импорт файлов в виде строк (аналогично Импортировать актив как строку) с помощью синтаксиса Импорт Reflection:
js
const modules = import.meta.glob('./dir/*.js', { as: 'raw' })
Вышеупомянутое будет преобразовано в следующее:
js
// code produced by vite
const modules = {
'./dir/foo.js': 'export default "foo"\n',
'./dir/bar.js': 'export default "bar"\n'
}
{ as: 'url' }
также поддерживается для загрузки ресурсов в виде URL-адресов.
Несколько шаблонов
Первый аргумент может быть глобальным массивом, например:
js
const modules = import.meta.glob(['./dir/*.js', './another/*.js'])
Негативные шаблоны
Также поддерживаются негативные глобальные шаблоны (с префиксом !
). Чтобы игнорировать некоторые файлы из результата, вы можете добавить к первому аргументу глобальные шаблоны исключения:
js
const modules = import.meta.glob(['./dir/*.js', '!**/bar.js'])
js
// code produced by vite
const modules = {
'./dir/foo.js': () => import('./dir/foo.js')
}
Именованный импорт
Можно импортировать только части модулей с параметрами import
.
ts
const modules = import.meta.glob('./dir/*.js', { import: 'setup' })
ts
// code produced by vite
const modules = {
'./dir/foo.js': () => import('./dir/foo.js').then((m) => m.setup),
'./dir/bar.js': () => import('./dir/bar.js').then((m) => m.setup)
}
В сочетании с eager
можно даже включить встряхивание дерева для этих модулей.
ts
const modules = import.meta.glob('./dir/*.js', { import: 'setup', eager: true })
ts
// code produced by vite:
import { setup as __glob__0_0 } from './dir/foo.js'
import { setup as __glob__0_1 } from './dir/bar.js'
const modules = {
'./dir/foo.js': __glob__0_0,
'./dir/bar.js': __glob__0_1
}
Установите для import
значение default
, чтобы импортировать экспорт по умолчанию.
ts
const modules = import.meta.glob('./dir/*.js', {
import: 'default',
eager: true
})
ts
// code produced by vite:
import __glob__0_0 from './dir/foo.js'
import __glob__0_1 from './dir/bar.js'
const modules = {
'./dir/foo.js': __glob__0_0,
'./dir/bar.js': __glob__0_1
}
Пользовательские запросы
Вы также можете использовать опцию query
, чтобы предоставить пользовательские запросы для импорта для использования другими плагинами.
ts
const modules = import.meta.glob('./dir/*.js', {
query: { foo: 'bar', bar: true }
})
ts
// code produced by vite:
const modules = {
'./dir/foo.js': () =>
import('./dir/foo.js?foo=bar&bar=true').then((m) => m.setup),
'./dir/bar.js': () =>
import('./dir/bar.js?foo=bar&bar=true').then((m) => m.setup)
}
Предостережения по глобальному импорту
Обратите внимание, что:
- Это функция только для Vite и не является стандартом для Интернета или ES.
- Шаблоны glob обрабатываются как спецификаторы импорта: они должны быть либо относительными (начинаться с
./
), либо абсолютными (начинаться с/
, разрешаться относительно корня проекта), либо псевдонимом пути (смотрите параметрresolve.alias
). - Сопоставление универсальных объектов выполняется с помощью
fast-glob
- ознакомьтесь с его документацией для поддерживаемых глобальных шаблонов. - Вы также должны знать, что все аргументы в
i
должны быть переданы как литералы. Вы НЕ можете использовать в них переменные или выражения.mport.meta.glob
Динамический импорт
Подобно glob import, Vite также поддерживает динамический импорт с переменными.
ts
const module = await import(`./dir/${file}.js`)
Обратите внимание, что переменные представляют имена файлов только на один уровень глубины. Если file
это 'foo/bar'
, импорт завершится ошибкой. Для более продвинутого использования вы можете использовать функцию glob import.
Веб-сборка
Предварительно скомпилированные файлы .wasm
можно импортировать с помощью ?init
– экспорт по умолчанию будет функцией инициализации, которая возвращает Promise экземпляра wasm:
js
import init from './example.wasm?init'
init().then((instance) => {
instance.exports.test()
})
Функция инициализации также может принимать объект imports
, который передается WebAssembly.instantiate
в качестве второго аргумента:
js
init({
imports: {
someFunc: () => {
/* ... */
}
}
}).then(() => {
/* ... */
})
В производственной сборке файлы .wasm
меньше, чем assetInlineLimit
, будут встроены как строки base64. В противном случае они будут скопированы в каталог dist как ресурс и извлечены по запросу.
WARNING
Предложение по интеграции модуля ES для WebAssembly в настоящее время не поддерживается. Используйте vite-plugin-wasm
или другие плагины сообщества, чтобы справиться с этим.
Веб-работники
Импорт с помощью конструкторов
Сценарий веб-воркера можно импортировать с помощью new Worker()
и new SharedWorker()
. По сравнению с рабочими суффиксами этот синтаксис ближе к стандартам и является рекомендуемым способом создания рабочих процессов.
ts
const worker = new Worker(new URL('./worker.js', import.meta.url))
Конструктор воркеров также принимает параметры, которые можно использовать для создания "module" вокеров:
ts
const worker = new Worker(new URL('./worker.js', import.meta.url), {
type: 'module'
})
Импорт с суффиксами запроса
Сценарий веб-воркера можно импортировать напрямую, добавив ?worker
или ?sharedworker
к запросу на импорт. Экспортом по умолчанию будет настраиваемый рабочий конструктор:
js
import MyWorker from './worker?worker'
const worker = new MyWorker()
Рабочий скрипт также может использовать операторы import
вместо importScripts()
- обратите внимание, что во время разработки это зависит от встроенной поддержки браузера и в настоящее время работает только в Chrome, но для рабочей сборки он скомпилирован.
По умолчанию рабочий скрипт будет выпущен как отдельный блок в производственной сборке. Если вы хотите встроить worker в виде строк base64, добавьте запрос inline
:
js
import MyWorker from './worker?worker&inline'
Если вы хотите получить работника как URL-адрес, добавьте запрос url
:
js
import MyWorker from './worker?worker&url'
Смотрите Параметры работника для получения подробной информации о настройке объединения всех вокеров.
Оптимизация сборки
Перечисленные ниже функции автоматически применяются как часть процесса сборки, и нет необходимости в явной настройке, если только вы не хотите их отключить.
Разделение кода CSS
Vite автоматически извлекает CSS, используемый модулями, в асинхронный блок и создает для него отдельный файл. Файл CSS автоматически загружается с помощью тега <link>
при загрузке связанного с ним асинхронного фрагмента, а асинхронный фрагмент гарантированно будет оцениваться только после загрузки CSS, чтобы избежать FOUC.
Если вы предпочитаете, чтобы весь CSS был извлечен в один файл, вы можете отключить разделение кода CSS, установив для параметра build.cssCodeSplit
значение false
.
Генерация директив предварительной загрузки
Vite автоматически генерирует директивы <link rel="modulepreload">
для входных блоков и их прямого импорта во встроенный HTML.
Оптимизация асинхронной загрузки чанков
В реальных приложениях Rollup часто генерирует "common" фрагменты — код, который используется двумя или более другими фрагментами. В сочетании с динамическим импортом довольно часто возникает следующий сценарий:
В неоптимизированных сценариях, когда импортируется асинхронный блок A
, браузер должен будет запросить и проанализировать A
прежде чем он сможет понять, что ему также нужен общий блок C
. Это приводит к дополнительному круговому обходу сети:
Entry ---> A ---> C
Vite автоматически переписывает вызовы динамического импорта с разделением кода с шагом предварительной загрузки, так что при запросе A
извлекается C
параллельно:
Entry ---> (A + C)
Для C
возможен дальнейший импорт, что приведет к еще большему количеству обращений в оба конца в неоптимизированном сценарии. Оптимизация Vite будет отслеживать весь прямой импорт, чтобы полностью исключить двусторонние операции независимо от глубины импорта.