html5j nodejs2018...Long Term Support で不具合は2年間修正される...
Transcript of html5j nodejs2018...Long Term Support で不具合は2年間修正される...
Node 20182018/11/23 @ HTML5j
Twitter: @yosuke_furukawa Github: yosuke-furukawa
Node.js v11 released!!!
Node.js Core Policy
Node.js Core Policy
small core, less is more
Less is More Focusing on Stability, Security, Performance
Stability
Stability (Node.js Core)
Long Term Support で不具合は2年間修正される
また、セキュリティ問題はさらに3年間修正される
♥
♥V8 は Node.js 非互換の修正をするときは事前に 通知する。
V8自身がNodeをforkして最新アップデートをしても テスト壊れないことを保証してる。
毎PR毎にCIでテストするのはもちろん、全CPU・プラットフォームでビルドしてうまくいくことを確認する。
たまに壊れるテスト (flaky test) に関してはどのプラットフォームで起きるか調査し、修正していく流れ
Stability (Node.js Application)
CPU・メモリ等のプロファイラーがあり、これを使うとボトルネックを調査できる。
Performance
Performance priority is high
必ず定期的にbenchmarkを取得し、遅くなってないことを調査する。
マイクロベンチマークだけではなく、Expressを使ったある程度の規模のアプリでもテストする。
keep v8 fresh
v8 のバージョンはメジャーバージョンリリース時までのStable Chrome に利用されて
るv8を利用。
(余談)なので、実はES unshippedの機能とか使える(v11だとprivate fieldとか
BigIntとか)
Worker
Worker
• Thread を使えるようにするためのもの。
• Node.js で multi thread プログラミングができる(ついに)
Worker
Worker
ちなみに最近入った llhttpというパーサがやばい
(まだexperimental)
llhttp は Node.js v11.2から入った新しいパーサ
$ node --experimental-http-parser test.js
# で実行可能。
ここがやばいよllhttp
• TypeScript から LLVM bitcode生成する。ラッパーを書いてCからも呼べるようにしている。
• (普通(?) CからLLVMにしてWASMにしてJSで呼べるようにっていう逆のアプローチを取りそうだが、TypeScript(JS)からLLVM bitcode生成して、Cのライブラリとして呼べるようにしたという所がやばいんだけど、一旦やばさは書ききれない。。。)
llhttp performance
2倍くらい早い(なぜか)
Security
Security (Node Core)
Node.js自身のセキュリティ脆弱性はTSCで必ず話されてる。
つい最近あったリリース、OpenSSLの脆弱性が発見されたのでパッチバージョンで全体に展開。
Security Releaseは脆弱性が報告される度に修正パッチが作られて報告されるようになってる
Security (Ecosystem)
npm audit は脆弱性が報告されてるライブラリが 自分のパッケージ内に存在するかを調査してくれる機能
ちなみに yarn にも audit は追加されてる(snyk.io というデータベースでnpmの脆弱性データベースと違うが)
Less is More で機能追加はしないと言っても例外はある。
Web Standards
Why Node needs web standard?
James Snell @ NodeFest 2016Node.js is, and has been, primarily a platform for Web Application Development
While Node.js presumes a "small core" philosophy for most things, it includes support for the most basic andcritical internet standards
Node.js v10.0.0 ~ v10.12.0
• HTTP/2
• ES Modules
• Promise in node core
• Stream/Promisesの親和性改善
Node.js v11
• url module が deprecated になり、 WHATWG
URL を利用するように内部改善が行われた
• WHATWG TextEncoder/TextDecoderがglobalになった
• queueMicrotask API が実験的に追加された
http2
Multiplexing requests on 1 TCP connection
Server
1 TCP Connection but multi requests
Multiplexing requests on 1 TCP connection
Server
If some requests are slow, BUT whole requests are not affected
HTTP/1.1
HTTP/2
ES Modules
ES Modules
import { readFile } from 'fs';readFile('./foo.txt', (err, source) => { if (err) { console.error(err); } else { console.log(source); }});
ES Modules
import { readFile } from 'fs';readFile('./foo.txt', (err, source) => { if (err) { console.error(err); } else { console.log(source); }});
import で読み込める
ES Modules
• まだ Experimental だが、 commonjs も es modules も相互運用できる形で実装されてる。
• ただ `.mjs` という拡張子が必要になる(試験的なもの)
• 今は nodejs/modules で議論中
• https://github.com/nodejs/modules
Promise in Node core
Promise in Node Core
• そもそも Node.js には非同期処理のやり方が複数存在する。
• Callback
• Promise
• Stream
• WebではPromiseがほぼ標準的な地位、これに合わせてPromiseと相互運用できるようにしていく流れ。
util.promisify
const util = require('util');const dns = require('dns');
// Promise 化された関数を取れる。const lookup = util.promisify(dns.lookup);
fs.promises
const fs = require('fs');
async function main() { // fs.promisesから処理を実行 const content = await fs.promises.readFile("./foo.txt"); console.log(content.toString());}
main();
fs.promises
const fs = require('fs');
async function main() { // fs.promisesから処理を実行 const content = await fs.promises.readFile("./foo.txt"); console.log(content.toString());}
main();
fs.promises にreadFileでCallbackではなくPromiseを返すようになる。
fs.promises
• これもまだExperimental
• PromiseがWeb開発者にとっては親和性が高く、ニーズも強いので追加された。
• httpなどの他のAPIはまだ
Stream/Promiseの親和性改善
• for await of で Stream を逐次処理できるようになった
• Node v10 から Stream に追加された finished,
pipeline APIが Promiseとの親和性高い
for await of の改善
const fs = require('fs');async function print(readable) { readable.setEncoding('utf8'); let data = '';
// for await 句でiterateしつつ、chunkを取り出す for await (const k of readable) { data += k; }
console.log(data);}print(fs.createReadStream('file')).catch(console.log);
Stream finished API
const fs = require('fs');const { finished } = require('stream');const rs = fs.createReadStream('./stream.js');
//finished API でエラー終了、正常終了にかかわらず終了したらコールバックを呼べる。finished(rs, (err) => { if (err) { console.error('Stream failed', err); return; } console.log('Stream is done reading');});
rs.resume();
Stream finished API
const fs = require('fs');const util = require('util');const stream = require('stream');// Promisify を使ってcallbackをpromiseにするconst finished = util.promisify(stream.finished);const rs = fs.createReadStream('./stream.js');
// async await が使えるasync function run() { await finished(rs); console.log('Stream is done reading');}run().catch((err) => console.error('Stream failed', err));rs.resume();
Stream Pipeline API
const fs = require('fs');const rs = fs.createReadStream('error.txt');const ws = fs.createWriteStream('output.txt');
rs.pipe(ws).on("error", (e) => { // ここで統一的にエラーをハンドリングしたいが、 // readstreamでエラーになるとここに来ない。 // こうやって書かなくてはいけない // rs.on("error", errorHandler).pipe(ws).on("error", errorHandler)});
Stream Pipeline API
const { pipeline, Transform } = require('stream');const rs = fs.createReadStream('./stream.js');const ts = new Transform({ transform(chunk, encoding, callback) { callback(null, chunk.toString().toUpperCase()) }});
const ws = fs.createWriteStream('./stream_cap.js');
pipeline(rs, ts, ws, (err) => { if (err) { console.error(err); return; } console.log('Stream is done reading');});
rs.resume();
Stream Pipeline API
const { pipeline, Transform } = require('stream');const p = util.promisify(pipeline);const rs = fs.createReadStream('./stream.js');const ts = new Transform({ transform(chunk, encoding, callback) { callback(null, chunk.toString().toUpperCase()) }});const ws = fs.createWriteStream('./stream_cap.js');// promisify してから async-awaitできるasync function run() { await p(rs, ts, ws); console.log('Stream is done reading');}run().catch(console.error);rs.resume();
Stream/Promiseの親和性改善
• Stream => Promise
• Promise => Stream
• のどちらでも運用できるようになった。
Node.js Future ~~~
Node.js Big News!!!
• Node.js Foundation and JS Foundation intent to create joint organization.
Node.js Big News!!!
• Node.js Foundation and JS Foundation intent to create joint organization.
Node.js Foundation と JS Foundation は統合 されて、一つになるのを目指す。
Unified JavaScript Platform
W3C / WHATWG Node.jsECMA
Unified JavaScript Platform
W3C / WHATWG Node.jsECMA
W3C/WHATWG の Web API と Node.js API
は徐々に寄せていく。さらにECMAScriptが その標準を中央で固めていく。
Example
Unified JavaScript Platform
• Web API も Node.js API も ECMAScript も求めているのは "ユースケース"
• さらにWeb API も Node API も ECMAScriptも全部丸っと知っているのは仕様策定者よりも開発者
• 開発者側、つまり僕らがユースケースを作っていき、仕様策定者側にフィードバックしていく必要がある。
Unified JavaScript Platform
• Web API も Node.js API も ECMAScript も求めているのは "ユースケース"
• さらにWeb API も Node API も ECMAScriptも全部丸っと知っているのは仕様策定者よりも開発者
• 開発者側、つまり僕らがユースケースを作っていき、仕様策定者側にフィードバックしていく必要がある。リードしていくのは仕様策定者だけではなく、我々です。
Thank you