Недавно вышла Node 12 с кодовым именем Erbium
, долгосрочная поддержка которой (LTS) продлится с октября 2019 по апрель 2022.
В новой версии много вкусностей и улучшений рантайма. Помимо этого, учитывая, что под капотом V8, нода также получит все улучшения движка.
Поддержка import/export
Нода входит в 3 фазу на пути к ECAMScript Modules. Изначально эта фича была доступна лишь с флагом --experimental-modules
. К моменту перехода Node на LTS планируется убрать необходимость использования этого флага.
Синтаксис с использованием import/export
стал предпочтительным при работу с модулями у js разработчиков с момента стандартизации в ES6, и команда, стоящая за Node, старательно работала над нативной поддержкой. Экспериментально эта возможность была доступна с Node 8.0 с 0 фазы. Текущий релиз — это большой шаг в этом направлении. Большинство популярных браузеров уже поддерживают эту фичу с помощью <script type="module">
.
С 3 фазы будет поддержка трёх вариантов import
из ES моделуей:
1 2 3 4 5 6 7 8 |
// экспорт по умолчанию import module from 'module' // именованный экспорт import { namedExport } from 'module' // экспорт всего пространства имён import * as module from 'module' |
Ванильные модули можно экспортировать только дефолтным способом:
1 |
import module from 'cjs-library' |
Можно использовать import()
для загрузки в рантайме. import()
возвращает Promise
и работает как с ES моделями, так и с CommonJS библиотеками.
V8
Node 12 будет первоначально работать на V8 7.4 и в конечном итоге обновится до 7.6. Команда V8 согласилась предоставить ABI (Application Binary Interface). Заметными улучшениями в V8 7.4 являются улучшения производительности для более быстрого исполнения JavaScript, лучшего управления памятью и расширенной поддержки синтаксиса ECMAScript.
- Async stack traces.
- Ускоренный вызов при несоответствии числа аргументов.
- Ускоренный парсинг.
- Улучшена работа с
await
.
Async stack traces
Давайте рассмотрим этот код:
1 2 3 4 5 6 7 8 9 10 11 |
async function testAsyncStacktrace() { await killme(); return 42; } async function killme() { await Promise.resolve(); throw new Error('#Feelsbadman'); } testAsyncStacktrace().catch(error => console.log(error.stack)); |
На более старых версиях вы получите примерно такой стектрейс:
1 2 3 4 5 6 |
Error: #Feelsbadman at killme (test.js:8:11) at process._tickCallback (internal/process/next_tick.js:68:7) at Function.Module.runMain (internal/modules/cjs/loader.js:721:11) at startup (internal/bootstrap/node.js:228:19) at bootstrapNodeJSCore (internal/bootstrap/node.js:576:3) |
Как видно, в сообщении вообще нигде не упоминается testAsyncStacktrace
. А теперь флаг --async-stack-traces
включен по умолчанию, и лог будет выглядеть так:
1 2 3 |
Error: #Feelsbadman at killme (test.js:8:11) at async testAsyncStacktrace (test.js:2:5) |
Ускоренный вызов при несоответствии числа аргументов
В JavaScript вполне допустимо вызывать функции с меньшим/большим числом аргументов (т.е. передавать меньше или больше объявленных формальных параметров). В первом случае это under-application, а во втором over-application. В случае недостаточным числом аргументов параметры будут иметь значение undefined
, тогда как в случае с большим числом параметров они просто игнорируются.
Однако функции JavaScript всё еще могут получить фактические параметры с помощью объекта arguments
, rest parameters или даже с использованием нестандартизованного Function.prototype.arguments в sloppy mode функциях. В результате, движки JavaScript должны предоставлять способ получения фактических параметров. В V8 это делается с помощью методики arguments adaption. К сожалению, подобные методы сказываюся на производительности.
В некоторых сценариях V8 полностью пропускает arguments adaption, сокращая накладные расходы на вызовы до 60%.
Подробности можно узнать в документе.
Ускоренный парсинг
В Chrome достаточно большие скрипты парсятся потоково в рабочих потоках во время их загрузки. В V8 7.4 исправили проблему с производительностью декодирования UTF-8, что привело к ускорению на 8%.
Каждое падение на диаграмме представляет собой одно из улучшений производительности в потоковом анализаторе.
Улучшена работа await
Вместе с флагом --async-stack-traces
теперь по дефолту включен флаг --harmony-await-optimization
. Подробности тут.
Приватные поля классов
Доступная в V8 возможность использовать приватные поля перекочевала и в ноду. Такие поля недоступны вне класса. Для создания оных нужно перед переменной указать #
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class HelloThere { #hidden = 'Hidden'; get hidden() { return this.#hidden; } set hidden(txt) { this.#hidden = txt; } hi() { console.log(`Hello, ${this.#hidden}`); } } |
При попытке обратиться к #hidden
извне получите синтаксическую ошибку.
1 2 3 |
const hello = new HelloThere(); hello.#hidden = 'Visible'; // -> SyntaxError console.log(hello.#hidden); // -> SyntaxError |
Быстрый старт
Node 12 будет использовать кеш для встроенных библиотек перед сборкой и встраивать как бинарники. За счёт использования этого кеша основным потоком время старта сократится на 30%.
TLS и безопасность
Нода теперь поддерживает TLS 1.3, предлагающий повышенную безопасность и уменьшающий задержку. TLS 1.3 сильно изменил протокол и активно интегрируется в сеть. Благодаря внедрению TLS 1.3 повысится конфиденциальность данных пользователей, а также ускорится обработка запросов за счёт снижения времени на handshake в HTTPS. Кроме того, TLS 1.0 и 1.1 отключены по умолчанию, а из crypto
убрали deprecated методы.
Динамичный размер хипа
Ранее использовался дефолтный размер кучи V8, составляющий 700МБ (32-разрядные системы) или 1400МБ (64-разрядные системы). Теперь нода будет определять размеры кучи на основе доступной памяти, чтобы оптимизировать используемые ресурсы машины.
Возможность дампить хип
Node 12 предоставляет возможность дампить кучи, облегчая обнаружение проблем с памятью. Подробности можно посмотреть тут и тут.
Экспериментальные диагностические репорты
Нода предлагает более мощный инструменты по диагностике проблем (производительности, загрузка ЦП, памяти, сбои и т.д) прям внутри приложений, предоставляя экспериментальную фичу по отчётам.
Улучшения при работе с нативными модулями
Node 12 продолжает тренд по упрощению работы с N-API. В этой версии улучшена поддержка, в частности при работе с worker threads.
Заключение
В Node 12 много улучшений. Полный CHANGELOG можно посмотреть на Гитхабе и на самом сайте.