Node.js v21 ã®ä¸»ãªå¤æ´ç¹
2023å¹´10æ17æ¥ã«ãªãªã¼ã¹ãããNode.js v21ã®ä¸»ãªå¤æ´ç¹ãç´¹ä»ãã¾ãã
ãã®è¨äºãæ¸ãã¦ããæç¹ã§ã¯v21.4.0ãææ°çã§ãã®ã§ãv21.0.0ããv21.4.0ã¾ã§ã®å¤æ´ç¹ã§æ³¨ç®ã®æ©è½ãã¾ã¨ãã¦ãã¾ãã
- fetchã¨WebStreamsãå®å®çã¸
- WebSocketã®å®é¨çãªå®è£
- navigator.language/languages ã®è¿½å
- V8 11.8 ã«ããæ°ãã JavaScript ã®æ©è½
- ESM ãããã©ã«ãåãããã©ã°
- å®è¡ãã¡ã¤ã«ãESMãªã®ãèªåå¤å®ããå®é¨çæ©è½
- import.meta.dirname/filename ã®è¿½å
- ãã¹ãã©ã³ãã¼ãglobã§ã®ãã¹ããã¡ã¤ã«æå®ã«å¯¾å¿
- è¦åï¼Warningï¼ãç¡å¹åãããã©ã°ã®è¿½å
- ãã®ä»ã®å¤æ´ç¹
- ã¾ã¨ã
- åèè¨äº
fetchã¨WebStreamsãå®å®çã¸
Webã¢ããªã±ã¼ã·ã§ã³ã®éçºè
ãªãfetchãä¸åº¦ã¯è¦ãã使ã£ããã¨ããããã¨æãã¾ãã
Node.jsã§ã¯ãfetchã¯v16.15.0ã¨v17.5.0ã§å®é¨çã«è¿½å ããã¾ããã
v18.0.0ããã¯--experimental-global-fetch
ã®ãããªãã©ã°ãä»ããªãã¦ã使ããããã«ãªãã¾ããããã¾ã å®é¨çãªæ©è½ã§ããã
v21.0.0ããã¯å®é¨çãªæ©è½ã§ã¯ãªããªãã¾ããã
88%ã®ãã¹ããééãã¦ãããããã¾ã å®å
¨ã§ã¯ããã¾ããããå®å®çã¸ã¨ææ ¼ãã¾ããã
ã¾ããWebStreamsãå®å®çã«ãªãã¾ããã
Web Streams API 㯠Webï¼ãã©ã¦ã¶ï¼ã® Stream API ã¨åãã¤ã³ã¿ã¼ãã§ã¤ã¹ãä»æ§ã«æ²¿ã£ãæ°ãã Stream ã® API ã§ãã å ã Node.js ã«ã¯ Stream API ãããã¾ãããããã©ã¦ã¶ã¨ã®äºææ§ããªã API ã§ããã Node.js 㯠Web ã¨ã®äºææ§ãéè¦ããããã«ãªããWeb ã® API ãç©æ¥µçã« Node.js æ¬ä½ã«å®è£ ãã¦ãã¾ãã ãã®ãããå¾æ¥ã® Node.js ã® Stream API ã¯æ®ãã¤ã¤ããWeb äºæ㪠Stream API ãå®è£ ãã¾ããã
詳ããã¯Node.js v18ã®å¤æ´ç¹ã®è¨äºãã覧ãã ããã
WebSocketã®å®é¨çãªå®è£
Webããã³ãã¨ã³ãéçºè ãªãWebSocketãä¸åº¦ã¯èããã使ã£ãããããã¨ãããã¨æãã¾ãããNode.jsã§ã¯ã¾ã å®é¨çãªå®è£ ã¨ãªã£ã¦ãã¾ãã
å®é¨çãªæ©è½ã®ããã--experimental-websocket
ãã©ã°ãå¿
è¦ã§ãããã©ã°ãä»ãã¦å®è¡ããã¨ãã ãWebSocket
ãªãã¸ã§ã¯ããã°ãã¼ãã«ããã¢ã¯ã»ã¹ã§ããããã«ãªã£ã¦ãã¾ãã
$ node --experimental-websocket index.js
// --experimental-websocket ãã©ã°ããªãã¨ã¨ã©ã¼ã«ãªã const socket = new WebSocket("ws://localhost:8080");
navigator.language/languages ã®è¿½å
navigator.language
ã¨navigator.languages
ã¯ãã©ã¦ã¶ã®è¨èªè¨å®ãåå¾ããAPIã§ãã
Node.jsã¯å¤è¨èªããµãã¼ããã¦ãã¾ãã
navigator.language
ã使ãã°ãå®è¡ä¸ã®Node.jsã®ããã»ã¹ã§å©ç¨ããã¦ããè¨èªãåå¾ãããã¨ãã§ãã¾ãã
console.log(navigator.language);
// en-US
navigator.languages
ã使ãã°ãå®è¡ä¸ã®Node.jsã®ããã»ã¹ã§å©ç¨å¯è½ãªè¨èªã®ä¸è¦§ãåå¾ãããã¨ãã§ãã¾ãã
console.log(navigator.languages);
// ["en-US", "zh-CN", "ja-JP"]
V8 11.8 ã«ããæ°ãã JavaScript ã®æ©è½
JavaScriptã¨ã³ã¸ã³ã§ããV8ã11.8ã«ã¢ãããã¼ããã¾ããã
ããã«ãã以ä¸ã®æ°ããJavaScriptã®æ©è½ã追å ããã¦ãã¾ãã
- Array grouping
- ArrayBuffer.prototype.transfer
- WebAssembly extended-const expressions
ããã§ã¯ã使ãæãå¤ãã¨æãããArray groupingã«ã¤ãã¦ç´¹ä»ãã¾ãã
TC39ã®proposalã«è¨è¼ã®ä»¥ä¸ã®ã³ã¼ããèªãã§ããã ãã¨ããããããã¨æãã¾ãã github.com
const array = [1, 2, 3, 4, 5]; // `Object.groupBy` ã¯ä»»æã®ãã¼ã§å¤ãã°ã«ã¼ãåãã¾ãã // 以ä¸ã¯å¥æ°(odd)ã¨å¶æ°(even)ã§ã°ã«ã¼ãåãã¦ãã¾ãã Object.groupBy(array, (num, index) => { return num % 2 === 0 ? 'even': 'odd'; }); // => { odd: [1, 3, 5], even: [2, 4] }
ESM ãããã©ã«ãåãããã©ã°
Node.jsã¯æ´å²ççµç·¯ããECMAScriptæ¨æºã§ããES Modules(ESM)ãããã©ã«ãã§æå¹ã«ãã¦ããããCommonJS(CJS)ãããã©ã«ãã§æå¹ã«ãã¦ãã¾ãã
ãã ããpackage.jsonã«"type": "module"
ãè¨è¿°ãããã¨ã§ESMãããã©ã«ãã§æå¹ã«ãããã¨ãã§ãããããã¡ã¤ã«ã®æ¡å¼µåã.mjs
ã®å ´åã¯ESMã¨ãã¦æ±ãããããã¾ãã
ããããpackage.jsonã«"type": "module"
ãè¨è¿°ããã¦ããããæ¡å¼µåã.js
ã®å ´åã¯ESMãªã®ãCJSã¦ã¼ã¶ã¼ã®æ確ãªæå®ããªãããã"ambiguous" filesï¼ææ§ãªãã¡ã¤ã«ï¼ã¨ããã¦ãã¾ãã
ããã§ãAmbiguous fileã¯åè¿°ã®ã¨ããCJSã¨ãã¦æ±ããã¦ãã¾ãããv21.0.0ã§å®é¨çã«å°å
¥ããã--experimental-default-type
ãã©ã°ã使ããã¨ã§"ambiguous" filesãESMã¨ãã¦æ±ããã¨ãã§ãã¾ãã以ä¸ã®ããã«ãã©ã°ãã¤ãã¦å®è¡ããã¨ã"ambiguous" fileãESMã¨ãã¦æ±ããã¾ãã
$ node --experimental-default-type=module index.js
ESMã®ããã©ã«ãåã«ã¤ãã¦ã¯ä»¥ä¸ã®è¨äºã詳ããã§ãã
å®è¡ãã¡ã¤ã«ãESMãªã®ãèªåå¤å®ããå®é¨çæ©è½
ãã1ã¤ESMå¨ãã®å¤æ´ç¹ã¨ãã¦ã¯ãv21.1.0ãã--experimental-detect-module
ãã©ã°ãå®é¨çã«è¿½å ããã¦ãã¾ãã
ãã®ãã©ã°ãã¤ããã¨ãpackage.jsonã®type
ãè¨å®ããã¦ããªãå ´åã§ã.js
ã®æ¡å¼µåã®ãã¡ã¤ã«ã®ä¸èº«ãè¦ã¦ãESMãCJSããå¤å¥ãã¦ããã¾ãã
$ node --experimental-detect-module index.js
ãã®å¤å¥å¦çã«ä¼´ãå®è¡æã®ããã©ã¼ãã³ã¹ãä½ä¸ããå¯è½æ§ããããããNode.jsãã¼ã ã¨ãã¦ã¯package.jsonã®type
ãè¨å®ãããã¨ãæ¨å¥¨ãã¦ãã¾ãã
import.meta.dirname/filename ã®è¿½å
ESMãå©ç¨ããã¨ãCJSã§ã¯å©ç¨å¯è½ã ã£ã__dirname
ã__filename
ãå©ç¨ã§ããªããªãã¾ãã
ããã§ã以ä¸ã®ãããªã³ã¼ããæ¸ãå¿ è¦ãããã¾ããã
// /path/to/file/index.js ããå®è¡ import url from 'url' import path from 'path' const __filename = url.fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); console.log(__filename); // /path/to/file/index.js console.log(__dirname); //path/to/file
ããã¯ç
©ãããã®ã§ãå¾æ¥ã®__dirname
ã__filename
ã¨åãããã«ç¾å¨ã®ãã£ã¬ã¯ããªã¨ãã¡ã¤ã«åã«ã¢ã¯ã»ã¹ã§ããimport.meta.dirname
ã¨import.meta.filename
ã追å ããã¾ããã
ä¸è¨ã®ã³ã¼ãã¯ä»¥ä¸ã®ããã«æ¸ãæãããã¨ãã§ãã¾ãã
// /path/to/file/index.js ããå®è¡ // const __filename = url.fileURLToPath(import.meta.url); import.meta.filename; // => /path/to/file/index.js // const __dirname = path.dirname(__filename); import.meta.dirname; // => /path/to/file
ãã¹ãã©ã³ãã¼ãglobã§ã®ãã¹ããã¡ã¤ã«æå®ã«å¯¾å¿
v18.0.0ã§Node.jsæ¬ä½ã«ãã¹ãã©ã³ãã¼ã追å ããã¾ããã shisama.hatenablog.com
JestãVitestãªã©ã®ã©ã¤ãã©ãªã使ããªãã¦ãNode.jsæ¬ä½ã®ãã¹ãã¢ã¸ã¥ã¼ã«ãå©ç¨ãããã¨ã§ä»¥ä¸ã®ãããªãã¹ããè¨è¿°ãããã¨ãã§ãã¾ãã
import test from 'node:test'; import assert from 'assert/strict'; test('top level test', async (t) => { await t.test('subtest 1', (t) => { assert.strictEqual(1, 1); }); await t.test('subtest 2', (t) => { assert.strictEqual(2, 2); }); });
ã¢ãã¯ãã¿ã¤ãã¼ã¨ãã£ãæ©è½ãåãã¦ãããã¡ãã£ã¨ãããã¹ããªãã«ãã¼ã§ããã¨æãã¾ãã詳ããã¯APIã®ä»æ§ãã確èªãã ããã
ãã®ãã¹ãã©ã³ãã¼ã§ãããv21.0.0ããã¯globã§ã®ãã¹ããã¡ã¤ã«æå®ã«å¯¾å¿ãã¾ããã
$ node --test **/*.test.js
ããã¾ã§--test
ãªã©ã®ã³ãã³ãã©ã¤ã³ãªãã·ã§ã³ã¯åå¨ãã¦ãã¾ãããã以ä¸ã®ããã«åå¥ã®ãã¡ã¤ã«åããã£ã¬ã¯ããªåãæå®ãããã¨ããã§ãã¾ããã§ããã
node --test test1.js test2.mjs custom_test_dir/
globã使ã£ããã¡ã¤ã«æå®ãã§ããããã«ãªã£ããã¨ã§ãã¹ãã®å®è¡ã¯ããç°¡åã«ãªãã¾ããã
è¦åï¼Warningï¼ãç¡å¹åãããã©ã°ã®è¿½å
Node.jsãå®è¡ããã¨ãã«ãéæ¨å¥¨ï¼Deprecatedï¼ãªæ©è½ãå®é¨çï¼Experimentalï¼ãªæ©è½ã使ã£ã¦ããã¨å®è¡æã«è¦åãåºã¾ãã
ãã®è¦åãç¡å¹åããããã®--disable-warning
ãã©ã°ã追å ããã¾ããã
以ä¸ã®ããã«ãã©ã°ãã¤ãã¦å®è¡ããã¨ãç¹å®ã®è¦åãè¦åãåºãªããªãã¾ãã
$ node --disable-warning=DEP0025 index.js
ä¸è¨ã®ããã«ã³ã¼ããæå®ãããã¨ã§ç¹å®ã®éæ¨å¥¨ãªæ©è½ã®è¦åãç¡å¹åãããã¨ãã§ãã¾ãã
éæ¨å¥¨æ©è½ã®ã³ã¼ãã«ã¤ãã¦ã¯ä»¥ä¸ã®ãªã³ã¯ãã確èªãã ããã
ã¾ããéæ¨å¥¨ãªæ©è½ãå®é¨çãªæ©è½ã®ä½¿ç¨ã«å¯¾ããè¦åãä¸æ¬ã§ç¡å¹åããããã®ãªãã·ã§ã³ãç¨æããã¦ãã¾ãã
以ä¸ã¯éæ¨å¥¨ãªæ©è½ã®è¦åãç¡å¹åããããã®ãªãã·ã§ã³ã§ãã
$ node --disable-warning=DeprecationWarning index.js
以ä¸ã¯å®é¨çãªæ©è½ã®è¦åãç¡å¹åããããã®ãªãã·ã§ã³ã§ãã
$ node --disable-warning=ExperimentalWarning index.js
éçºè ãæå³çã«éæ¨å¥¨ãªæ©è½ãå®é¨çãªæ©è½ã使ã£ã¦ããå ´åã¯ãè¦åãç¡å¹åãããã¨ã§è¦åãåºãªããªãã¾ãã
ããããæå³ãã¦ããªãå ´åã¯ãè¦åãç¡å¹åãããã¨ã§åé¡ãçºçããå¯è½æ§ãããã¾ãããªã®ã§ãè¦åãç¡å¹åããå ´åã¯æ³¨æãå¿ è¦ã§ãã
ãã®ä»ã®å¤æ´ç¹
fs.writeFile
é¢æ°ã«'flush'
ãªãã·ã§ã³ã追å ãããããããã©ã¼ãã³ã¹ã®æ¹åãããããä»ã«ããã¾ãã¾ãªå¤æ´ç¹ãããã¾ãã
詳ããã¯ä»¥ä¸ã®ãªã³ã¯ãã確èªãã ããã
ã¾ã¨ã
Node.js v21ã¯fetch
ãWebStream
ã®å®å®ãªãªã¼ã¹ãWebSocketã®è¿½å ãESMå¨ãã®æ¹åã®ããã®å®é¨çãªæ©è½ãå®è£
ãimport.meta
ã«filename
ã¨dirname
ã追å ããããªã©ãWebã¨ã®äºææ§ãESMå©ç¨ã«åããæ¹åæ©è½ã追å ããã¾ããã
Node.js v21ã¯ãã¼ã¸ã§ã³ãå¥æ°ãªã®ã§ãµãã¼ãæéã¯çãã2024å¹´6æã¾ã§ã¨ãªã£ã¦ãã¾ãã æ¥ç¨ã«ã¤ãã¦ã®ææ°ã®æ å ±ã¯ä»¥ä¸ã®ãªãã¸ããªãã確èªãã ããã
ã¾ãããã®è¨äºã§ç´¹ä»ããæ©è½ã®ãµã³ãã«ã³ã¼ãã¯ä»¥ä¸ã®ãªãã¸ããªã«ããã¾ããåèã«ãªãã°å¹¸ãã§ãã
æå¾ã¾ã§ãèªã¿ããã ããããã¨ããããã¾ãããä¸åã質åããããã¾ãããã@shisama_ã¾ã§ã¡ã³ã·ã§ã³ããããã³ã¡ãªã©ã§ã³ã¡ã³ããã ããã