Что нового в Node.js 20

Node.js1 Изучение

Версия 20 Node.js была выпущена 18 апреля 2023 года. В ней рассматриваются некоторые проблемы и критические замечания, уже «решенные» Дено и Баном, в том числе новая модель разрешений и стабильный нативный тестовый движок. В этой статье рассматриваются новые возможности, доступные разработчикам, использующим самую популярную в мире среду выполнения JavaScript.

График выпуска Node.js

Node.js имеет шестимесячный график выпуска:

  • Апрельские четные выпуски (14, 16, 18 и т. д.) являются стабильными и получают обновления долгосрочной поддержки (LTS) в течение трех лет.
  • Октябрьские выпуски с нечетными номерами (15, 17, 19 и т. д.) являются более экспериментальными, и обновления часто заканчиваются через год.

Как правило, вам следует выбирать LTS-версию с четным номером, если вам не требуется конкретная функция в экспериментальной версии и вы не собираетесь обновлять ее позже. Тем не менее, Node.js 20 является новым, и веб-сайт рекомендует вам продолжить работу с версией 18, пока команда разработчиков исправит все последние проблемы.

Node.js 20 имеет следующие новые функции…

Новая модель разрешений

Бег node somescript.jsне без риска. Скрипт может делать что угодно: удалять важные файлы, отправлять личные данные на сервер или запускать майнер криптовалюты в дочернем процессе. Трудно гарантировать, что ваш собственный код ничего не сломает: можете ли вы быть уверены, что все модули и их зависимости безопасны?

Новая (экспериментальная) модель разрешений Node.js ограничивает возможности сценария. Чтобы использовать его, добавьте —experimental-permissionфлаг в свою nodeкомандную строку, а затем:

1. —allow-fs-readпредоставить доступ для чтения к файлам. Вы можете ограничить доступ для чтения к:

  • конкретные каталоги:—allow-fs-read=/tmp/
  • конкретные файлы:—allow-fs-read=/home/me/data.json
  • или шаблоны файлов с подстановочными знаками:—allow-fs-read=/home/me/*.json

2. —allow-fs-writeчтобы предоставить доступ для записи к файлам с идентичными шаблонами каталогов, файлов или подстановочных знаков.

3. —allow-child-processчтобы разрешить дочерним процессам, таким как выполнение других сценариев, возможно, написанных на других языках.

4. —allow-workerразрешить рабочие потоки, которые выполняют код Node.js параллельно основному потоку обработки.

В следующем примере somescript.jsможно читать файлы в /home/me/data/каталоге:

node --experimental-permission --allow-fs-read=/home/me/data/ somescript.js

Любая попытка записать файл, выполнить другой процесс или запустить веб-воркер вызывает ошибку ERR_ACCESS_DENIED.

Вы можете проверить разрешения в своем приложении, используя новый process.permissionобъект. Например, вот как проверить, может ли скрипт записывать файлы:

process.permission.has('fs.write');

Вот как проверить, может ли скрипт писать в определенный файл:

if ( !process.permission.has('fs.write', '/home/me/mydata.json') ) {
  console.error('Cannot write to file');
}

Управление разрешениями JavaScript было впервые представлено Deno, который предлагает детальный контроль над доступом к файлам, переменным среды, информации об операционной системе, измерению времени, сети, динамически загружаемым библиотекам и дочерним процессам. Node.js небезопасен по умолчанию, если вы не добавите —experimental-permissionфлаг. Это менее эффективно, но гарантирует, что существующие сценарии будут продолжать работать без изменений.

Собственный тестировщик

Исторически Node.js был минимальной средой выполнения, поэтому разработчики могли выбирать, какие инструменты и модули им нужны. Для запуска тестов кода требовался сторонний модуль, такой как Mocha, AVA или Jest. Хотя это привело к большому количеству вариантов, может быть трудно принять лучшее решение, а переключение инструментов может быть непростым.

Другие среды выполнения придерживались альтернативной точки зрения и предлагали встроенные инструменты, которые считались необходимыми для разработки. Deno, Bun, Go и Rust предлагают встроенные средства запуска тестов. У разработчиков есть выбор по умолчанию, но они могут выбрать альтернативу, если у их проекта есть особые требования.

В Node.js 18 появился экспериментальный инструмент запуска тестов, который теперь стабильно работает в версии 20. Нет необходимости устанавливать сторонний модуль, и вы можете создавать тестовые сценарии:

  • /test/в каталоге вашего проекта
  • назвав файл test.js, test.mjs, илиtest.cjs
  • использование test-в начале имени файла, напримерtest-mycode.js
  • использование testв конце имени файла предшествующей точки (.), дефиса ( -) или подчеркивания ( _) — например mycode-test.js, mycode_test.cjs, илиmycode.test.mjs

Затем вы можете импортировать node:testи node:assertписать функции тестирования:

// test.mjs
import { test, mock } from 'node:test';
import assert from 'node:assert';
import fs from 'node:fs';

test('my first test', (t) => {
  assert.strictEqual(1, 1);
});

test('my second test', (t) => {
  assert.strictEqual(1, 2);
});

// asynchronous test with mocking
mock.method(fs, 'readFile', async () => 'Node.js test');
test('my third test', async (t) => {
  assert.strictEqual( await fs.readFile('anyfile'), 'Node.js test' );
});

Запустите тесты node —test test.mjsи проверьте вывод:

✔ my first test (0.9792ms)
✖ my second test (1.2304ms)
  AssertionError: Expected values to be strictly equal:

  1 !== 2

      at TestContext.<anonymous> (test.mjs:10:10)
      at Test.runInAsyncScope (node:async_hooks:203:9)
      at Test.run (node:internal/test_runner/test:547:25)
      at Test.processPendingSubtests (node:internal/test_runner/test:300:27)
      at Test.postRun (node:internal/test_runner/test:637:19)
      at Test.run (node:internal/test_runner/test:575:10)
      at async startSubtest (node:internal/test_runner/harness:190:3) {
    generatedMessage: false,
    code: 'ERR_ASSERTION',
    actual: 1,
    expected: 2,
    operator: 'strictEqual'
  }

✔ my third test (0.1882ms)
ℹ tests 3
ℹ pass 2
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 72.6767

Вы можете добавить —watchфлаг для автоматического повторного запуска тестов при изменении файла:

node --test --watch test.mjs

Вы также можете запустить все тесты, найденные в проекте:

node --test

Нативное тестирование — долгожданное дополнение к среде выполнения Node.js. Меньше необходимости изучать различные сторонние API, и у меня больше нет оправданий, если я забыл добавить тесты в небольшие проекты!

Компиляция одного исполняемого приложения

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

Версия 20 предлагает экспериментальную функцию, позволяющую создавать одно исполняемое приложение (SEA), которое можно развертывать без зависимостей. Руководство объясняет процесс, хотя это немного запутанно:

1. У вас должен быть проект с одним сценарием записи. Он должен использовать CommonJS, а не модули ES.

2. Создайте файл конфигурации JSON, используемый для преобразования сценария в большой двоичный объект, который запускается внутри среды выполнения. Например sea-

{
  "main": "myscript.js",
  "output": "sea-prep.blob"
}

3. Создайте большой двоичный объект с помощью node —experimental-sea-config sea-config.json.

4. В соответствии с вашей ОС вы должны затем скопировать nodeисполняемый файл, удалить подпись двоичного файла, внедрить большой двоичный объект в двоичный файл, повторно подписать его и протестировать полученное приложение.

Пока это работает, вы ограничены более старыми проектами CommonJS и можете ориентироваться только на ту же ОС, которую используете. Это обязательно улучшится, учитывая, что превосходный компилятор Deno может создать исполняемый файл для любой платформы с помощью одной команды из исходных файлов JavaScript или TypeScript.

Вы также должны знать размер результирующего исполняемого файла. Один console.log(’Hello World’);генерирует файл размером 85 МБ, потому что Node.js (и Deno) необходимо добавить весь движок JavaScript V8 и стандартные библиотеки. Рассматриваются варианты уменьшения размеров файлов, но вряд ли они опустятся ниже 25 МБ.

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

Обновленный движок JavaScript V8

Node.js 20 включает последнюю версию движка V8, которая включает следующие функции JavaScript:

  • String.prototype.isWellFormed() : возвращается true, когда строка имеет правильный формат и не содержит одиночных (непарных) суррогатных символов.
  • String.prototype.toWellFormed() : возвращает правильно сформированную строку, которая устраняет проблемы с одиночными суррогатными символами.
  • Новый vфлаг регулярного выражения, который устраняет проблемы с регистром символов Unicode.

Разные обновления

Также доступны следующие обновления и улучшения:

  • Повышение производительности API- интерфейсов URL, native fetch() и EventTarget.
  • Улучшения загрузки модуля ES, включая экспериментальную поддержку import.meta.resolve(), которая может ограничивать ссылку пути файла модуля строкой URL.
  • Улучшения совместимости Web Crypto API
  • Дальнейший прогресс в системном интерфейсе WebAssembly (WASI), который предоставляет изолированным приложениям WASM доступ к операционной системе.
  • Официальная поддержка ARM64 в Windows

Краткое содержание

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

Дено великолепен. Он стабилен, изначально поддерживает TypeScript, сокращает время разработки, требует меньше инструментов и получает регулярные обновления. С другой стороны, это было меньше времени, в нем меньше модулей, и они часто являются более поверхностными имитациями библиотек Node.js.

Deno и Bun стоит рассмотреть для новых проектов, но существуют тысячи существующих приложений Node.js. Deno и Bun упрощают перенос кода, но отказ от Node.js не всегда дает явное преимущество.

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

Читайте также:  Процесс проектирования пользовательского интерфейса: все, что вам нужно знать
Оцените статью
bestprogrammer.ru
Добавить комментарий