Babel Boogaloo!

📑 Содержание

Этот пост устарел. См. Мои новые сообщения о компиляции кода .

Добро пожаловать в серию статей, посвященных облачным функциям для Firebase с использованием современного стека приложений (React, Apollo, GraphQL, Next.js и Firebase). Если вы не знакомы с этим стеком, читайте дальше! Если вы знакомы, ознакомьтесь с оглавлением.

Мой предыдущий пост на тему ES6 в облачных функциях для Firebase был написан довольно давно. С тех пор мы все выросли, и я тоже знаю Вавилон. Здесь я расскажу о более гибком и нерекомендуемом способе компиляции вашего JavaScript для Firebase с помощью Babel preset-env.

Если вы не знакомы с Babel и preset-env, я настоятельно рекомендую прочитать мой предыдущий пост, объясняющий, как это работает. Я написал это как ресурс, который я хотел бы существовать, когда учился.

ES6 + в облачных функциях

Вот код, который мы хотим выполнить в нашей облачной функции. Он имеет литерал шаблона ES6 и ES6 lets.

Ранее мы использовали эту команду с babel-cli для компиляции до ES5:

"package-functions": "babel 'functionsES6' --out-dir 'functions' --presets=es2015 --copy-files --ignore 'node_modules'"

Ключ здесь был preset=es2015. Этот пресет Babel компилирует ES2015 (ES6) в ES5. Наша среда выполнения Node - v6.11.5 (на момент написания), которая на 97% поддерживает спецификацию ES6 (согласно compat-table). Это имеет два значения:

  1. Узел v6.11.5 может выполнять 97% кода ES6, поэтому babel-preset-es2015 компилирует этот ES6 в ES5 без необходимости. Нам нужно скомпилировать только 3% несовместимого кода, который мы, возможно, не написали.
  2. babel-preset-es2015 скомпилирует ES6 (es2015) в ES5, а babel-preset-es2016 скомпилирует ES7 (es2016) в ES6 (es2015) »- предыдущий пост. Следовательно, использование только preset-es2015 не приведет к поддержке ES7, ES8 и т. д. Вы можете составлять пресеты, но это лишняя боль.

preset-env снимает ответственность за знание совместимости вашего кода во время выполнения. Вы просто указываете время выполнения, и он выполняет тяжелую работу по поиску минимально необходимого объема компиляции.

Почти все работает под управлением ES5, зачем беспокоиться?

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

NB: Sourcemaps можно использовать с Babel, но использовать их с Cloud Functions… интересно, так что, допустим, у нас их нет (в этом примере на самом деле нет).

Хотя скомпилированный код Babel вполне читаем, это определенно не тот код, который вы написали. В идеале вы хотели бы отлаживать и читать собственный код, который вы написали; это особенно актуально при использовании сложных новых функций, таких как async / await, и их компиляции до ES5 или ES6.

Вавилонский REPL

Babel REPL можно использовать для просмотра скомпилированного кода, выводимого Babel с различными предустановками. Давайте теперь взглянем на код:

  1. Наш оригинальный пример с синтаксисом модуля CommonJS вместо синтаксиса модуля ES:

Он удаляет строку шаблона, const и let и преобразует стрелочную функцию в обычную функцию. Прохладный.

2. С синтаксисом модуля ES:

Добавление синтаксиса модуля ES import и export добавляет некоторого раздувания к нашему коду, особенно это касается импорта пространства имен * на L23.

3–5. Следующие 3 примера будут использовать следующий код в качестве входных данных. Мы собираемся поэкспериментировать с некоторыми из предустановок:

Дружественное сочетание async / await (синтаксис модуля CommonJS для краткости).

3. Компиляция с использованием только preset-es2015:

Подождите минутку?! Это не составило async (L25) или await (L26), в чем дело ?!

Что ж, ES6 не поддерживает async / await, а preset-es2015 компилирует только ES6 в ES5. Когда Babel сталкивается с чем-то, что не умеет компилировать, он оставляет все как есть.

4. Компиляция с preset-es2015, preset-es2016 и preset-es2017 для достижения компиляции ES8- ›ES7-› ES6- ›ES5.

Успех! Теперь он компилирует этот async / await! К сожалению, в нашей облачной функции есть множество раздутий из-за того, что async / await становится функцией генератора, а затем функция генератора компилируется в ES5. Но Node v6.11.5 поддерживает функции генератора, поэтому компилировать НЕ НУЖНО.

Если бы только был способ ...

5. Минимальная компиляция для версий Node с preset-env:

Здесь вы можете видеть на L67 / 68, что функция генератора с yield используется вместо async/await. Функция генератора была полностью скомпилирована в последнем примере, но не в этот раз! Вы также можете видеть, что наша строка шаблона, lets и consts не скомпилирована. Супер!

Попробуйте скопировать входной код из этих сущностей и поиграйте с предустановками в REPL самостоятельно.

Использование preset-env с облачными функциями

Ключевые изменения, которые нам нужно сделать, чтобы добавить preset-env:

  1. добавить preset-env:
yarn add @babel/preset-env @babel/cli -D

2. создайте .babelrc файл в корне проекта со следующим содержимым:

{
  "presets": [
    ["@babel/env", {
      "targets": {
        "node": "6.11.5"
      }
    }]
  ]
}

3. обновите нашу базу кода, чтобы структура папок выглядела так:

package.json
src/.babelrc
src/functions/index.js - from - firebaseFunctions/index.js

4. обновите наши сценарии npm (удаление части preset= сценария Babel означает, что интерфейс командной строки будет искать наш .babelrc файл):

"build-funcs": "babel src/functions --out-dir dist/functions",

Прочтите мой предыдущий пост, чтобы узнать больше об использовании preset-env. Если вы уже разбираетесь на высоком уровне, настоятельно рекомендую вам RTFM 😄.

Полный пример репозитория, использующего preset-env для транспиляции облачной функции с помощью async / await, можно найти в этом репозитории:



Заключение

Приносим извинения за поддержку preset-es2015, я не знал, что это было так близко к прекращению поддержки. Пожалуйста, используйте preset-env. Ориентируйтесь на свою среду, компилируйте только то, что вам нужно, и отправьте как можно больше нативного кода.

Хотите еще что-нибудь почитать?

Подробнее о функциях ES и Babel:

Еще я:

Если вы нашли это полезным, порекомендуйте и поделитесь с друзьями и коллегами.