Перейти к содержимому

Babel polyfill что это

  • автор:

@babel/polyfill

�� As of Babel 7.4.0, this package has been deprecated in favor of directly including core-js/stable (to polyfill ECMAScript features):

JavaScript

import "core-js/stable"; 

If you are compiling generators or async function to ES5, and you are using a version of @babel/core or @babel/plugin-transform-regenerator older than 7.18.0 , you must also load the regenerator runtime package. It is automatically loaded when using @babel/preset-env ‘s useBuiltIns: «usage» option or @babel/plugin-transform-runtime .

Babel includes a polyfill that includes a custom regenerator runtime and core-js.

This means you can use new built-ins like Promise or WeakMap , static methods like Array.from or Object.assign , instance methods like Array.prototype.includes , and generator functions (provided you use the regenerator plugin). The polyfill adds to the global scope as well as native prototypes like String in order to do this.

Installation​

npm install --save @babel/polyfill 
yarn add @babel/polyfill 
pnpm add @babel/polyfill 

Because this is a polyfill (which will run before your source code), we need it to be a dependency , not a devDependency

Size​

The polyfill is provided as a convenience but you should use it with @babel/preset-env and the useBuiltIns option so that it doesn’t include the whole polyfill which isn’t always needed. Otherwise, we would recommend you import the individual polyfills manually.

TC39 Proposals​

If you need to use a proposal that is not Stage 4, @babel/polyfill will not automatically import those for you. You will have to import those from another polyfill like core-js individually. We may work towards including this as separate files in @babel/polyfill soon.

Usage in Node / Browserify / Webpack​

To include the polyfill you need to require it at the top of the entry point to your application.

Make sure it is called before all other code/require statements!

JavaScript

require("@babel/polyfill"); 

If you are using ES6’s import syntax in your application’s entry point, you should instead import the polyfill at the top of the entry point to ensure the polyfills are loaded first:

JavaScript

import "@babel/polyfill"; 

With webpack, there are multiple ways to include the polyfills:

  • When used alongside @babel/preset-env ,
    • If useBuiltIns: ‘usage’ is specified in .babelrc then do not include @babel/polyfill in either webpack.config.js entry array nor source. Note, @babel/polyfill still needs to be installed.
    • If useBuiltIns: ‘entry’ is specified in .babelrc then include @babel/polyfill at the top of the entry point to your application via require or import as discussed above.
    • If useBuiltIns key is not specified or it is explicitly set with useBuiltIns: false in your .babelrc, add @babel/polyfill directly to the entry array in your webpack.config.js .

    webpack.config.js

    module.exports =   entry: ["@babel/polyfill", "./app/js"], >; 
    • If @babel/preset-env is not used then add @babel/polyfill to webpack entry array as discussed above. It can still be added at the top of the entry point to application via import or require , but this is not recommended.

    We do not recommend that you import the whole polyfill directly: either try the useBuiltIns options or import only the polyfills you need manually (either from this package or somewhere else).

    Usage in Browser​

    Available from the dist/polyfill.js file within a @babel/polyfill npm release. This needs to be included before all your compiled Babel code. You can either prepend it to your compiled code or include it in a before it.

    NOTE: Do not require this via browserify etc, use @babel/polyfill .

    Details​

    If you are looking for something that won’t modify globals to be used in a tool/library, checkout the transform-runtime plugin. This means you won’t be able to use the instance methods mentioned above like Array.prototype.includes .

    Note: Depending on what ES2015 methods you actually use, you may not need to use @babel/polyfill or the runtime plugin. You may want to only load the specific polyfills you are using (like Object.assign ) or just document that the environment the library is being loaded in should include certain polyfills.

    Полифиллы — JS: DOM API

    DOM непрерывно развивается. Какие-то браузеры его адаптируют быстрее, какие-то медленнее. Все это не позволяет легко и непринужденно пользоваться последними новинками. Разработчикам каждый раз нужно думать, какие браузеры распространены у пользователей их проектов.

    Как выяснить, какие браузеры актуальны? Обычно об этом узнают из аналитики. Например, можно использовать Google Analytics, которая в режиме реального времени собирает данные обо всех, кто заходит на сайт.

    В особо сложных ситуациях приходится поддерживать совсем старые браузеры, которые практически ничего не могут. Такое нередко встречается в государственных организациях.

    Например, есть метод matches() , который ищет элементы по CSS-селекторам. Он поддерживается Internet Explorer, но только с девятой версии. Если в вашем проекте заявлена совместимость с восьмой версией, то на вызов этого метода мы получим ошибку:

    const div = document.querySelector('div'); div.matches('.someClass'); // Uncaught TypeError: matches is not a function 

    К счастью, JavaScript позволяет частично компенсировать недостатки старых браузеров. Благодаря прототипам разработчики могут добавить недостающую функциональность прямо в реализацию DOM. Делается это с помощью полифиллов, которые мы изучим сегодня.

    Общий принцип работы этих библиотек следующий:

    1. Проверяем наличие нужного метода или свойства
    2. Если их нет, то добавляем

    Важно, чтобы библиотека с полифиллами грузилась до выполнения любого другого кода. Только в этом случае остальной код может рассчитывать на то, что все нужные свойства будут в наличии.

    Добавление метода

    Рассмотрим пример полифилла для метода node.matches() . Он работает для всех популярных браузеров и задействует их специфику, что видно по именам свойств:

    (function(constructor)  const p = constructor.prototype; if (!p.matches)  p.matches = p.matchesSelector || p.mozMatchesSelector || p.msMatchesSelector || p.oMatchesSelector || p.webkitMatchesSelector; >; >)(window.Element); 

    После выполнения этого кода мы можем использовать метод element.matches() , не боясь, что его не будет в старых браузерах.

    Добавление свойства

    Более сложный вариант – добавление свойства ParentNode.lastElementChild . Здесь приходится программировать логику поиска нужного элемента:

    // Обратите внимание, что добавление свойства производится особым образом, // из-за которого свойство становится динамическим и ленивым // Другими словами, его значение будет вычисляться только в момент обращения if (!('lastElementChild' in document.documentElement))  Object.defineProperty(Element.prototype, 'lastElementChild',  get: function()  for (let nodes = this.children, n, i = nodes.length  1; i >= 0; --i)  if (n = nodes[i], 1 === n.nodeType)  return n; > > return null; > >); > 

    Примеры выше не совсем полные. Если бы мы посмотрели исходники соответствующих библиотек, мы бы удивились, как много кода в них. Все таки обеспечение универсальной работы во всех браузерах и всех версиях — это непростая задача.

    Чтобы проверить поддержку определенных фич в разных браузерах, можно воспользоваться ресурсом Can I use :

    А самый простой способ добавить полифиллы на сайт — это воспользоваться проектом polyfill.io .

    Кроме этого проекта, на GitHub есть много готовых полифиллов для любых частей DOM. Они разбросаны по разным репозиториям разных людей. Поэтому если вам понадобится что-то полифиллить, то сначала придется поискать нужную библиотеку.

    Иногда нам нужно просто проверить наличие определенной фичи и выполнить разный код в зависимости от результата. В такой ситуации поможет библиотека modernizr:

    // Проверяется наличие flash Modernizr.on('flash', (result) =>  if (result)  // the browser has flash > else  // the browser does not have flash > >); 

    Ядро JavaScript

    Полифиллы бывают не только для DOM. Сам JavaScript тоже непрерывно развивается.

    Многие фичи современного JavaScript настолько упростили разработку, что без них уже сложно. Поэтому практически ни один современный проект не обходится без библиотеки core-js . Она закрывает почти все возможности современного JavaScript.

    Чтобы использовать эту библиотеку, нужно установить ее как зависимость проекта и подключить ее на самом верхнем уровне приложения. И все — дальше она делает всю работу сама, поэтому нам не приходится собирать приложения через webpack:

    import 'core-js/stable'; // Другие зависимости 

    Открыть доступ

    Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

    • 130 курсов, 2000+ часов теории
    • 1000 практических заданий в браузере
    • 360 000 студентов

    Наши выпускники работают в компаниях:

    Почему вы можете обойтись без Babel

    Также приглашаем всех желающих на открытый вебинар «Код как проект — настройка окружения для разработки на JavaScript». На вебинаре участники вместе с экспертом рассмотрят основные инструменты, которые помогают делать код лучше и чище — prettier, eslint, husky.

    В наше время фронтенд-разработчики все еще тратят много времени на чрезмерную подготовку и настройку программного обеспечения. Babel воспринимается некоторыми как вынужденная необходимость, но я намерен показать вам, что это не так.

    Ознакомившись с этой статьей, вы поймете:

    • как выяснить, какие браузеры действительно требуют дополнительной поддержки в каждом конкретном случае.
    • как использовать редактор Visual Studio Code, чтобы обойтись без Babel.
    • существует другая альтернатива программного обеспечения, чтобы сделать ту же работу быстрее.
    Что такое Babel и какую проблему он решает?

    Babel — это компилятор, который преобразует ваш современный JavaScript для запуска в старых браузерах. Он также может выполнять и другие задачи, такие как преобразование синтаксиса JSX, но это не единственный инструмент для этого.

    По мере развития браузеров добавляются новые функции API и ECMAScript. Различные браузеры развиваются с разной скоростью и расставляют акценты в качестве приоритетных для разных задач. Это ставит нас перед непростым выбором: как мы можем их все поддерживать и при этом использовать современные функции? Некоторые из них будут несовместимы.

    Обычное решение заключается в том, чтобы использовать новейшие возможности и трансформировать их в более старый код, который будет понятен браузеру. Транспилирование (Transpiling — сочетание двух слов: transforming — преобразование и compiling — компиляция) описывает специализированный тип компиляции. Она имеет различные значения в разных контекстах. В нашем случае также существуют две отдельные составляющие для переноса (транспилирования).

    Разница между транспилированием (transpiling) и полифилингом (polyfilling)

    Транспилирование (Transpiling) — это процесс преобразования синтаксиса нового языка, который старые браузеры не могут понять, в старый синтаксис, который они распознают.

    Приведем пример переноса оператора let :

    // the new syntax `let` was added in ECMAScript 2015 aka ES6 let x = 11; // `let` transpiles to the old syntax `var` if your transpiler target was ES5 var x = 11;

    Полифилинг (Polyfilling) — это процесс добавления недостающих методов, свойств или API к старым браузерам путем предоставления собственной версии недостающего родного кода.

    Это можно рассматривать как дополнение недостающих элементов. Например, вот полифил (polyfill) для isNaN :

    // check if the method `isNaN` exists on the standard built-in `Number` object if (!Number.isNaN) < // if not we add our own version of the native method newer browsers provide Number.isNaN = function isNaN(x) < return x !== x; >; >

    Наилучшим способом для получения полифилов является использование core-js.

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

    Альтернатива №1: не поддерживать древние браузеры

    Если бы пользователи просто обновили свои браузеры, мы могли бы избежать хлопот, связанных с транспилированием, и они могли бы наслаждаться усовершенствованными функциями и производительностью нового браузера. К сожалению, все не так просто.

    Главный виновник — крупные корпорации, которым приходится поддерживать старое программное обеспечение. Классическим примером является Internet Explorer, который с самого начала был помехой для веб-разработок.

    Тем не менее, за последние годы многое изменилось в лучшую сторону. Теперь большинство существующих браузеров актуальны, то есть они постоянно обновляются. Microsoft продвигает свой современный браузер Edge, который, что удобно, использует тот же движок V8, как и Chrome, что означает сокращение количества поддерживаемых движков на один.

    Чтобы определить, нужно ли поддерживать определенный браузер, задайте себе следующие вопросы.

    1. Какие браузеры в настоящее время используют Ваши клиенты?

    Если у вас уже есть веб-сайт или приложение, которое обслуживает одну и ту же клиентскую базу, вы можете получить эту информацию из программы аналитики. Ниже приведены некоторые последние статистические данные с британского сайта звуковой инженерии, которым я управляю. Если бы это было JavaScript-приложение с теми же клиентами из той же категории, я бы предположил, что они будут использовать те же браузеры.

    Если у вас не установлено аналитическое программное обеспечение, вы не будете знать, какие браузеры вам нужно поддерживать. Вы должны будете сделать обоснованное предположение. Если у вас есть корпоративные клиенты, гораздо больше шансов, что вам понадобится поддержка IE11 (Internet Explorer 11), чем если бы вы занимались маркетингом для фанатов web-literate (грамотное программирование) технологий.

    Когда вы поддерживаете браузер, то принимаете на себя обязательства. Вы действительно хотите иметь лишние тесты в каждом выпуске, дополнительные инструменты для настройки и больше различных функций, чтобы это обслуживать?

    Должна быть ясная финансовая причина, чтобы пойти на все эти хлопоты. Будет ли потеря тех клиентов, которые не могут получить доступ к вашему сайту или приложению, стоить дороже, чем поддержка браузера?

    2. Какие современные функции браузера вы хотите использовать?

    Использование современных функций языка и API (Application Programming Interfaces) браузера делает написание кода проще, быстрее и интереснее. Это также делает ваш код более удобным в обслуживании.

    Если вам нравиться писать ES5 (ECMAScript) и использовать XMLHttpRequest() , тогда определенно не нужен Babel, но может потребоваться какая-нибудь специальная процедура.

    3. Какие современные функции браузера поддерживают браузеры ваших клиентов?

    Эти данные доступны через Can I use (могу ли я использовать), но это напрасная трата времени на их поиск вручную. Теперь, когда вы знаете названия браузеров, которые вы хотите поддерживать, поиск совместимых функций может быть автоматизирован с помощью удивительного приложения Browserlist (подробнее об этом в следующем разделе).

    Альтернатива № 2: Используйте eslint-plugin-compat

    Вы можете вообще избежать всего процесса переноса (transpiling) и вместо этого позволить вашему редактору кода предупредить вас, если вы используете какие-либо функции, которые слишком сложны для браузеров ваших клиентов. Это самый простой вариант, потому что он:

    • исключает любую зависимость от транспилиров (transpilers). Возвращает вам практический контроль над рабочим кодом.
    • если имеется современная функция, без которой вы не можете жить, то ее можно использовать применив полифил (polyfill).

    В противном случае, вы можете просто использовать старый синтаксис, когда это необходимо.

    Создать тест

    Прежде чем мы сможем разобраться в плюсах и минусах, надо убедиться, что наши альтернативы Babel могут выполнять ту же самую основную работу. Давайте сделаем небольшой тест.

    Ниже приведен современный код, который должна поддерживать наша целевая среда после переноса (transpiled).

    После переноса (transportation) для каждой функции есть console.assert (метод записи сообщений на консоли для пользователя), чтобы убедиться, что она работает, как положено. В случае eslint-plugin-compat вместо этого проверим, что несовместимый код помечен в linting (Linting — это процесс, выполняемый программой linter, которая анализирует исходный код на определенном языке программирования и отмечает потенциальные проблемы, такие как синтаксические ошибки, отклонения от предписанного стиля кодирования или использование конструкций, о которых известно, что они небезопасны).

    // test nullish coalescing - return right side when left side null or undefined const x = null ?? "default string"; console.assert(x === "default string"); const y = 0 ?? 42; console.assert(y === 0); // test optional chaining - return undefined on non existent property or method const adventurer = < name: "Alice", cat: < name: "Dinah", >, >; const dogName = adventurer.dog?.name; console.assert(dogName === undefined); console.assert(adventurer.someNonExistentMethod?.() === undefined); // use browser API fetch, to check linting fetch("https://jsonplaceholder.typicode.com/todos/1") .then((response) => response.json()) .then((json) => console.log(json));

    Использование eslint env свойства с помощью eslint-plugin-compat

    Нам нужен обходной путь для объединения функций языка и API браузера.

    Вы можете использовать eslint (Eslint – это утилита, проверяющая стандарты кодирования на JavaScript) для проверки синтаксиса языка. Для этого измените свойство env на es2020 .

    Для проверки совместимости API браузера используйте eslint-plugin-compat . Он использует ту же самую конфигурацию Browserlist и остальные инструменты, что и Babel.

    Полную инструкцию можно найти в eslint-plugin-compat repo. Мы воспользуемся browserlist defaults как предустановками по умолчанию. Замените их по своему выбору, основанному на аналитике.

    Что такое browserlist?

    Browserlist автоматически выбирает список браузеров, основываясь на различных критериях, которые Вы ему предоставляете.

    defaults — использует быстрый доступ к таким версиям браузеров:

    • > 0,5 процента (версии браузеров, выбранные по глобальной статистике использования)
    • Последние две версии (каждого «живого (not dead)» браузера)
    • Firefox ESR (Extended Support Release)
    • “Живые (not dead)” (браузеры без официальной поддержки и обновлений в течение 24 месяцев).

    Перейдите на GitHub, чтобы получить полный список запросов, доступных для выбора поддерживаемых браузеров.

    Настройка eslint-plugin-compat для Visual Studio Code

    Добавьте следующие пакеты в свой проект.

    npm install --save-dev eslint eslint-plugin-compat

    Добавьте следующее в package.json .

    "browserslist": [ "defaults" ]

    Создайте следующий файл .eslintrc.json или добавьте эти настройки к существующим.

    Теперь любой API браузера, несовместимый с конфигурацией browserlist в вашем package.json , отображается как ошибка linting . Вы можете отдельно контролировать, какую версию ECMAScript вы хотите поддержать, используя свойство env в файле .eslintrc.json .

    Было бы неплохо, если бы eslint-plugin-compat автоматически добавил и возможности языка, но на данный момент это является нерешённой задачей.

    IE 11 с выбранной настройкой —

    — наш API fetch() помечен.

    Поменяйте объект env на es6 .

    Вы сразу же увидите ошибку при попытке использовать nullish coalescing , который был запущен в составе Es2020.

    Альтернатива № 3: Используйте другое программное обеспечение для замены Babel

    Прежде чем рассматривать альтернативы, давайте быстро рассмотрим, как использовать Babel.

    Использование Babel для транспилирования (transpile) и полифилинга (polyfill)

    Сначала создайте директорию мини-проекта и установите нужные нам взаимосвязи.

    mkdir babel-test cd babel-test npm init -y mkdir src dist npm install --save-dev @babel/core @babel/cli @babel/preset-env npm install --save @babel/polyfill

    Добавьте следующее в свой package.json .

    "browserslist": "defaults",

    Запишите файл test.js в src , а затем выполните следующую команду.

    npx babel src --out-dir dist --presets=@babel/env

    Наконец, запустите файл, чтобы проверить, что тесты все еще работают.

    node dist/test.js

    Ошибок ввода не должно быть, но будет сказано, что fetch is not defined , так как в Node.js нет метода fetch() .

    Вот результирующий транспилированный (transpiled) код. Обратите внимание на весь лишний мусор и хлам.

    "use strict"; var _ref, _, _adventurer$dog, _adventurer$someNonEx; // test nullish coalescing - return right side when left side null or undefined var x = (_ref = null) !== null && _ref !== void 0 ? _ref : "default string"; console.assert(x === "default string"); var y = (_ = 0) !== null && _ !== void 0 ? _ : 42; console.assert(y === 0); // test optional chaining - return undefined on non existent property or method var adventurer = < name: "Alice", cat: < name: "Dinah", >, >; var dogName = (_adventurer$dog = adventurer.dog) === null || _adventurer$dog === void 0 ? void 0 : _adventurer$dog.name; console.assert(dogName === undefined); console.assert( ((_adventurer$someNonEx = adventurer.someNonExistentMethod) === null || _adventurer$someNonEx === void 0 ? void 0 : _adventurer$someNonEx.call(adventurer)) === undefined, ); // use browser API fetch, to check linting fetch("https://jsonplaceholder.typicode.com/todos/1") .then(function (response) < return response.json(); >) .then(function (json) < return console.log(json); >);
    Преимущества и недостатки использования Babel
    • Эта базовая установка была относительно несложной.
    • У Babel есть большое сообщество для поддержки и постоянных обновлений с 36.8k GitHub звездами на момент написания статьи.
    • Медленное время компиляции
    • Множество зависимостей (dependencies), даже если они являются зависимостями (dev-dependencies). (установлено 269 пакетов)
    • 39М использованного дискового пространства, как сообщает du -sh
    • 5728 установленных файлов, о чем сообщает find . -тип f | wc -l
    Использование swc для транспилирования (transpile) и полифилинга (polyfill)

    Swc — новый конкурент Babel. Он написан на языке программирования Rust и в 20 раз быстрее. Это может быть очень важно, если вы долго ждете, чтобы построить свой проект.

    Чтобы все устроить:

    mkdir swc-test cd swc-test npm init -y mkdir src dist npm install --save-dev @swc/cli @swc/core browserslist

    Добавьте следующее в свой package.json .

    "browserslist": "defaults",

    Запишите конфигурационный файл .swcrc в корневую директорию проекта.

    Запишите ваш тестовый файл в src , затем выполните следующую команду для переноса (transpile).

    npx swc src -d dist

    Запустите полученный файл, чтобы проверить, что тесты все еще работают.

    node dist/test.js

    В итоге swc-transpiled (транспилированный) файл, выглядит вот так:

    var ref, ref1; var ref2; // test nullish coalescing - return right side when left side null or undefined var x = (ref2 = null) !== null && ref2 !== void 0 ? ref2 : "default string"; console.assert(x === "default string"); var ref3; var y = (ref3 = 0) !== null && ref3 !== void 0 ? ref3 : 42; console.assert(y === 0); // test optional chaining - return undefined on non existent property or method var adventurer = < name: "Alice", cat: < name: "Dinah", >, >; var dogName = (ref = adventurer.dog) === null || ref === void 0 ? void 0 : ref.name; console.assert(dogName === undefined); console.assert( ((ref1 = adventurer.someNonExistentMethod) === null || ref1 === void 0 ? void 0 : ref1.call(ref1)) === undefined, ); // use browser API fetch, to check linting fetch("https://jsonplaceholder.typicode.com/todos/1") .then(function (response) < return response.json(); >) .then(function (json) < return console.log(json); >);
    Преимущества и недостатки использования swc
    • swc намного быстрее
    • Гораздо меньше зависимостей (установлено 43 пакета)
    • Не все функции Babel в настоящее время поддерживаются
    • Меньшая пользовательская база и количество постоянных участников

    Другие альтернативы: Google Closure Compiler и TypeScript

    Я не включил Google Closure Compiler в качестве опции, потому что он, как это ни печально, сложен в использовании. Тем не менее, он может сделать хорошую работу по транспилированию (transpile) и полифилингу (polyfill). Если у вас есть свободное время, я рекомендую вам проверить его — особенно если вы цените небольшой размер файла, так как встроенная функция минификации демонстрирует отличные результаты.

    Вы также можете использовать TypeScript для переноса (transpile) и core-js для ручной полифил (polyfill) обработки, но это неуклюжее решение, которое может с легкостью создать больше проблем, чем решить их.

    Заключение

    Вам не нужно автоматически поддерживать старые браузеры. Важно сначала взглянуть на свои аналитические данные, чтобы увидеть, какие браузеры на самом деле используют ваши клиенты.

    При необходимости Вы можете использовать функцию linting, чтобы убедиться в их совместимости друг с другом. Это избавит Вас от лишних хлопот, связанных с созданием специального сборочного процесса и транспиляции (transpilation).

    Если вы выберете автоматический перевод, то SWC будет намного быстрее, чем Babel, и будет содержать гораздо меньше зависимостей. Также есть возможность использовать Google Closure Compiler или TypeScript, но для их настройки потребуется немного больше усилий.

    LogRocket: Полная видимость ваших веб-приложений

    LogRocket — это передовое решение для мониторинга приложений, позволяющее воспроизводить проблемы так, как если бы они возникали в вашем собственном браузере. Вместо того, чтобы гадать, почему происходят ошибки, или спрашивать пользователей на скриншотах и дампах логов, LogRocket позволяет воспроизводить сеанс, чтобы быстро понять, что пошло не так. Он отлично работает с любым приложением, независимо от фреймворка, и имеет плагины для записи дополнительного контекста из Redux, Vuex и @ngrx/store.

    В дополнение к регистрации действий и состояния Redux, LogRocket записывает журналы консольных сообщений, ошибки JavaScript, следы стеков, сетевые запросы/ответы в формате заголовок + тело, метаданные браузера и пользовательские журналы. Кроме того при помощи DOM (Document Object Model) позволяет записывать страницы HTML и CSS, воссоздавая превосходные в пиксельном отношении видео даже для самых сложных одностраничных приложений.

    Узнать подробнее о курсе «JavaScript Developer. Basic».

    Смотреть открытый вебинар «Код как проект — настройка окружения для разработки на JavaScript».

    • Блог компании OTUS
    • JavaScript
    • Программирование

    javascript 1.7.7 Полифилы

    В старых IE, особенно в IE8 и ниже, ряд стандартных DOM-свойств не поддерживаются или поддерживаются плохо.

    Если говорить о современных браузерах, то они тоже не все идут «в ногу», всегда какие-то современные возможности реализуются сначала в одном, потом в другом.

    Но это не значит, что нужно ориентироваться на самый старый браузер из поддерживаемых!

    Для того, чтобы не думать об устаревших браузерах, а писать современный код, который при этом работает везде, используют полифилы.

    Полифилы

    «Полифил» (англ. polyfill) – это библиотека, которая добавляет в старые браузеры поддержку возможностей, которые в современных браузерах являются встроенными.

    Один полифил мы уже видели, когда изучали собственно JavaScript – это библиотека ES5 shim. Если её подключить, то в IE8- начинают работать многие возможности ES5. Работает она через модификацию стандартных объектов и их прототипов. Это типично для полифилов.

    В работе с DOM несовместимостей гораздо больше, как и способов их обхода.

    Что делает полифил?

    Для примера добавим в DOM поддержку свойства firstElementChild , если её нет. Здесь речь, конечно, об IE8, в других браузерах оно и так поддерживается, но пример типовой.

    Вот код для такого полифила:

    if (document.documentElement.firstElementChild === undefined) < // (1) Object.defineProperty(Element.prototype, 'firstElementChild', < // (2)get: function() < var el = this.firstChild; do < if (el.nodeType === 1) < return el; >el = el.nextSibling; > while (el); return null; > >); >

    Если этот код запустить, то firstElementChild появится у всех элементов в IE8.

    Общий вид этого полифила довольно типичен. Обычно полифил состоит из двух частей:

    1. Проверка, есть ли встроенная возможность.
    2. Эмуляция, если её нет.

    Стандарты js

    JavaScript – динамично развивающийся язык программирования. Регулярно появляются предложения о добавлении в JS новых возможностей, они анализируются, и, если предложения одобряются, то описания новых возможностей языка переносятся в черновик https://tc39.github.io/ecma262/, а затем публикуются в спецификации.

    Разработчики JavaScript-движков сами решают, какие предложения реализовывать в первую очередь. Они могут заранее добавить в браузеры поддержку функций, которые всё ещё находятся в черновике, и отложить разработку функций, которые уже перенесены в спецификацию, потому что они менее интересны разработчикам или более сложные в реализации.

    Таким образом, довольно часто реализуется только часть стандарта.

    Можно проверить текущее состояние поддержки различных возможностей JavaScript на странице https://kangax.github.io/compat-table/es6/ (нам ещё предстоит изучить многое из этого списка).

    Babel

    Когда мы используем современные возможности JavaScript, некоторые движки могут не поддерживать их. Как было сказано выше, не везде реализованы все функции.

    И тут приходит на помощь Babel.

    Babel – это транспилер. Он переписывает современный JavaScript-код в предыдущий стандарт.

    На самом деле, есть две части Babel:

    1. Во-первых, транспилер, который переписывает код. Разработчик запускает Babel на своём компьютере. Он переписывает код в старый стандарт. И после этого код отправляется на сайт. Современные сборщики проектов, такие как webpack или brunch, предоставляют возможность запускать транспилер автоматически после каждого изменения кода, что позволяет экономить время.
    2. Во-вторых, полифил.Новые возможности языка могут включать встроенные функции и синтаксические конструкции. Транспилер переписывает код, преобразовывая новые синтаксические конструкции в старые. Но что касается новых встроенных функций, нам нужно их как-то реализовать. JavaScript является высокодинамичным языком, скрипты могут добавлять/изменять любые функции, чтобы они вели себя в соответствии с современным стандартом.Термин «полифил» означает, что скрипт «заполняет» пробелы и добавляет современные функции.Два интересных хранилища полифилов:
      • core js поддерживает много функций, можно подключать только нужные.
      • polyfill.io – сервис, который автоматически создаёт скрипт с полифилом в зависимости от необходимых функций и браузера пользователя.

    Таким образом, чтобы современные функции поддерживались в старых движках, нам надо установить транспилер и добавить полифил.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *