В 2019 году Node.js исполнилось 10 лет. Количество пакетов, доступных в реестре npm, пересекло отметку в 1 миллион. С каждым годом объём загрузок самой платформы Node.js увеличивается на 40%. Ещё одной важной вехой для Node.js стало то, что этот проект присоединился к OpenJS Foundation. Благодаря этому можно ожидать улучшения состояния и стабильности проекта, а также, в целом, положительных сдвигов в области взаимодействия членов JavaScript-сообщества.



Несложно заметить то, что за короткий отрезок времени, за год, в мире Node.js произошло много всего интересного. Каждый год Node.js набирает обороты. У нас нет причин рассчитывать на что-то другое в 2020.

В следующих релизах Node.js нас ждёт множество интересных возможностей. Этот материал посвящён наиболее значительным новшествам платформы, которые могут появиться в ней в 2020 году.

Новшества Node.js 13


В начале декабря 2019 года, во время написания этого материала, Node.js 13 — это самая свежая версия данной платформы. Тут уже имеется много новых возможностей и улучшений, с которыми можно начинать экспериментировать, готовясь к наступлению нового года. Вот некоторые из них:

  • ECMAScript-модули.
  • Поддержка WebAssembly.
  • Диагностические отчёты.
  • Полная поддержка интернационализации. В частности, речь идёт о форматах даты, времени, чисел, валют.
  • Поддержка протокола QUIC.
  • Улучшение производительности JavaScript-движка V8.

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

Процесс выпуска новых версий Node.js в 2020 году


Новая мажорная версия Node.js выпускается каждые 6 месяцев. Одна — в октябре, другая — в апреле. Их называют «текущими версиями». На момент написания этого материала текущей версией Node.js является 13-я, вышедшая в октябре 2019 года.

Версии с нечётными номерами (v9, v11, v13) выпускаются каждый октябрь. Актуальны они сравнительно недолго, они не считаются готовыми для применения в продакшне. Их можно считать бета-версиями платформы. Они рассчитаны на тестирование новых возможностей и изменений, которые попадут в следующую версию Node.js с чётным номером.

Версии с чётными номерами (v8, v10, v12) выходят каждый апрель. После выпуска подобной версии прекращается выпуск обновлений для предыдущей «чётной» версии. Хотя эти версии и гораздо стабильнее «нечётных», активная работа над ними продолжается ещё 6 месяцев. В это время их можно считать находящимися в состоянии релиз-кандидата.

После того, как «чётная» версия будет доработана в течение 6 месяцев, она входит в новую стадию своего жизненного цикла, превращаясь в LTS-версию (Long-Term Support, долгосрочная поддержка). LTS-версии Node.js считаются готовыми для использования в продакшне. Следующие 12 месяцев для таких версий выпускаются исправления ошибок, обновления безопасности и другие улучшения. Делается всё это с учётом сохранения работоспособности существующих приложений.

После LTS-стадии наступает стадия сопровождения (Maintenance stage). В это время выпускаются только исправления критических ошибок и обновления безопасности. Стадия сопровождения длится 18 месяцев. После того, как это время пройдёт, соответствующая версия переходит в стадию окончания жизненного цикла (EOL, End-of-Life) и больше не поддерживается.


Жизненный цикл версий Node.js

Ожидаемый план выпуска новых версий Node.js в 2020 году


В 2020 году можно ожидать следующего плана выпуска новых версий Node.js:

Январь-март 2020

  • Текущей версией является 13.x, ведётся активная работа над ней.
  • Версии 10.x и 12.x находятся в состоянии LTS.

Апрель 2020

  • Версия 14.x становится текущей.
  • Работа над версией 13.x останавливается вскоре после выпуска 14.x.
  • Версия 10.x входит в стадию сопровождения.

Октябрь 2020

  • Выходит версия 15.x, которая становится текущей.
  • Версия 14.x входит в фазу LTS.
  • Версия 12.x переходит в стадию сопровождения.


План выпуска новых версий Node.js в 2020 году

Обратите внимание на то, что конец жизненного цикла Node.js 8 назначен на конец 2019 года. Дело в том, что эта версия платформы зависит от OpenSSL-1.0.2, а жизненный цикл этой версии OpenSSL так же оканчивается в конце 2019 года. Спланируйте перевод Node.js 8.x-приложений на Node.js 10.x или 12.x если вы ещё этого не сделали.

ECMAScript-модули


В версии 13.2.0 Node.js поддерживает и CommonJS-модули, и новые стандартные ECMAScript-модули (ES-модули) без необходимости использования каких-либо сторонних инструментов. Это означает, что разработчики наконец-то могут пользоваться инструкциями import и export, теми же самыми, которыми они, вероятно, уже пользуются при создании фронтенд-проектов на JavaScript. Кроме того, важно отметить, что ES-модули в Node.js по умолчанию работают в строгом режиме. В результате для включения этого режима не нужно добавлять в начало каждого файла "use strict";.

// файл message
async function sendMessage { ... }
export { sendMessage };

// файл index
import { sendMessage } from "./message";

Однако для того, чтобы сообщить Node.js о том, что разработчик применяет ES-модули, нужно кое-что сделать. Тут можно воспользоваться одним из двух наиболее часто применяемых способов. Первый из них заключается в том, что файлам назначают расширение .mjs. Второй — в том, что в ближайшем родительском файле package.json размещают конструкцию "type": "module".

С первым подходом всё понятно — .js-файлы переименовывают в .mjs-файлы. При использовании второго подхода в корневой файл package.json, или в package.json, помещённый в папку, содержащую ES-модули, добавляют свойство type со значением module:

{
   "type": "module"
}

Ещё одна возможность, касающаяся работы с ES-модулями, заключается в их включении в корневом файле package.json проекта и в изменении расширений файлов, использующих CommonJS-модули, на .cjs.

Лично мне кажется, что использование расширений .mjs или .cjs — это не особенно удачная идея. Поэтому мне приятно видеть то, что для работы с ES-модулями достаточно внести изменения в файл package.json.

Импорт WebAssembly-модулей


Node.js теперь поддерживает не только ES-модули, но и импорт WebAssembly-модулей (Wasm-модулей). Wasm-модуль — это файл, содержащий код в переносимом бинарном формате, который можно распарсить быстрее, чем аналогичный JavaScript-код, и выполнить со скоростью, аналогичной нативной. Wasm-модули можно создавать, разрабатывая исходный код на таких языках, как C/C++, Go, C#, Java, Python, Elixir, Rust, да и на многих других.

Поддержка WebAssembly-модулей всё ещё находится в экспериментальной стадии. Для того чтобы включить эту возможность, нужно передать Node.js специальный флаг командной строки при запуске приложения:

node --experimental-wasm-modules index.js

Рассмотрим пример. Предположим, у нас имеется библиотека для обработки изображений, реализованная в виде Wasm-модуля. Для работы с такой библиотекой в JS-коде можно поступить так:

import * as imageUtils from "./imageUtils.wasm";
import * as fs from "fs";
( async () => {
   const image = await fs.promises.readFile( "./image.png" );
   const updatedImage = await imageUtils.rotate90degrees( image );
} )();

Тут мы импортировали модуль и воспользовались имеющейся в нём функцией.

Wasm-модули в Node.js можно импортировать и пользуясь новой динамической инструкцией import():

"use strict";
const fs = require("fs");
( async () => {
   const imageUtils = await import( "./imageUtils.wasm" );
   const image = await fs.promises.readFile( "./image.png" );
   const updatedImage = await imageUtils.rotate90degrees( image );
} )();

Системный интерфейс WebAssembly


Технология WebAssembly, как и JavaScript, была разработана с учётом требований безопасности. Wasm-код выполняется в защищённом окружении, которое иногда называют «песочницей». Это позволяет защитить от такого кода операционную систему, в которой он работает. Однако в некоторых случаях Wasm-модули, работающие в среде Node.js, могут только выиграть от возможности выполнения системных вызовов.

Здесь на сцену и выходит системный интерфейс WebAssembly (WebAssembly System Interface, WASI). WASI спроектирован как стандартный интерфейс для выполнения обращений к системам, на которых выполняется Wasm-код. В роли таких систем могут выступать хост-приложения, операционные системы, и так далее.

В репозитории Node.js можно обнаружить недавний коммит, вводящий первоначальную поддержку WASI. Собственно говоря, системный интерфейс WebAssembly — это одна из интересных возможностей Node.js, появления которой можно ожидать в 2020 году.

Поддержка диагностических отчётов


Диагностические отчёты — это JSON-документы, предназначенные для людей, содержащие сведения о работе программных механизмов. Среди таких сведений могут быть стеки вызовов функций, информация об операционной системе, данные о загруженных модулях и другие полезные показатели, направленные на помощь в поддержке приложений. Подобные отчёты можно создавать при возникновении необработанных исключений, критических ошибок. Их можно формировать по сигналам от процессов или с использованием нового API process.report. Node.js можно настроить так, чтобы диагностические отчёты сохранялись бы в заданной папке с использованием заданных имён файлов.

Сейчас эта возможность носит статус экспериментальной. Для её включения нужно передать Node.js специальный флаг при запуске приложения:

node --experimental-report --report-uncaught-exception --report-filename=./diagnostics.json index.js

Расширение поддержки интернационализации


В Node.js 13.x включена полная версия библиотеки ICU (International Components for Unicode). ICU — это зрелый популярный проект. Среди множества возможностей этой библиотеки можно отметить поддержку форматирования чисел, дат, валют, вывод времени в локализованном формате. Она умеет выполнять вычисления, связанные с временными промежутками, умеет сравнивать строки и выполнять перекодировку текстов из Unicode в другие кодировки и обратно.

Некоторые другие новые возможности Node.js


Вот ещё некоторые интересные возможности Node.js, появления которых можно ожидать в 2020 году:

  • Поддержка протокола QUIC. QUIC — это современный интернет-протокол, с помощью которого можно налаживать надёжные и производительные связи между приложениями.
  • Улучшенная поддержка Python 3. В 2020 году у нас должна появиться возможность сборки Node.js-модулей и нативных модулей с использованием Python 3.
  • Обновлённая версия JS-движка V8. Версии 7.8 и 7.9 движка V8 дадут увеличение производительности приложений и поддержку Wasm.
  • Стабильный API Worker Threads. API Worker Threads позволяет распараллеливать выполнение интенсивных вычислений.

Уважаемые читатели! Чего вы больше всего ждёте от платформы Node.js в 2020 году?


Комментарии (11)


  1. ReklatsMasters
    11.12.2019 12:51
    +2

    Я ещё жду стабилизации WeakRef с финализаторами. В репе ноды уже пишут о создании умного буфер пула.
    Ещё важное нововведение 12 ноды это чтение данных из tcp сокета в статический буфер. Это реально позволит сэкономить память и повысить скорость.
    В events можно будет нормально обрабатывать асинхронные колбэки без оборачивания в try catch.
    Видел ещё pr на упакованные указатели, они сократят расход памяти на 40%. Звучит интересно, но посмотрим что будет в реальности.


  1. Cobalt
    11.12.2019 14:15

    К сожалению поддержка ECMAScript-модулей в 13.2 не очень удобно. Только сегодня с утра пытался рабочий проект запустить без Бабеля на ней, не вышло. Указал в корневом Package.json type module:

    1. При import локальных модулей почему-то надо обязательнео указывать полный путь к модулю с расширением! import model from '../models/index.js' — почему не работает стандартная конструкция не понятно
    2. При import сторонних модулей написанных как CommonJS — ругается что они не ECMAScript. Т.е их в любом случае подключать надо через require

    Вообщем пока еще все сыро и не удобно. Подождем, может к апрелю станет поудобнее


    1. ReklatsMasters
      11.12.2019 15:16

      1. Да, в браузере нет автоподстановки расширения и тут не будет. Это проблема транспайлеров, люди приучаются к неправильно реализованным стандартам.
      2. Да, это так и останется. Нельзя никак легально cjs модуль загрузить используя esm конструкции. Там есть возможность через createRequire загрузить.


      1. vvadzim
        11.12.2019 20:01

        Да, в браузере нет автоподстановки расширения и тут не будет.
        Хм. Навскидку, не вижу препятствий браузеру грузить модули со слешем на конце напр. «path/to/module/» а серверу отдавать при этом «path/to/module/index.js». В таком случае относительный импорт внутри index.js будет работать корректно.

        В спецификацию вносить это излишне, конечно.

        Но если когда-либо такое поведение станет де-факто стандартом, то полагаю и node.js подтянется.


        1. BerkutEagle
          12.12.2019 07:40

          Будет не очень хорошо, если «path/to/module/», «path/to/module/index» и «path/to/module/index.js» будут возвращать один и тот же файл.
          Браузер то этого не знает. Это 3 запроса, 3 файла в кэше и 3 инстанса модуля.

          import {someFunc as func1} from './path/to/module/';
          import {someFunc as func2} from './path/to/module/index.js';
          func1 === func2 //false
          


    1. JustDont
      11.12.2019 15:58

      При import локальных модулей почему-то надо обязательнео указывать полный путь к модулю с расширением!

      Потому что вообще-то это нужно делать согласно спецификации. На фронте этого никто не делает, потому что там всегда пишутся alias, которые затем при транспиляции или даже в import-map через подстановку превратятся в полные пути. Но если этот сахар выкинуть, то в браузере (работающему согласно спецификации) без полных путей вы никуда не денетесь. В ноде так же.
      Пользуйтесь каким-нибудь инструментом, который вам обеспечит алиасы. Ну или делайте это через package.json, это будет обрабатываться правильно самой нодой (другое дело, что вешать в каждую папку с сорсами свой package.json как-то мягко говоря неудобно).

      При import сторонних модулей написанных как CommonJS — ругается что они не ECMAScript.

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


      1. mayorovp
        11.12.2019 16:52

        В браузере этого не делается потому что больно много файлов придётся скачивать. Но нода-то могла бы и воспользоваться преимуществами наличия файловой системы...


        1. JustDont
          11.12.2019 16:57
          -1

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

          … что в контексте работы кода не имеет никакого значения.


  1. QSandrew
    12.12.2019 09:50

    Что я жду от Node.JS? Во-первых, сделайте какой-нибудь плохонький визуальный интерфейс, в котором написал jquery и он подсказывает, как какую версию jquery устанавливать, а не лезть всякий раз в интернет! И плюс, какие плагины совместимы с этой версией JQuery!


    1. murzilka
      12.12.2019 11:49

      Я полагаю, что это сарказм. Но всё равно не улавливаю суть. Не могли бы вы пояснить смысл шутки?


      1. QSandrew
        12.12.2019 12:33

        npm install писать не хочу