html5j nodejs2018...Long Term Support で不具合は2年間修正される...

Post on 27-Jul-2020

1 views 0 download

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