Slide 1

Slide 1 text

ConFoo 2023 Node.js Runtime ruyadorno.com The Renaissance

Slide 2

Slide 2 text

Ruy Adorno 
 Based in Montreal Node.js Collaborator & Releaser. 
 Working with Node.js things at Google @[email protected] The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com

Slide 3

Slide 3 text

Chronology 2022 features What’s next in 2023 ToC ConFoo 2023 ruyadorno.com The Node.js Runtime Renaissance

Slide 4

Slide 4 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Chronology

Slide 5

Slide 5 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com 2009 Ryan Dahl writes the initial implementation of the Node.js runtime

Slide 6

Slide 6 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com 2010 npm initial release

Slide 7

Slide 7 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com 2011 npm bundled with Node.js

Slide 8

Slide 8 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com 2014 io.js fork

Slide 9

Slide 9 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com 2015 Node.js Foundation announced, Node.js and io.js merged back together

Slide 10

Slide 10 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com 2015 Welcome to the Renaissance era!

Slide 11

Slide 11 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com 2017 Ruy Adorno fi rst commit to the project

Slide 12

Slide 12 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com 2018 Ryan Dahl announces the work on Deno, a new JavaScript runtime

Slide 13

Slide 13 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com 2019 Node.js Foundation and the JS Foundation merge together forming the OpenJS Foundation

Slide 14

Slide 14 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com 2020 Deno v1.0 is released

Slide 15

Slide 15 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com The end of the small core Most collaborators these days are open to the idea of adding more features in order to provide a batteries-included experience in order to improve DX.

Slide 16

Slide 16 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com 2022 Welcome to the Industrial era!

Slide 17

Slide 17 text

The Node.js Runtime Renaissance Industrialization ConFoo 2023 ruyadorno.com 2022 Welcome to the Industrial era!

Slide 18

Slide 18 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com 5 exciting recent features

Slide 19

Slide 19 text

Test Runner ConFoo 2023 ruyadorno.com The Node.js Runtime Renaissance

Slide 20

Slide 20 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Test Runner Shipped initially in v18.0.0, the test runner was initially designed to be a minimal viable test runner but has been getting more and more features since then.

Slide 21

Slide 21 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Test Runner - Mocks added in v18.13.0, v19.1.0 
 - Reporters added in v19.6.0 
 - Coverage added in v19.7.0 (this week!)

Slide 22

Slide 22 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com import assert from 'node:assert'; import test from 'node:test'; import {splitChars} from './split-chars.mjs'; test('test splitChars function', async t => { const input = 'a:b:c'; const expected = ['a', 'b', 'c']; assert.deepStrictEqual( splitChars(input), expected, 'should return expected characters' ); }) test-runner.mjs

Slide 23

Slide 23 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com $ node test-runner.mjs TAP version 13 # Subtest: test splitChars function ok 1 - test splitChars function --- duration_ms: 4.859125 ... 1..1 # tests 1 # pass 1 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 59.869375 shell

Slide 24

Slide 24 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com $ node --test TAP version 13 # Subtest: test splitChars function ok 1 - test splitChars function --- duration_ms: 4.859125 ... 1..1 # tests 1 # pass 1 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 59.869375 shell

Slide 25

Slide 25 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com How the test runner finds what files to run - skip node_modules folders 
 - if a test folder is found, recursively fi nd all .js .cjs .mjs fi les 
 - in other folders, match: 
 - Files named test: ^test$ 
 - Filenames that start with test-: ^test-.+ 
 - Filenames that ends with -test: .+[\.\-\_]test$

Slide 26

Slide 26 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Learn more https://nodejs.org/dist/latest-v18.x/docs/api/test.html

Slide 27

Slide 27 text

File Watcher ConFoo 2023 ruyadorno.com The Node.js Runtime Renaissance

Slide 28

Slide 28 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com File Watcher First introduced in v18.11.0 and v16.19.0, the fi le watcher is a native way to have the node runtime reload anytime watched fi les are modi fi ed.

Slide 29

Slide 29 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com import assert from 'node:assert'; import test from 'node:test'; import {splitChars} from './split-chars.mjs'; test('test splitChars function', async t => { const input = 'a:b:c'; const expected = ['a', 'b', 'c']; assert.deepStrictEqual( splitChars(input), expected, 'should return expected characters' ); }) test-runner.mjs shell $ node --watch test-runner.mjs (node:42453) ExperimentalWarning: Watch mode is 
 an experimental feature and might change at any 
 time (Use `node --trace-warnings ...` to show where 
 the warning was created) TAP version 13 # Subtest: test splitChars function ok 1 - test splitChars function --- duration_ms: 2.681209 ... 1..1 # tests 1 # pass 1 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 6.377 Completed running 'test-runner.mjs'

Slide 30

Slide 30 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com export function splitChars(str) { return str.split(':'); } split-chars.mjs shell $ node --watch test-runner.mjs (node:42453) ExperimentalWarning: Watch mode is 
 an experimental feature and might change at any 
 time (Use `node --trace-warnings ...` to show where 
 the warning was created) TAP version 13 # Subtest: test splitChars function ok 1 - test splitChars function --- duration_ms: 2.681209 ... 1..1 # tests 1 # pass 1 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 6.377 Completed running 'test-runner.mjs'

Slide 31

Slide 31 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com export function splitChars(str) { return str.split('d'); } split-chars.mjs shell Restarting 'test-runner.mjs' TAP version 13 # Subtest: test splitChars function not ok 1 - test splitChars function --- duration_ms: 3.022458 failureType: 'testCodeFailure' error: 'should return expected characters' code: 'ERR_ASSERTION' 0: 'a' 1: 'b' 2: 'c' 0: 'a:b:c' operator: 'deepStrictEqual' ... 1..1 # tests 1 # pass 0 # fail 1 # duration_ms 6.597791 Failed running 'test-runner.mjs'

Slide 32

Slide 32 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com export function splitChars(str) { return str.split(':'); } split-chars.mjs shell Restarting 'test-runner.mjs' TAP version 13 # Subtest: test splitChars function ok 1 - test splitChars function --- duration_ms: 2.054583 ... 1..1 # tests 1 # pass 1 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 4.697125 Completed running 'test-runner.mjs'

Slide 33

Slide 33 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com More options - --watch-path specify what exact folders / fi les to watch, disable watching of imported modules 
 - --watch-preserve-output disable clearing the console when watch mode restarts the process

Slide 34

Slide 34 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Learn more https://nodejs.org/dist/latest-v18.x/docs/api/cli.html#--watch

Slide 35

Slide 35 text

Argument Parser ConFoo 2023 ruyadorno.com The Node.js Runtime Renaissance

Slide 36

Slide 36 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Argument Parser Initially added in v18.3.0 and v16.17.0, the argument parser is an opinionated way to handle command line arguments in your apps without the need of an extra package.

Slide 37

Slide 37 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Argument Parser Made in collaboration between the maintainers of yargs and Commander , two of the most popular argument parsers.

Slide 38

Slide 38 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Argument Parser Currently an experimental API but should be promoted to stable soon. Unlikely to have changes at this point.

Slide 39

Slide 39 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com import { parseArgs } from 'node:util'; const { values } = parseArgs({ options: { active: { type: 'boolean' }, pathname: { type: 'string' }, }, }); if (Object.keys(values).length) { console.table(values) } cli-parse-args.mjs

Slide 40

Slide 40 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com $ node cli-parse-args.mjs --active \ --pathname=./cli-parse-args.mjs ┌──────────┬────────────────────────┐ │ (index) │ Values │ ├──────────┼────────────────────────┤ │ active │ true │ │ pathname │ './cli-parse-args.mjs' │ └──────────┴────────────────────────┘ shell

Slide 41

Slide 41 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Highly customizable The argument parser has much more options such as support to positional values, loose mode, providing default values, etc.

Slide 42

Slide 42 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Learn more https://nodejs.org/dist/latest-v18.x/docs/api/util.html#utilparseargscon fi g

Slide 43

Slide 43 text

Fetch ConFoo 2023 ruyadorno.com The Node.js Runtime Renaissance

Slide 44

Slide 44 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Fetch After many years in the making, the fetch() method is fi nally available in Node.js starting at version v18.3.0 and up.

Slide 45

Slide 45 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com const res = await fetch('https://nodejs.org/dist/index.json', { method: 'GET', headers: [ ['Accept', 'application/json'], ], }) const data = await res.json() const versions = data .map(i => ({ version: i.version, date: i.date })) .slice(0, 10) console.table(versions) fetch-something.mjs

Slide 46

Slide 46 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com $ node fetch-something.mjs ┌─────────┬───────────┬──────────────┐ │ (index) │ version │ date │ ├─────────┼───────────┼──────────────┤ │ 0 │ 'v19.7.0' │ '2023-02-21' │ │ 1 │ 'v19.6.1' │ '2023-02-16' │ │ 2 │ 'v19.6.0' │ '2023-02-01' │ │ 3 │ 'v19.5.0' │ '2023-01-24' │ │ 4 │ 'v19.4.0' │ '2023-01-05' │ │ 5 │ 'v19.3.0' │ '2022-12-14' │ │ 6 │ 'v19.2.0' │ '2022-11-29' │ │ 7 │ 'v19.1.0' │ '2022-11-14' │ │ 8 │ 'v19.0.1' │ '2022-11-04' │ │ 9 │ 'v19.0.0' │ '2022-10-17' │ └─────────┴───────────┴──────────────┘ shell

Slide 47

Slide 47 text

Stream iterator methods and Stream Web API helpers ConFoo 2023 ruyadorno.com The Node.js Runtime Renaissance

Slide 48

Slide 48 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Stream iterator methods A variety of stream iterator methods have been introduced between v17.4.0 and v17.5.0. Some of these methods may also be available in v16.4.0.

Slide 49

Slide 49 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com import { Readable } from 'node:stream'; const s = Readable.from([1, 2, 3, 4]); const mapped = [] s.on('data', data => { mapped.push(data * 2); }) s.on('end', () => { for (const m of mapped) { console.log(m) } }) map-stream-before.mjs map-stream-iterator.mjs import { Readable } from 'node:stream'; const s = Readable.from([1, 2, 3, 4]); const mapped = s.map(i => i * 2); for await (const m of mapped) { console.log(m); }

Slide 50

Slide 50 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Web Stream API Utility Consumers Added in v16.7.0, providing helper methods to help collect stream data.

Slide 51

Slide 51 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com import { Readable } from 'node:stream'; const s = Readable .from(['a', 'b', 'c', 'd']); let res = ''; s.on('data', data => { res += data; }); s.on('end', () => { console.log(res); }); read-stream-before.mjs read-stream-utility-consumer.mjs import { Readable } from 'node:stream'; import { text } from 'node:stream/consumers'; const s = Readable .from(['a', 'b', 'c', 'd']); const res = await text(s); console.log(res);

Slide 52

Slide 52 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Web Stream API Utility Consumers There are also utility consumers for arrayBuffer , blob , buffer and json .

Slide 53

Slide 53 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Learn more https://nodejs.org/dist/latest-v18.x/docs/api/stream.html#readablemapfn-options 
 https://nodejs.org/dist/latest-v18.x/docs/api/webstreams.html#utility-consumers

Slide 54

Slide 54 text

ConFoo 2023 ruyadorno.com 2023 The Node.js Runtime Renaissance Coming up this year

Slide 55

Slide 55 text

Single Executable 
 Apps ConFoo 2023 ruyadorno.com The Node.js Runtime Renaissance

Slide 56

Slide 56 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Single Executable Apps (Just landed!) Added in v19.7.0, there’s now a way to package your app code along with the Node.js runtime so that you can distribute a single executable binary fi le.

Slide 57

Slide 57 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Learn more https://nodejs.org/docs/latest-v19.x/api/single-executable-applications.html

Slide 58

Slide 58 text

Process-based Permissions ConFoo 2023 ruyadorno.com The Node.js Runtime Renaissance

Slide 59

Slide 59 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Process-based Permissions (Work in progress) New options to restrict access to speci fi c resources (such as fi le system, child process, workers) during execution.

Slide 60

Slide 60 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Process-based Permissions Very likely to still change, this new permission model is going to be behind a fl ag: --experimental-permission

Slide 61

Slide 61 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com $ node --experimental-permission index.js node:internal/modules/cjs/loader:171 const result = internalModuleStat(filename); ^ Error: Access to this API has been restricted code: 'ERR_ACCESS_DENIED', permission: ‘FileSystemRead' $ node --experimental-permission --allow-fs-read=* --allow-fs-write=./tmp index.js Hello world! (node:19836) ExperimentalWarning: Permission is an experimental feature (Use `node --trace-warnings ...` to show where the warning was created) shell

Slide 62

Slide 62 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Learn more https://github.com/nodejs/node/pull/44004

Slide 63

Slide 63 text

The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com Want to learn even more? Join one of the Working Groups meetings: https://nodejs.org/calendar 
 Join the OpenJS Foundation Slack: https://slack-invite.openjsf.org Repository: https://github.com/nodejs/node 
 Website: https://nodejs.org

Slide 64

Slide 64 text

Merci! @[email protected] The Node.js Runtime Renaissance ConFoo 2023 ruyadorno.com