mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-02-05 06:28:31 -06:00
102 lines
12 KiB
Markdown
102 lines
12 KiB
Markdown
# Совместимость с браузерами
|
||
|
||
## browserslist
|
||
|
||
Вы заметите поле `browserslist` в файле `package.json` (или файл `.browserslistrc`), где определяется диапазон браузеров под которые разрабатывается проект. Эти значения будут использоваться в [@babel/preset-env][babel-preset-env] и [autoprefixer][autoprefixer] для автоматического определения возможностей JavaScript, которые требуется транспилировать, а также необходимые префиксные правила CSS.
|
||
|
||
Как указывается диапазон браузеров, можно узнать [здесь][browserslist].
|
||
|
||
## Полифилы
|
||
|
||
По умолчанию проект Vue CLI использует [@vue/babel-preset-app][babel-preset-app], в котором используется `@babel/preset-env` и конфигурация `browserslist` для определения необходимых полифилов.
|
||
|
||
### useBuiltIns: 'usage'
|
||
|
||
По умолчанию в `@babel/preset-env` будет передаваться [`useBuiltIns: 'usage'`](https://new.babeljs.io/docs/en/next/babel-preset-env.html#usebuiltins-usage) для автоматического определения необходимых полифилов, основываясь на том, какие возможности языка были использованы в исходном коде проекта. Это гарантирует, что в финальную сборку попадёт только минимально необходимое количество полифилов. Однако это также означает, что **если одна из ваших зависимостей имеет специфичные требования к полифилам, то по умолчанию Babel не сможет это определить.**
|
||
|
||
Если одной из ваших зависимостей требуются полифилы, у вас есть несколько вариантов:
|
||
|
||
1. **Если зависимость написана в версии ES, которую не поддерживают целевые окружения:** Добавьте эту зависимость в опцию [`transpileDependencies`](../config/#transpiledependencies) в файле `vue.config.js`. Это позволит использовать как синтаксические преобразования, так и определение полифилов для используемых возможностей для этой зависимости.
|
||
|
||
2. **Если зависимость предоставляет ES5 код и явно перечисляет необходимые полифилы:** вы можете предварительно включить необходимые полифилы с помощью опции [polyfills](https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/babel-preset-app#polyfills) для `@vue/babel-preset-app`. **Обратите внимание, что `es.promise` добавлен по умолчанию, так как он часто необходим для библиотек, основанных на Promise.**
|
||
|
||
```js
|
||
// babel.config.js
|
||
module.exports = {
|
||
presets: [
|
||
['@vue/app', {
|
||
polyfills: [
|
||
'es.promise',
|
||
'es.symbol'
|
||
]
|
||
}]
|
||
]
|
||
}
|
||
```
|
||
|
||
::: tip Совет
|
||
Рекомендуется добавлять полифилы таким образом, а не напрямую импортировать их в коде, потому что полифилы перечисленные здесь, могут быть автоматически исключены, если целевым браузерам, указанным в `browserslist`, они не нужны.
|
||
:::
|
||
|
||
3. **Если зависимость предоставляет ES5 код, но использует возможности ES6+ без явного перечисления необходимых полифилов (например, Vuetify):** Используйте `useBuiltIns: 'entry'` и затем добавьте `import 'core-js/stable'; import 'regenerator-runtime/runtime';` в файл точки входа. Это будет импортировать **ВСЕ** полифилы на основе целей, перечисленных в `browserslist`, так что вам больше не нужно будет беспокоиться о полифилах для зависимостей, но это скорее всего увеличит размер финальной сборки некоторыми неиспользуемыми полифилами.
|
||
|
||
Подробнее можно изучить в [документации @babel/preset-env](https://new.babeljs.io/docs/en/next/babel-preset-env.html#usebuiltins-usage).
|
||
|
||
### Полифилы при сборке библиотеки или веб-компонентов
|
||
|
||
При использовании Vue CLI для [сборки библиотеки или веб-компонентов](./build-targets.md) рекомендуется указывать `useBuiltIns: false` для `@vue/babel-preset-app`, чтобы отключить автоматическое добавление полифилов. Это гарантирует, что вы не добавляете ненужные полифилы в свой код, потому что полифилами должно будет заниматься приложение, где они будут использоваться.
|
||
|
||
## Современный режим
|
||
|
||
Благодаря Babel мы можем использовать все новейшие возможности языка ES2015+, но это также означает, что нам необходимо предоставлять транспилированную сборку с полифилами для поддержки старых браузеров. Эти транспилированные сборки зачастую больше в размере, чем оригинальный исходный код в ES2015+, а их парсинг и выполнение происходит медленнее. Учитывая, что сегодня у большинства современных браузеров есть прекрасная поддержка ES2015, становится пустой тратой необходимость предоставлять более тяжёлый и менее эффективный код для них лишь потому, что мы должны поддерживать старые версии браузеров.
|
||
|
||
Vue CLI предоставляет «Современный режим», чтобы помочь в решении этой проблемы. При сборке для production с помощью следующей команды:
|
||
|
||
```bash
|
||
vue-cli-service build --modern
|
||
```
|
||
|
||
Vue CLI будет собирать **две версии** вашего приложения: первая сборка для современных браузеров, которые поддерживают [ES-модули](https://jakearchibald.com/2017/es-modules-in-browsers/), а вторая сборка для старых браузеров, которые не имеют такой поддержки.
|
||
|
||
Приятная часть заключается в том, что ничего специально делать при публикации не требуется. Сгенерированный HTML-файл автоматически использует технику, описанную в классном [посте Филлипа Уолтона](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/):
|
||
|
||
- Современная сборка загружается с помощью `<script type="module">` в браузерах, которые поддерживают модули; они также предзагружаются через `<link rel="modulepreload">`.
|
||
|
||
- Сборка для старых браузеров загружается с помощью тега `<script nomodule>`, который игнорируется браузерами, поддерживающими ES-модули.
|
||
|
||
- Исправление ошибки для `<script nomodule>` в Safari 10 также внедряется автоматически.
|
||
|
||
Для приложения Hello World современная сборка на 16% меньше. В production использование современной сборки приводит к значительному ускорению парсинга и исполнения кода, что повышает производительность загрузки приложения.
|
||
|
||
::: tip Совет
|
||
`<script type="module">` загружаются [всегда с помощью CORS](https://jakearchibald.com/2017/es-modules-in-browsers/#always-cors). Это значит, что ваш сервер должен возвращать корректные заголовки CORS, такие как `Access-Control-Allow-Origin: *`. Если вы хотите загружать скрипты с помощью credentials, установите опцию [crossorigin](../config/#crossorigin) в значение `use-credentials`.
|
||
|
||
Кроме того, современный режим использует инлайновый скрипт для избежания загрузки обеих сборок в Safari 10, поэтому, если вы используете строгие политики CSP, необходимо явно разрешить инлайновый скрипт с помощью:
|
||
|
||
```
|
||
Content-Security-Policy: script-src 'self' 'sha256-4RS22DYeB7U14dra4KcQYxmwt5HkOInieXK1NUMBmQI='
|
||
```
|
||
:::
|
||
|
||
::: tip Определение текущего режима в конфигурации
|
||
Иногда может потребоваться изменить конфигурацию webpack только сборки для старых браузеров или только сборки для современных браузеров.
|
||
|
||
Vue CLI использует две переменных окружения для определения этого:
|
||
|
||
* `VUE_CLI_MODERN_MODE`: флаг, что сборка была запущена с флагом `--modern`
|
||
* `VUE_CLI_MODERN_BUILD`: значение true будет, если текущая конфигурация для современной сборки. В противном случае это сборка для старых браузеров.
|
||
|
||
**Важно:** Переменные доступны только при вызове/после вызова функций `chainWebpack()` и `configureWebpack()`, (т.е. не напрямую в области видимости модуля `vue.config.js`). Это также означает, что они доступны в файле конфигурации postcss.
|
||
:::
|
||
|
||
::: warning Предостережение: Настройка плагинов webpack
|
||
Некоторые плагины, такие как `html-webpack-plugin`, `preload-plugin` и т.п., добавляются только в конфигурации для современного режима. Попытка использовать их опции в конфигурации для старых браузеров может привести к ошибке, так как этих плагинов не будет существовать.
|
||
|
||
Используйте совет выше об *Определении текущего режима в конфигурации* для управления плагинами только в соответствующем режиме, и/или проверяйте наличие плагина в конфигурации текущего режима, прежде чем использовать их опции.
|
||
:::
|
||
|
||
[autoprefixer]: https://github.com/postcss/autoprefixer
|
||
[babel-preset-env]: https://new.babeljs.io/docs/en/next/babel-preset-env.html
|
||
[babel-preset-app]: https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/babel-preset-app
|
||
[browserslist]: https://github.com/ai/browserslist
|