関西Node学園 梅田キャンパス 1時限目 https://nodejs.connpass.com/event/82614/ でNode.js v10やEcmaScriptの新機能の話をしました。
य़͔Β͡ΊΔ৽͍͠Node.jsؔNodeֶԂ #1ฏ ণ࢜ / @shisama
View Slide
{"about": {"name": "Masashi Hirano","works": "Weblio, Inc.","twitter": "@shisama_","github": "shisama"}}
Agenda• ݱࡏͷNode.jsΛ෮श• ৽͍͠Node.jsΛ༧श• ৽͍͠Node.jsΛ࣮श
ରͱ͢Δਓ• Node.jsΛͬͨ͜ͱ͋Δਓ• Node.jsͬͯΔ͚Ͳɺ࠷৽ใΛΓ͍ͨਓ• ݹ͍όʔδϣϯͷNode.jsͬͯΔਓ
ࠓ͞ͳ͍͜ͱ• Node.jsͱ• ϑϩϯτΤϯυ(jQuery,React,Angular,Vue…)• ػೳ༷ͷͯ͢ʢ࣌ؒత੍ʣ
Goal• Node.jsͷ࠷৽ใΛΔ• ݹ͍ڥΛΞοϓσʔτ͢Δ• ৽͍͠Node.jsͷػೳΛͬͯΈΔ
·ͣࠓճ͢༰ʹؔ͢Δ༻ޠΛͬ͘͟Γ෮श
V8 engine• Google͕։ൃ͢ΔJavaScriptΤϯδϯ• ChromeͱNode.jsͰΘΕ͍ͯΔ• ࣮ߦ͕͍
npm• Node Package Manager• ϥΠϒϥϦཧ• λεΫ࣮ߦ
V8ɺnpmͷόʔδϣϯใhttps://nodejs.org/en/download/releases/
EcmaScript• JavaScriptͷ༷• ҰൠతʹEcmaScriptECMA-262Λࢦ͢• TC39ͱ͍͏ҕһձ͕༷ࡦఆΛ͍ͯ͠Δ• Living Standard• ৗʹ༷͕Ξοϓσʔτ͞ΕΔ
EcmaScript• 2ϲ݄ʹ1ճϛʔςΟϯά͕ߦΘΕ͍ͯΔ• ֤ػೳͷεςʔδߋ৽ͳͲ͕ٞ͞ΕΔ• stage-4ʹͳͬͨͷ͕1ʹ1ճEcmaScriptͷ༷ͱͯ͠ϦϦʔε͞ΕΔ(ES201X)
EcmaScript• ༷ࡦఆ·Ͱʹstage0ʙstage4·Ͱͷஈ֊͕ଘࡏ͢Δ• 0 Strawman - ΞΠσΞ• 1 Proposal - ఏҊ• 2 Draft - υϥϑτ• 3 Candidate- ༷ॻͱಉ͡ܗࣜ• 4 Finished - ࡦఆྃ
EcmaScripthttps://azu.github.io/slide-what-is-ecmascript/slide/B[V͞Μͷʰ&$."4DSJQUͱԿ͔ʁʱ͕Θ͔Γ͍͢ͷͰಡΜͰΈͯ΄͍͠
&DNB4DSJQUͷ࠷৽ใ5$ͷϦϙδτϦʹ͋Γ·͢ʂ
ݱࡏͷNode.jsΛ෮श
Release Schedule• github.com/nodejs/Releaseʹࡌ͍ͬͯΔ• ʹҰճϝδϟʔϦϦʔε͕ߦΘΕΔ
https://github.com/nodejs/Release
Active• LTS (Long Term Support)• 18ϲ݄ؒαϙʔτ͕ߦΘΕΔ• ຖ10݄͔ΒLTS ActiveʹͳΔ• όʔδϣϯ൪߸͕ۮ
Current• ࠷৽ͷϦϦʔε൛• ϝδϟʔόʔδϣϯ͕حˠ10݄ʹϦϦʔε• ϝδϟʔόʔδϣϯ͕ۮˠ4݄ʹϦϦʔε
Maintenance• LTSCurrentظؒऴྃޙͷϝϯςφϯεظؒ• LTS12ϲ݄ؒαϙʔτ• όάɺ੬ऑੑɺυΩϡϝϯτͳͲ͕ϝϯς͞ΕΔ
https://github.com/nodejs/Releaseݱࡏαϙʔτதͷόʔδϣϯʁ
Node 4.x• V8Τϯδϯ4.5• ES2015ͷػೳͷଟ͕͑͘ΔΑ͏ʹ• 2018/04/30ʹϝϯςφϯεऴྃ༧ఆ• αϙʔτࢭ·ΔͷͰΞοϓσʔτඞਢ
Node 6.x• V8Τϯδϯ5.1• ProxyσϑΥϧτҾ͕͑ΔΑ͏ʹ• 2018/04/30͔ΒLTSͰͳ͘ͳΔ༧ఆ• ϝϯςφϯε͞ΕΔ͚Ͳདྷ4݄ʹαϙʔτऴྃ༧ఆ
Node 8.x• ݱࡏͷLTS• V8Τϯδϯ6.1• async / awaitΛαϙʔτ͢Δ࠷ॳͷLTS• util.promisify, inspectorͳͲ͕Ճ͞Εͨ
Node 8.x• [email protected]• package-lock.json• 8.5͔Βϑϥά͖ͰES Modules͑Δ• import / export syntax• AWS LambdaͰ࠷ۙΑ͏͘v8͕͑ΔΑ͏ʹ
Node 8.x• 2019/04͔ΒLTSͰͳ͘ͳΔ• 2019/12ʹϝϯςφϯεऴྃ• ࠓ͏ͳΒ͜ͷόʔδϣϯ͕ແ
Node 9.x• ݱࡏͷCurrent• V8Τϯδϯ6.2• HTTP2͕ϑϥάͳ͠Ͱ͑Δ• 2018/06/30Ͱϝϯςφϯεऴྃ༧ఆ
͜͜·Ͱͷ͓͞Β͍• 4.xͬͯΔਓࠓ݄தʹΞοϓσʔτ• 6.xͬͯΔਓ̍ҎʹΞοϓσʔτ• 8.xͬͯΔਓ·ͩ̍Ҏ্େৎ• 9.xͬͯΔਓ݄̒·ͰʹΞοϓσʔτ
͜͜·Ͱͷ͓͞Β͍• 4.xͬͯΔਓࠓ݄தʹΞοϓσʔτ• 6.xͬͯΔਓ̍ҎʹΞοϓσʔτ• 8.xͬͯΔਓ·ͩ̍Ҏ্େৎ• 9.xͬͯΔਓ݄̒·ͰʹΞοϓσʔτࠓ͕Ξοϓσʔτ͢Δͱ͖Ͱ͢Αʂʂ
৽͍͠Node.jsΛ༧श
Node.js 10.0• 2018/04/24ʹϦϦʔε༧ఆ• ࣍ͷLTS• V8Τϯδϯ6.6• [email protected](ϦϦʔε࣌ʹೖΔ͔ະఆ)
V8 Engine• ݱࡏͷmasterʹೖͬͯΔͷ6.6• 6.7ʹͯ͠΄͍͠ཁ͋Δ
WWFSTJPOIʹఆٛ͞Ε͍ͯΔhttps://github.com/nodejs/node/blob/master/deps/v8/include/v8-version.h࠷৽ͷNode.jsͷV8ʁ
V8 engine• Node 9.x(V8 6.2) => Node 10.0(V8 6.6)• EcmaScript৽ػೳͷՃ(ޙड़)• ࣮ߦͷվળ• asyncͷύϑΥʔϚϯεվળ
https://github.com/nodejs/node/pull/19091V8 6.77ʹTUBCMFʹͳΔ͚ͲɺͦΕͰ͗͢Δ/PEF݄ޙʹϦϦʔε͍ͨ͠
V8 6.7• Chrome 67• BigInt(64bitܕ)ͳͲEcmaScript৽ػೳͷՃ• Node v10Ͱϑϥά͖Ͱ͑Δͷ͋Δ
[email protected]https://github.com/npm/npm/releases/tag/v6.0.0-next.0มߋখ͞Ίɻ/PEF͕ϦϦʔε͞ΕΔ·Ͱখ͍͞มߋ͔͠͠ͳ͍༧ఆ
[email protected]https://github.com/npm/npm/releases/tag/v6.0.0-next.0ࠓޙʹେ͖ͳมߋΛೖΕΔ༧ఆɻOQN!ʹʂ
[email protected]• Node 10.0ʹ͚ͯখ͞ͳมߋ͋Δ• Node 4.xͱNode 7.xͷαϙʔτऴྃ• npm ci && npm tͳnpm cit͕Ճ• npm install͢Δͱ͖ʹdeprecateͷόʔδϣϯΛճආͳͲ
deprecateͷόʔδϣϯΛճආ$ npm install [email protected]~1.1.0// 1.1.2// 1.1.3 (deprecated)// 1.2.0 (latest)͕Yͷ࠷৽͕ͩɺEFQSFDBUFʹͳ͍ͬͯΔͨΊΠϯετʔϧ͞Εͳ͍
EcmaScript৽ػೳ• ଟ͘ͷػೳ͕Ճ͞Εͨ• ES Modules·ͩϑϥά͚ͳ͍ͱ͑ͳ͍
Node.js v10ʹՃ͞ΕΔEcmaScript৽ػೳ• Dynamic import• Async Iteration• Promise.prototype.finally• RegExp New Features• Intl.NumberFormat.formatToParts• Function.prototype.toString()• Optional catch binding• String.prototype.trimStart• String.prototype.trimEnd
Dynamic Import(async() => {let count = 0;let id = setInterval(async() => {const i = Math.floor(Math.random() * 3) + 1;const module = await import(`./hello${i}.mjs`);module.hello();count++;if (count === 10) {clearInterval(id);}}, 1000);})();ಈతʹϞδϡʔϧΛJNQPSUՄೳʹ
Async Iterationasync function* gen() {while (true) {const res = await axios.get(‘https://hogehoge.com');const data = await res.data;yield data;}}(async() => {for await (const data of gen()) {console.log(data);}})();1SPNJTFͳྻΛGPSBXBJUPGͰඇಉظϧʔϓ͕Մೳʹ
Promise.prototype.finallyPromise.resolve(“then”).then(val => {console.log(val);throw new Error(“catch")}).catch(err => {console.log(err.message)}).finally(() => {console.log(“finally")});pOBMMZ ͕Ճ
RegExp New Featuresconst result = '123$456 $789 $ 000'.match(/(?<=\$)\d+/g);console.log(result); // ['456', '789']ਖ਼نදݱͷޙಡΈ͕Մೳɻଞʹ υοτ͕վߦจࣈʹϚον͢ΔΑ͏ʹͳΔTϑϥάͳͲ
Intl.NumberFormat.formatToPartsconst num = 1000;const formatter = new Intl.NumberFormat('ja-JP', {style: 'currency',currency: 'JPY'});const yen = formatter.formatToParts(num).map(({type,value}) => {switch (type) {case 'currency': return "" + value + "strong>";default: return value;}}).reduce((string, part) => {return string + part});console.log(yen);// => "¥1,000"ͷΧελϜϑΥʔϚοτ͕Մೳʹ
Function.prototype.toStringfunction /* a comment */ foo () {}foo.toString();// → 'function /* comment */ foo () {}'UP4USJOH ͷ༷มߋ
Optional catch bindingtry {const a = 1;a = 2;} catch {console.error("catch");}DBUDIͷҾͳ͠ͰՄೳʹ
String.prototype.trim{Start|End}const value = " has spaces ";console.log(`‘${value}'`);// => ‘ has spaces ‘console.log(`‘${value.trimStart()}'`);// => ‘has spaces ‘console.log(`trimEnd: '${value.trimEnd()}'`);// => ‘ has spaces‘จࣈྻͷલޙͷεϖʔεΛআڈ
http://node.green/OPEFHSFFOͱ͍͏αΠτʹ/PEFKTͷόʔδϣϯ͝ͱʹ&4ͷͲͷػೳ͕͑Δ͔ࡌ͍ͬͯΔ
ͦͷଞؾʹͳΔՃػೳ• fs͕PromiseϕʔεͰಈ͔ͤΔΑ͏ʹͳͬͨ• const data = await fs.readFile(‘./something’, ‘utf-8’);• util.types.isPromiseͱ͔isDateͰܕఆͳͲ
Wʹ͍ͭͯͬͱৄ͍͠Λฉ͖͍ͨਓདྷि౦ژʂ
৽͍͠Node.jsΛ࣮श
࠷৽ͷNode.jsΛ͏
master• ࠷৽ͷιʔείʔυ• ຖେྔʹίϛοτ͞Ε͍ͯΔ• ࠓϏϧυ͢ΔͱNode 10.0.0-preʹͳΔ
Node.jsΛϏϧυhttps://github.com/nodejs/node/blob/master/BUILDING.md#6*-%*/(NEΛݟΕ֤04͚ͷखॱ͕ॻ͔Ε͍ͯΔɻϏϧυ࣌ؒͦΜͳʹ͔͔Βͳ͍
Node.jsΛϏϧυ$ ./configure$ make -j4Ϗϧυதɾɾɾ$ ./node -v> v10.0.0-pre͜Ε͚ͩ
Ϗϧυͨ͠Node.jsΛ͏• ৽ػೳΛࢼͯ͠ΈΔ➡ ࠓհͨ͠ES৽ػೳಈ͘ʂʂ• Nodeຊମͷ࣮Λมߋͯ͠ಈ͔ͯ͠ΈΔ
͞Βʹ৽͍͠ػೳΛࢼ͢• Node.jsʹ࣮ݧతʹ࣮͞Ε͍ͯΔػೳ͕͋Δ• ϑϥάΛ͚ͭΔ͜ͱͰ͑Δ• ES Modules·࣮ͩݧతͳػೳ
ES Modules$ node —experimental-modules index.mjsFYQFSJNFOUBMNPEVMFTϑϥάΛ͏ɻ֦ுࢠNKT
harmony• --harmonyϑϥάΛ࣮͑ݧతͳػೳ͕͑ΔΑ͏ʹͳΔ• Node.jsʹ࣮͞Ε͍ͯΔEcmaScriptͷػೳʹΑͬͯϑϥάมΘΔ• EcmaScriptͷػೳ̏ͭʹ͚ΒΕΔ
EcmaScriptͷػೳ• shipping: ϦϦʔεࡁ• ϑϥάͳ͠Ͱ࣮ߦՄೳ• staged: ΄΅͕ͩɺ҆ఆ͍ͯ͠ΔͱΈͳ͞Εͳ͍• --harmonyϑϥάͰ࣮ߦՄೳ• in progress: ։ൃத• --harmony-class-fieldsͷΑ͏ʹݸʑʹ༻ҙ͞Εͨharmonyϑϥά
harmony ֬ೝํ๏$ node —v8-options | grep harmony--es_staging (enable test-worthyɾɾɾ--harmony (enable all completedɾɾɾ--harmony_shipping (enable allɾɾɾ--harmony_array_prototype_values (ɾɾ--harmony_function_sent (enableɾɾɾͲΜͳIBSNPOZϑϥά͕͋Δ͔WPQUJPOTΛ࣮ߦ͢Ε֬ೝͰ͖Δ
harmony ྫ$ node —harmony-bigint> typeof 123n‘bigint’> 123n + 1n124nIBSNPOZϑϥάΛ͚ͭΔ͜ͱͰ#JH*OU͑Δ /PEFW
Node.jsʹ࣮͞Ε͍ͯͳ͍ػೳΛ͏• BabelͰτϥϯεύΠϧ• EcmaScriptશػೳΛΧόʔ͍ͯ͠ΔΘ͚Ͱͳ͍• Node.jsͱޓੑ͕ͳ͍SyntaxͰಈ͘ͷͰҙ• import {readFile} from ‘fs’; ͜ΕNode.jsͰErrorʹͳΓ·͢
Ξτϓοτ͢Δ• ৽͍ٕ͠ज़ʹ৮ΕͨΒ͔ͤͬ͘ͳͷͰݟΛڞ༗ͯ͠΄͍͠ʂ• ϒϩά• Qiita• ษڧձ
ؔNodeֶԂ͍ͭͰ͋ͳͨͷొஃΛ͓͍ͪͯ͠·͢ʂ
·ͱΊ• Node.jsͷαϙʔτظؒΛҙࣝ͠Α͏ʂ• Node.js v10 དྷिϦϦʔεʂ(༧ఆ)• ٕज़Δ͚ͩͰͳ͘ɺͬͯͳΜ΅Ͱ͢ʂ• ొஃͯ͘͠ΕΔํ͓͍ͪͯ͠·͢ʂʂ
Special Thanks!ओ࠵ऀϝϯόʔ (@sbntaminif, @vanx2, @mdaisuke,@kamiyam,@leichtgewicht), ͘͞ΒΠϯλʔωοτ༷, εϐʔΧʔͷํʑ(@mochiya98, @sota1235,@h_michael_z) and ࠓདྷͯ͘Εͨօ༷!!1ճ։࠵Ͱ͖ͯخ͍͠Ͱ͢ʂ͜Ε͔ΒؔNodeֶԂΛӬ͘ΑΖ͓͘͠ئ͍͍ͨ͠·͢
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠