Начальная архитектура JavaScript, часть 3: список браузеров Webpack, сокращение транспиляции и полифил
Продолжая свою серию статей, в которых рассказывается о моем личном путешествии по созданию архитектуры для JavaScript на традиционном веб-сайте, сегодня я перехожу к тонкой настройке веб-пакета и устранению недостающей части полифилла.
Для справки предыдущие статьи здесь:
- Стартовая архитектура JavaScript для общего веб-сайта (часть 1)
- Начальная архитектура JavaScript, часть 2: зелье полифила
Во второй части я повторил механизмы загрузки полифиллов для вашего веб-сайта, и сегодня я завершаю их включение в начальную архитектуру и загрузку как часть своего веб-пакета.
Ключом к этой конкретной статье является Список браузеров - спасибо всем, кто запустил этот модуль как способ стандартизации того, как наши инструменты могут определять список версий браузеров. В этом примере мы скажем, что будем поддерживать последние две версии всех браузеров, за исключением IE, мы не будем поддерживать ничего старше 11.
Конфигурация Babel - уменьшение транспиляции
Пресет env
Babel, похоже, не учитывает чтение из package.json
файла, поэтому вместо этого мы должны напрямую обновить наш .babelrc:
{ "presets": [ [ "env", { "debug": true, "targets": { "browsers": [ "last 2 versions", "not ie < 11" ] }, "useBuiltIns": true } ] ] }
Наш исходный файл .babelrc содержал {"presets": ["env"]}
, но теперь он более сложный. Важное примечание: значение предустановок стало списком списков для добавления словаря параметров к определению «env». Я какое-то время упускал этот факт, и это сводило меня с ума. Это изменение конфигурации с использованием формата списка браузеров сообщает Babel, какие именно браузеры мы хотим поддерживать: последние две версии всех браузеров, но ни одна версия Internet Explorer не ниже 11.
Предоставляя эти списки браузеров, Babel теперь может ограничить объем выполняемой транспиляции, чтобы соответствовать тому, чего не хватает этим конкретным браузерам. Например, если вы укажете только те среды, которые уже имеют встроенную поддержку стрелочных функций, Babel не потребуется их переносить.
Конфигурация Babel - реализация полифиллов
Для наших нужд полифила мы должны сделать npm install — save-dev babel-polyfill
и добавить import "babel-polyfill";
в наш входной скрипт. В нашем примере архитектуры наш сценарий входа - это наш site.js
файл. С указанными выше целями, указанием "useBuiltIns": true
в .babelrc и импортом babel-polyfill, Babel будет вычислять только те полифилы, которые необходимы выбранным браузерам. Если доступен полифилл, который изначально поддерживается всеми браузерами, он не будет включать их. Без целевого списка и без "useBuiltIns": true
Babel будет включать все доступные полифиллы.
Я включаю "debug": true
как способ увидеть, что делает Babel, когда вы выполняете npm run pack
. Если вы переключите useBuiltIns
, вы увидите, что он включает все существующие поллифиллы. Если для него установлено значение true
, он покажет вам, какие из них включены, а также для каких из указанных вами браузеров это требуется. Например, следующая строка сообщает вам, что добавлен полифилл es7.array.includes
, поскольку в Android 4.4.3 и IE 11 эта функция отсутствует:
es7.array.includes {“android”:”4.4.3",”ie”:”11"}
Когда вы посмотрите на длинный список включаемых полифилов (до 90 КБ!), Вы, вероятно, увидите большие куски вещей, которые, как вы знаете, вы не используете. Вы можете добавить "exclude": []
список имен в конфигурацию, чтобы их, ну, исключить. Обратной стороной является то, что нет способа указать ему исключить все es6.math.*
- вы должны перечислить каждый из них.
Если вы знаете, что вам нужно всего несколько, может быть проще просто import
те, которые вам нужны, в вашем сценарии входа. Имейте в виду, что вам нужно только загрузить полифиллы в ваш site.js
, и пока это первый скрипт, который вы загружаете и выполняете, все остальные скрипты на вашем сайте будут иметь доступ к этим полифилам.
В соответствии с моим текущим планом для архитектуры JavaScript это работает хорошо, потому что код всего сайта (site.js
) и код, который выполняется непосредственно на группах страниц или отдельных страницах, сосуществуют вместе.
Для справки я обновил Образец архитектуры на GitHub.
Повесть о двух Вавилонах
Выше показано направление, в котором я беру эту стартовую архитектуру, которую я разрабатываю вместе с вами. Однако на моем рабочем сайте, поскольку меня очень волнует время загрузки сайта, и я не хочу загружать кучу кода, который не нужен на странице для большинства моих посетителей, я делаю что-то другое. Вот что я там делаю:
<script> // <![CDATA[ (function() { var myNav = navigator.userAgent.toLowerCase(); if (!Object.entries || !Array.from) { document.write('<script src="/js/polyfill.min.js"></scr'+'ipt>'); } })(); // ]]> </script> <script src="/js/site.js"></script>
Почему я использую document.write? Очень просто, потому что тем, кто предпочитает использовать браузер, в котором отсутствует поддержка современного JavaScript, мне нужно загрузить эти полифилы до выполнения моего site.js
. site.js
ожидает, что функциональность будет в среде JavaScript при выполнении.
Что такое polyfill.min.js
? Это уменьшенная версия полного набора полифилов, предоставляемого babel-poly. Вы можете использовать любой полифилл, достаточный для удовлетворения ваших потребностей. Вы даже можете включить его от polyfill.io
. Вариантов много! Это одна из областей, которую я буду улучшать, поскольку мы будем использовать эту новую архитектуру на нашем сайте.
Будущее
Я все еще изучаю и развиваю свои мысли об этой архитектуре, и мой реальный site.js для моего рабочего сайта продолжает расти и развиваться. Вскоре я представлю вам некоторые из внесенных мною изменений и расскажу о своих планах относительно «групп страниц» и «одностраничного» кода JavaScript в этой архитектуре.