Slide 1

Slide 1 text

You may not need XXX in Node.js @shisama_ 2024/06/12 ؔ੢NodeֶԂ 11࣌ݶ໨ #kng11 ͜ͷ਺೥ͰNode.jsຊମ͕αϙʔτͨ͠ػೳͷ঺հ

Slide 2

Slide 2 text

ฏ໺ণ࢜ / Masashi Hirano X: @shisama_ αΠϘ΢ζͰϚωʔδϟʔͱϑϩϯτΤϯυΤϯδχΞ Λ͍ͯ͠·͢ɻ • Node.jsίϛολʔ • JSConf.jpɺؔ੢NodeֶԂͳͲͷελοϑ • ʰϑϩϯτΤϯυ։ൃͷͨΊͷηΩϡϦςΟೖ໳ʱ ʢᠳӭࣾʣஶऀ

Slide 3

Slide 3 text

͜ͷτʔΫͷ಺༰ • Node.jsຊମ͕αϙʔτͨ͠ػೳͷ঺հ • ͦͷػೳʹΑͬͯඞཁ͕ͳ͘ͳ͔ͬͨ΋͠Εͳ͍΋ͷͱ͍͏؍఺Ͱ Node.jsͷػೳΛ঺հ͠·͢ • ঺հ͖͠Εͳ͍ͷͰಠஅͰPick up͠·ͨ͠ • ͋͘·Ͱ You may not need ͳͷͰ঺հ͢Δ΋ͷ͕׬શʹෆཁʹͳͬ ͨͱ͸ࢥΘͳ͍

Slide 4

Slide 4 text

େ੾ͳ͜ͱͳͷͰ΋͏̍ճɻ ϢʔεέʔεʹΑͬͯ͸Node.jsຊମ ػೳ͚ͩͰΧόʔͰ͖ΔΑ͏ʹͳͬͨ ͱ͍͏࿩

Slide 5

Slide 5 text

ඞཁͳ͘ͳ͔ͬͨ΋͠Εͳ͍ٕज़͸ྺ ্࢙ॏཁͳ໾ׂΛ୲͖ͬͯͨͷͰɺ ଚ͍ଘࡏͱ͍͏લఏͰฉ͍ͯ΄͍͠

Slide 6

Slide 6 text

SNSͳͲͰൃදதʹग़ͯ͘Δಛఆͷٕ ज़ʹର͢Δ߈ܸ͸͠ͳ͍Ͱ͍ͩ͘͞ʂ

Slide 7

Slide 7 text

1. node-fetch You may not need…

Slide 8

Slide 8 text

fetch͕Node.jsʹ࣮૷͞Εͨ • Node.js v17.5.0Ͱ࣮ݧతʹ࣮૷͞Εͨ • Node.js v18.0.0͔Β͸ϑϥάͳ͠Ͱ࣮ߦՄೳ • Node.js v21.0.0͔Β͸࣮ݧ൛͔Β҆ఆ൛ʹঢ֨ const res = await fetch('https://nodejs.org/api/documentation.json'); if (res.ok) { const data = await res.json(); console.log(data); }

Slide 9

Slide 9 text

fetch͕Node.jsʹ࣮૷͞Εͨ • ͜͜਺೥ͷNode.js͸Webϒϥ΢βͱͷޓ׵ੑΛॏࢹ͍ͯ͠Δ • fetch΋ͦͷऔΓ૊ΈͷҰͭ • Ϛʔδ͸͞Ε͍ͯͳ͔͕ͬͨɺPoCஈ֊Ͱ͸node-fetchΛϥοϓɻͦ Ε͙Β͍node-fetchͷ҆ఆੑ͸ߴ͍ͱ΋ݴ͑Δɻ • ݱࡏ͸undiciͱ͍͏εΫϥον͔Β࡞ΒΕͨHTTP/1.1ΫϥΠΞϯτΛ ಺෦Ͱݺͼग़͍ͯ͠Δ

Slide 10

Slide 10 text

2. Jest/Vitest/Mocha/Ava etc. You may not need…

Slide 11

Slide 11 text

Node.jsຊମʹςετϥϯφʔ͕࣮૷͞Εͨ • Node.js v18.0.0Ͱ࣮ݧతʹ௥Ճ͞Εͨ • Node.js v20.0.0Ͱ҆ఆ൛ʹঢ֨ • “node:test”͔Βimportͯ͠࢖͏ • Jest΍MochaͳͲ͕࣋ͭඪ४తͳػೳ͸උ͍͑ͯΔ

Slide 12

Slide 12 text

• Jest΍MochaɺVitestͳͲͱ ಉ͡ه๏ͰςετΛॻ͘͜ ͱ͕Ͱ͖Δ • ωετ͢Δ͜ͱ΋Մೳ • εΩοϓ΍Todoɺonlyɺ timeoutͷઃఆͳͲ΋Մೳ • v22Ͱplan()͕௥Ճ͞ΕͯΞ αʔγϣϯͷ࣮ߦճ਺΋ݕ ࠪͰ͖ΔΑ͏ʹͳͬͨ import { describe, it } from ‘node:test'; import assert from ‘node:assert'; describe('A thing', () => { it('should work', () => { assert.strictEqual(1, 1); }); it('should be ok', () => { assert.strictEqual(2, 2); }); describe('a nested thing', () => { it('should work', () => { assert.strictEqual(3, 3); }); }); it.skip(‘should be skipped', () => { assert.strictEqual(2, 2); }); it.todo(‘should be written later'); it(‘should be passed as planned', (t) => { t.plan(2); t.assert.strictEqual(2, 2); t.assert.ok(1 === 1); }); });

Slide 13

Slide 13 text

3. dotenv You may not need…

Slide 14

Slide 14 text

—env- fi leϑϥάͰ࣮ߦ࣌ʹenvϑΝΠϧ͕ಡΈ ࠐΊΔΑ͏ʹ • v20.6.0Ͱ௥Ճ͞Ε࣮ͨݧతͳػೳ • v20.12.0Ͱෳ਺ߦʹରԠ • ࣮ߦ࣌ʹ—env- fi leͰࢦఆͨ͠ϑΝΠϧʹఆٛ͞Εͨ؀ڥม਺ΛಡΈࠐ Ή (ྫ: node —env- fi le=.env) # .env # This is a comment PORT=3000 ENV=develop

Slide 15

Slide 15 text

4. nodemon You may not need…

Slide 16

Slide 16 text

—watchϑϥάͰίʔυͷมߋΛݕ஌ͯࣗ͠ಈ తʹNode.jsΛ࠶ىಈͤ͞Δ͜ͱ͕Մೳ • v16.19.0΍v18.11.0͔Βར༻Մೳ • v22.0.0Ͱ҆ఆ൛΁ঢ֨ • ࣮ߦ࣌ʹ—watchΛ͚ͭΔ • ྫ: node —watch-path=./src —watch-path=./tests index.js • ࣮ߦதͷNode.jsͷϓϩηεʹؔ࿈͢ΔίʔυͷมߋΛݕ஌ͯࣗ͠ಈతʹNode.jsͷϓ ϩηεΛ࠶ىಈͤ͞Δ • ։ൃதʹϓϩηεͷ࠶ىಈΛखಈͰ͢Δख͕ؒল͚ͯDX͕ྑ͍

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

5. socket.io You may not need…

Slide 19

Slide 19 text

WebSocket͕Node.jsຊମʹ࣮૷͞Εͨ • v21.0.0Ͱ࣮ݧతʹ࣮૷͞Εͨ • v22.0.0Ͱ҆ఆ൛ʹঢ֨ • Webϒϥ΢βͱಉ͘͡άϩʔόϧʹWebSocket͕ఆٛ͞Ε͍ͯΔ • Webϒϥ΢βͷWebSocketͱಉ͡Α͏ʹ࢖͑Δ

Slide 20

Slide 20 text

͜Μͳײ͡Ͱimportͳ͠Ͱ࢖͑Δ const socket = new WebSocket("ws://localhost:8080"); // Connection opened socket.addEventListener("open", (event) => { socket.send("Hello Server!"); }); // Listen for messages socket.addEventListener("message", (event) => { console.log("Message from server ", event.data); });

Slide 21

Slide 21 text

6. Deno(only for permission model) You may not need…

Slide 22

Slide 22 text

Permission model ͰNode.js͔ΒෆཁͳΞΫηε Λ੍ݶ͢Δ͜ͱ͕Ͱ͖Δ • Node.js࣮ߦ࣌ʹϑϥάͰϑΝΠϧΞΫηεͳͲΛ੍ޚ͢Δ͜ͱ͕Ͱ͖Δ • v20.0.0Ͱ—allow-fs-readɺ—allow-fs-writeɺ—allow-child-processͳͲ͕ ௥Ճ͞Εͨʢ·࣮ͩݧతͳػೳʣ • ਵ࣌ —allow-addonsɺ—allow-wasiͱ͔௥Ճ͞Ε͍ͯΔ • —experimental-permissionΛ෇͚ΔͱΞΫηε੍͕ݶ͞ΕΔ • Permission model͸Denoͷ΄ΜͷҰ෦͚ͩͲ…

Slide 23

Slide 23 text

—allow-* ϑϥά͕ͳ͍ͱΤϥʔʹͳΔ $ node --experimental-permission t.js node:internal/modules/cjs/loader:162 const result = internalModuleStat(filename); ^ Error: Access to this API has been restricted at stat (node:internal/modules/cjs/loader:162:18) at Module._findPath (node:internal/modules/cjs/loader:640:16) at resolveMainPath (node:internal/modules/run_main:15:25) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/ run_main:53:24) at node:internal/main/run_main_module:23:47 { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: '/Users/rafaelgss/repos/os/node/t.js' }

Slide 24

Slide 24 text

—allow-fs-readϑϥά $ node --experimental-permission --allow-fs-read=/path/to/index.js index.js

Slide 25

Slide 25 text

7. glob (npm package) You may not need…

Slide 26

Slide 26 text

fs.glob/globSync͕࣮૷͞Εͨ • v22.0.0Ͱ௥Ճ͞Εͨʢ·࣮ͩݧతͳػೳʣ • ඇಉظ൛(Callbackܗࣜ)ɺಉظ൛(globSync())ɺPromise൛͕͋Δ const { glob } = require('node:fs'); glob('**/*.js', (err, matches) => { if (err) throw err; console.log(matches); }); /** [ 'node22/esm.js', 'node22/glob.js', 'node22/test.js', ... ] */

Slide 27

Slide 27 text

8. Dual Package (ESM/CJS) or Transpile for ESM-only package You may not need…

Slide 28

Slide 28 text

ESMͱCJSͷޓ׵ੑͷ޲্ • Node.js v22.0.0Ͱ࣮ݧతʹrequire()ͰESM͕ಡΈࠐΊΔΑ͏ʹͳͬͨ • —experimental-require-moduleϑϥά͕ඞཁ // esm.js export const foo = () => { return “bar"; }; // require.cjs const { foo } = require("./esm.js"); console.log(foo()); // bar

Slide 29

Slide 29 text

ͳͥ͜Ε·Ͱrequire()ͰESMΛಡΈࠐΊͳ͔ͬ ͨͷ͔͸Joyeeͷϒϩά͕ৄ͍͠ https://joyeecheung.github.io/blog/2024/03/18/require-esm-in-node-js/

Slide 30

Slide 30 text

Thanks.