技術探し

JavaScriptを中心に記事を書いていきます :;(∩´﹏`∩);:

次のリリースであるBabel7の主な変更点まとめ

Babel7がリリースされるまでは更新されます。

注意: 量が多いので、BabelのInternal, Bug Fix, DocumentsとBabylonについては書きません。
また6.xへバックポートされたものも入っていますので注意してください。

もし、間違えや質問があれば、 @about_hiroppy までどうぞ;)

Index


Links

Milestone

Babel 7 Beta Milestone · GitHub

Wiki

Babel 7 · babel/babel Wiki · GitHub

Releases

Releases · babel/babel · GitHub

Revision History of This Article

2017/09/04(first)

Babelのstableがv6.26.0でプレリリースがv7.0.0-alpha.20です。
Babylonのv7.0.0-beta.22です。

The branches in babel have been moved. The previous master is now called 6.x, and the 7.0 branch is now master. Pull requests need to be based on master from now on. (2017/9/1)

masterブランチが7.0になったためここにまとめたいと思います。


Notable Changes

Babel

  • TypeScriptのサポート
  • .babelrc.jsのサポート
  • spread-operatorが仕様準拠となる
  • stageパッケージの追加と変動

Packages Status of Stage-X

従来通り、数値以上のパッケージはそこにすべて含まれます。

Tracking for Spec

github.com

stage-3

  • babel-plugin-syntax-dynamic-import(new)
  • babel-plugin-transform-async-generator-functions
  • babel-plugin-transform-class-properties(new)
  • babel-plugin-transform-object-rest-spread
  • babel-plugin-transform-optional-catch-binding(new)
  • babel-plugin-transform-unicode-property-regex(new)

stage-2

  • babel-plugin-transform-export-namespace
  • babel-plugin-transform-function-sent(new)
  • babel-plugin-transform-numeric-separator(new)
  • babel-preset-stage-3

stage-1

  • babel-plugin-transform-decorators
  • babel-plugin-transform-export-default
  • babel-plugin-transform-optional-chaining(new)
  • babel-preset-stage-2

stage-0

  • babel-plugin-transform-do-expressions
  • babel-plugin-transform-function-bind
  • babel-preset-stage-1

Flow

  • Object typeに対し、speadが使用可能になる
  • declare exportが使用可能になる
  • predicatesエイリアスサポート
  • opaqueエイリアスサポート

babel-preset-env

polyfillを動的に入れてくれるようになる


Details of Changes

Babel

babel-preset-es2015

specモード時に変換されたアロー関数に名前が付与される

// input
return {
  g: () => this
}

// output
return {
  g: function g() {
    babelHelpers.newArrowCheck(this, _this);
    return this;
  }.bind(this)
}
Related Plugins

babel-plugin-transform-es2015-arrow-functions

Versions

v7.0.0-alpha.10

PRs

Add function name to spec-transformed arrow functions by Kovensky · Pull Request #5620 · babel/babel · GitHub

check-es2015-constantsが仕様準拠となる

constコンパイル時にエラーではなく、その前にthrowが追加されました。

Related Plugins

babel-plugin-check-es2015-constants

Versions

v7.0.0-alpha.17, 20

PRs

配列でのfor-ofの最適化

Related Plugins

babel-plugin-transform-es2015-for-of

Versions

v7.0.0-alpha.15

PRs

test for for-of optimization on arrays and add it for array type anno… by hzoo · Pull Request #4747 · babel/babel · GitHub

looseモードでのClassCallCheckpossibleConstructorReturnが削除

Related Plugins
  • babel-helpers
  • babel-plugin-transform-es2015-classes
  • babel-plugin-transform-flow-comments
  • babel-plugin-transform-flow-strip-types
Versions

v7.0.0-alpha.15

PRs

Remove ClassCallCheck, possibleConstructorReturn in loose mode by hzoo · Pull Request #4850 · babel/babel · GitHub

looseモードにes2015-parametersが追加

argumentsを使用しません。

Related Plugins

babel-plugin-transform-es2015-parameters

Versions

v7.0.0-alpha.17

PRs

2nd try: Add loose option for es2015-parameters transformation by maurobringolf · Pull Request #5943 · babel/babel · GitHub

looseモードにclass-fieldsが追加

Object.definePropery を使わずに代入式でコンパイルされます。

var Bork = function Bork() {
  babelHelpers.classCallCheck(this, Bork);
  this.x = 'bar';
  this.y = void 0;
};
 
Bork.a = 'foo';
Bork.b = void 0;
Related Plugins

babel-plugin-transform-class-properties

Versions

v7.0.0-alpha.20

PRs

Update Class Fields to Stage 3 and change default behavior by kedromelon · Pull Request #6076 · babel/babel · GitHub

template-literalsはデフォルトでconcatを使用し、looseモードでは+を使用する

Related Plugins

babel-plugin-transform-es2015-template-literals

Versions

v7.0.0-alpha.20

PRs

default to spec mode for template literal transform by kedromelon · Pull Request #6098 · babel/babel · GitHub

spread-operatorが仕様準拠となる

// Invalid
( {...{}} = {} ); ( {...[]} = {} );
var { ...{ z } } = { z: 1 };
({ x, ...{ y, z } } = o);

// valid
let {...{}} = {}; let {...[]} = {};
let { ...z } = { z: 1 };
({ x, y, ...z } = o);

May 23, 2017 Meeting Notes

Related Plugins
  • babel-plugin-transform-es2015-destructuring
  • babel-plugin-transform-object-rest-spread
Versions

v7.0.0-alpha.20

PRs

Adjusted Object Rest/Spread tests to use only allowed syntax from the… by Andarist · Pull Request #6102 · babel/babel · GitHub

babel-preset-stage-3

stage-3からstage-4のプラグインが削除

Versions

v7.0.0-alpha.1

PRs

[7.0] Remove stage 4 plugins from stage 3 preset by varemenos · Pull Request #5126 · babel/babel · GitHub

dynamic-importの追加

for (const link of document.querySelectorAll('nav > a')) {
  link.addEventListener('click', e => {
    e.preventDefault();

    import(`./section-modules/${link.dataset.entryModule}.js`)
      .then(module => module.loadPageInto(main))
      .catch(err => main.textContent = err.message);
  });
}
Related Plugins

babel-plugin-syntax-dynamic-import

Versions

v7.0.0-alpha.8

PRs

Move syntax-dynamic-import to stage-3 by dkaoster · Pull Request #5610 · babel/babel · GitHub

Spec

GitHub - tc39/proposal-dynamic-import: import() proposal for JavaScript

optional-catch-bindingの追加

try {} catch {}
try {
  bar;
} catch {
  foo();
} finally {
  yay();
}
Related Plugins

babel-plugin-transform-optional-catch-binding

Versions
  • v7.0.0-alpha.17
  • v7.0.0-alpha.18
PRs
Spec

Optional catch binding

class-fieldsの追加

class Bork {
  static a = 'foo';
  static b;
 
  x = 'bar';
  y;
}

looseモードの指定がない場合、コンパイル時に代入式からObject.defineProperyを使うように変更されました。

Related Plugins

babel-plugin-transform-class-properties

Versions

v7.0.0-alpha.20

PRs

Update Class Fields to Stage 3 and change default behavior by kedromelon · Pull Request #6076 · babel/babel · GitHub

Spec

GitHub - tc39/proposal-class-fields: Orthogonally-informed combination of public and private fields proposals

transform-unicode-property-regexの追加

const regexGreekSymbol = /\p{Script=Greek}/u;
regexGreekSymbol.test('π'); // true
Related Plugins

babel-plugin-transform-unicode-property-regex

Versions
  • v7.0.0-alpha.1
  • v7.0.0-alpha.15
PRs
Spec

GitHub - tc39/proposal-regexp-unicode-property-escapes: Proposal to add Unicode property escapes `\p{…}` and `\P{…}` to regular expressions in ECMAScript.

babel-preset-stage-2

function.sentの追加

function* generator() {
  console.log('Sent', function.sent);
  console.log('Yield', yield);
}
 
const iterator = generator();
iterator.next(1); //  Sent 1
iterator.next(2); // Yield 2
Related Plugins
  • babel-helper-wrap-function
  • babel-plugin-transform-function-sent
Versions

v7.0.0-alpha.17

PRs

Function sent by nicolo-ribaudo · Pull Request #5920 · babel/babel · GitHub

Spec

ESideas/Generator metaproperty.md at master · allenwb/ESideas · GitHub

export-default-fromの追加

export var v;
export * as ns from 'mod';
export v, {x, y as w} from 'mod';
Related Plugins
  • babel-plugin-transform-export-default
  • babel-plugin-transform-export-namespace
Versions

v7.0.0-alpha.20

PRs
Spec

GitHub - tc39/proposal-export-default-from: Proposal to add `export v from "mod";` to ECMAScript.

numeric-separatorの追加

1_000_000_000  // Ah, so a billion
101_475_938.38  // And this is hundreds of millions

let fee = 123_00;   // $123 (12300 cents, apparently)
let fee = 12_300;   // $12,300 (woah, that fee!)
let amount = 12345_00;  // 12,345 (1234500 cents, apparently)
let amount = 123_4500;  // 123.45 (4-fixed financial)
let amount = 1_234_500; // 1,234,500

let budget = 1_000_000_000_000;
// What is the value of `budget`? It's 1 trillion!

console.log(budget === 10 ** 12); // true
Related Plugins

babel-plugin-transform-numeric-separator

Versions

v7.0.0-alpha.20

PRs

Add numeric separator to stage 2 preset by rwaldron · Pull Request #6071 · babel/babel · GitHub

Spec

GitHub - tc39/proposal-numeric-separator: A proposal to add numeric literal separators in Javascript. https://tc39.github.io/proposal-numeric-separator/

babel-preset-stage-1

optional-chaining-operatorの追加

abouthiroppy.hatenablog.jp

const obj = {
  foo: {
    bar: {
      baz: 42,
    },
  },
};

const baz = obj?.foo?.bar?.baz; // 42
const safe = obj?.qux?.baz; // undefined

// Optional chaining and normal chaining can be intermixed
obj?.foo.bar?.baz; // Only access `foo` if `obj` exists, and `baz` if `bar` exists
Related Plugins

babel-plugin-transform-optional-chaining

Versions

v7.0.0-alpha.15

PRs

Optional Chaining Operator (Stage 1) by jridgewell · Pull Request #5813 · babel/babel · GitHub

Spec

GitHub - tc39/proposal-optional-chaining

babel-plugin-transform-class-properties

configurableプロパティの追加

Object.defineProperty(REF, KEY, {
  configurable: true,
  enumerable: true,
  writable: true,
  value: VALUE
});
Versions

v7.0.0-alpha.20

PRs

Add 'configurable' property to class fields by reznord · Pull Request #6123 · babel/babel · GitHub

babel-polyfill

それぞれの機能のポリフィルファイルを個別に追加

Versions

v7.0.0-alpha.7

PRs

add individual polyfill files by hzoo · Pull Request #5584 · babel/babel · GitHub

babel-cli

--inspect-brkオプションの追加

Node7.6で入ったオプションです。

Versions

v7.0.0-alpha.11

PRs

Allow --inspect-brk option to be used with babel-node by noinkling · Pull Request #5785 · babel/babel · GitHub

--config-fileオプションの追加

.babelrcのパスを渡すオプションです。

Versions

v7.0.0-alpha.20

PRs

add --config-file option to CLI to pass in .babelrc location by bdwain · Pull Request #6133 · babel/babel · GitHub

babel-plugin-transform-runtime

useBuiltInsuseESModulesオプションの追加

Versions

v7.0.0-alpha.3

PRs

Add useBuiltIns and useESModules options to transform-runtime by Kovensky · Pull Request #5442 · babel/babel · GitHub

babel-core

babelの環境変数が取得できるようになった

Versions

7.0.0-alpha.3

PRs

Export Babel's environment by xtuc · Pull Request #5448 · babel/babel · GitHub

babel-register

キャッシュディレクトリを見つけ、作成する

Versions

v7.0.0-alpha.10

PRs

Find cache dir by pwmckenna · Pull Request #5669 · babel/babel · GitHub

Flow

Object typeに対し、speadが使用可能に

type U = {};
type V = {};
type T = { ...U };
type T = { ...U, ...V, };
type T = { p: V, ...U, };
type T = { ...U, p: V, };
type T = { ...{} | { p: V } };
Versions

v7.0.0-alpha.10

PRs

Add support for object type spread by conartist6 · Pull Request #5525 · babel/babel · GitHub

declare exportが使用可能に

declare export var foo;
declare export function foo(): void;
declare export function foo<T>(): void;
declare export function foo(x: number, y: string): void;
declare export class A<T> extends B<T> { x: number }
declare export class A { static foo(): number; static x : string }
declare export class A mixins B<T>, C {}
declare export default function foo(): void;
declare export * from 'asd';
declare export { a, b };
declare export { c, d } from 'bar';
Versions

v7.0.0-alpha.15

PRs

Support declare export statements by danez · Pull Request #5589 · babel/babel · GitHub

predicatesエイリアスサポート

declare function foo(x: mixed): boolean %checks(x !== null);

function is_string(x): boolean %checks {
  return typeof x === "string";
}
Versions

v7.0.0-alpha.17

PRs

Add support for flow predicates in babel-generator by existentialism · Pull Request #5984 · babel/babel · GitHub

opaqueエイリアスサポート

opaque type ID = string;
opaque type Foo<T> = Bar<T>;
opaque type Maybe<T> = _Maybe<T, *>;
export opaque type overloads =
  & ((x: string) => number)
  & ((x: number) => string)
;

medium.com

Versions

v7.0.0-alpha.18

PRs

Flow opaque type aliases by jbrown215 · Pull Request #5990 · babel/babel · GitHub

babel-preset-reactはflowアノテーションがあるときのみflowの処理するように変更

TypeScriptとの互換性を持つためにbabel-preset-reactからflowのサポートはなくなります。

Versions
  • v7.0.0-alpha.19
  • v7.0.0-alpha.20
PRs

その他使用者向け

Node 0.12のサポートが切られました

Versions

v7.0.0-alpha.1

PRs

Drop support for Node 0.12 :skull: by siddharthkp · Pull Request #5025 · babel/babel · GitHub

.babelrc.jsがサポートされました

Versions

v7.0.0-alpha.2

PRs

Add support for .babelrc.js files by kaicataldo · Pull Request #4892 · babel/babel · GitHub

.babelrc.jsで関数使用の許可・キャッシュ

Versions

v7.0.0-alpha.8

PRs

Cache configs based on mtime and allow .babelrc.js functions by loganfsmyth · Pull Request #5608 · babel/babel · GitHub

.babelignoreで否定パターンが使えるようになる

Versions

v7.0.0-alpha.8

PRs

Allow negation of ignore and only patterns. by loganfsmyth · Pull Request #5625 · babel/babel · GitHub

babel-plugin-transform-new-targetの追加

Versions

v7.0.0-alpha.15

PR・Issue

TypeScriptのサポート

{
  "presets": ["typescript"]
}
Related Plugins
  • babel-plugin-syntax-typescript
  • babel-plugin-transform-typescript
  • babel-preset-typescript
Versions
  • v7.0.0-alpha.18
  • v7.0.0-alpha.19
  • v7.0.0-alpha.20
PRs

その他開発者向け

for-awaitは新しいASTに変更

// new forOfStatement
t.forOfStatement(left, right, body, await) // @param {boolean} await - default: false
Versions

v7.0.0-alpha.1

PRs

Change for-await to use new AST by danez · Pull Request #5321 · babel/babel · GitHub

babel-traverseにString.rawの追加

Versions

v7.0.0-alpha.15

PRs

Add support for evaluating `String.raw` expressions by josephfrazier · Pull Request #5681 · babel/babel · GitHub

babel-standaloneがbabelレポへ移動

github.com

Versions

v7.0.0-alpha.20

PRs

Move babel-standalone into main Babel repo by Daniel15 · Pull Request #6029 · babel/babel · GitHub

babel-preset-env

useBuiltInsオプションの変更

以前はfalseでbooleanでしたが、"usage""entry"falseへ変更されました。
useBuiltInsというオプションはbabel-polyfillを入れるかどうかオプションです。
これにより、import 'babel-polyfill' が必要なくなります。

FYI: GitHub - babel/babel-preset-env at 2.0

Versions

v2.0.0-alpha.6

PRs

make useBuiltIns: false default, rename true to 'usage' by hzoo · Pull Request #285 · babel/babel-preset-env · GitHub

Website

REPLがreplaceされた

Babel · The compiler for writing next generation JavaScript


In Progress

Babel

decoratorsのアップデート

class Foo {
  @dec1 method1() {}
  @dec2(a, b, c) method2() {}
  @dec3outer @dec3inner method3() {}
  undecorated() {}
}

elementDescriptor`というspecの概念の追加等

Versions

N/A

PRs

Decorators 2 Transform [WIP] by peey · Pull Request #6107 · babel/babel · GitHub

Spec

現在stage-2
Decorators

bigIntの追加

(1073741824n ** 2n).toString() === (new BigInt('1152921504606846976')).toString()
Versions

N/A

PRs

BigInt (Stage 2) [WIP] by wdhorton · Pull Request #6015 · babel/babel · GitHub

Spec

現在stage-3(PRの段階では2ですが現在3)
GitHub - tc39/proposal-bigint: Arbitrary precision integers in JavaScript

Babylon

Pattern Matchingの追加

let getLength = vector => match (vector) {
  { x, y, z }: Math.sqrt(x ** 2 + y ** 2 + z ** 2),
  { x, y }:    Math.sqrt(x ** 2 + y ** 2),
  [...]:       vector.length,
  else: {
    throw new Error("Unknown vector type");
  }
};
Versions

N/A

PRs

WIP Pattern Matching (Stage 0) by krzkaczor · Pull Request #635 · babel/babylon · GitHub

Spec

現在stage-0
GitHub - tc39/proposal-pattern-matching: Pattern matching syntax for ECMAScript

classへprivate methodsのサポート

class Counter extends HTMLElement {
  #xValue = 0;

  #clicked() {
    this.#x++;
  }

  constructor() {
    super();
    this.onclick = this.#clicked.bind(this);
  }

  connectedCallback() {
    this.#render();
  }

  #render() {
    this.textContent = this.#x.toString();
  }
}
Versions

N/A

PRs

Add support for class private methods by Qantas94Heavy · Pull Request #703 · babel/babylon · GitHub

Spec

現在stage-2
GitHub - tc39/proposal-private-methods: Private methods and getter/setters for ES6 classes

メモ: Node.jsとAyo.jsに分裂したという話

この記事は自分用のリンク集メモです。(色々と聞かれるときにリンク探すの大変なため)

注意: 追記・変更が頻繁に行われるでしょう

原因

Rodが複数回のNode.js Foundationの行動規範に対し違反を行っていた。
コレに関して、TSCで辞任の投票が行われたが60%の反対で否決となった。(技術力や今までの貢献度がすごかったから)
この意思決定に関して疑問を持った人がTSCから自主的に辞任をした。

Rodの違反行為一覧

画像じゃなければこっち meta: vote regarding Rod's status on the TSC · Issue #310 · nodejs/TSC · GitHub

また、Rodの違反行為はModerationまでエスカレーションしている。

参考Issues

TSC投票ステータス

github.com

privateを除く、一番始めに表に出てきたIssue
ココから今回の騒動は始まった。

編集前魚拓: meta: vote regarding Rod's status on the TSC · Issue #310 · nodejs/TSC · GitHub

結果: 6人がNo, 4人がYes, 2人が棄権, 1人が拒否

自主的に辞退した人

Anna, Brya, Myles, Jeremiah

Pull Requests · nodejs/TSC · GitHub

Mylesの意見・考え

medium.com

Bryanの意見・考え

medium.com

自主辞退要求とRodの声明

github.com

簡単に言うと、辞退を拒否

Nodeの将来

github.com

Hacker News

Effective immediately I am stepping down from the Nodejs TSC | Hacker News

ZDNet

www.zdnet.com

TSC

github.com

TSCとはNode.js FoundationのTop Working Groupである。
今回の投票はここにいるメンバーで行われた。


Node.js Foundationの動き

事態が起こってから急速に動いている。

主な変更

TSCとCTCのリマージ

CTCがデチャータリングされ、TSCにCTCメンバーが加わります。

github.com github.com github.com

規約の更新

CoCなどの規約が改定されます。

新しいModerationチームを立ち上げるための取り組み

github.com

github.com

ボード

Coreへの全体周知

github.com

Board

github.com

大変重要な問題なので8/28に理事会がMTGを開く。
長期的に続くガバナンスモデルの構築のため、憲章・規範の改定を主に検討される。

質問リスト

github.com

このissueへの反応

github.com


Ayo.js

node.js/nodeからforkされた。
読み方は「アイヨ」、「アイオ」、「Awooooo」
Awoooooが結構押されている気がする(e.g. discord, etc…)

github.com

NodeのCore Collaboratorが多いが、決してNodeを捨てたつもりはないと思っています。
ただ自分としては、新しい規約提案ができるのではないかと期待している。

フォークに関して

github.com

Ayoも7000以上あるフォークの内の一つであり、それがOSSなのであまり敏感になる必要はないと思っています。
Node.jsのコアメンバーがいるただのフォークです。

github.com

意見交換場所

招待 discordapp.com

チャンネルURL(アカウントがある場合はこちら) discordapp.com

npm

http://blog.npmjs.org/post/164575965335/values-inclusion-and-the-nodejs-foundation
blog.npmjs.org

結構Ayoにノリノリっぽい気がした。(それぐらいNode.js Foundationの規範に不満があったのかな?)

目的

github.com

コード自体は当分ミラーリングの予定です。(が将来的には機能追加するとfishrockは言っていました)
それよりも規範等のガバナンスの再構築が目的です。

github.com

ここに書いてあるとおり、参加しているのはNode Coreで活動している人が主です。

github.com

Values

今現在、草稿が上がっています。 github.com

新しいガバナンスモデルとマネージメントの構築を目的としています。
全体的に人間が重要視されています。
価値や幸福を技術や企業より主軸に置きます。

アイコン

検討中

github.com

CI

インフラは検討中。
現在Travisで動いているが、各プラットフォームのテストができないのでつらそう。
今はTravisLinuxのみのテストを行っています。

ちなみにNode.jsはJenkinsでCIが行われています https://ci.nodejs.org/


さいごに

今回はio.jsと似て非なるものである。
io.jsと違い、あくまでも身内の話である。(また技術的な話が要因ではない)

だからこそ今回の件の理由は、外から見ると何が起こっているのかわかりづらい。

8/28に開催される理事会を待つ。

NodeにPerformance Timing APIが追加される

NodeへPerformance Timing APIの初期実装が入ります。

資料

developer.mozilla.org

W3C

Performance Timeline

High Resolution Time Level 2

github.com

NodeへのPR

github.com

まだ、masterやリリースラインに入っていないのでドキュメントはPRから見てください。
今回は、PerformanceFramePerformanceNodeTiming の説明は書かないので詳しくはドキュメントへ。

Nodeのイベントループの時間測定を測定するのも実装されている。

Performance Timing API

マイクロ秒で経過時間を取得するAPI である。

Dateを使い計測を行うことがあると思うが、以下のような場合がある。

const markStart = Date.now();

(() => {})();

const duration = Date.now() - markStart;

console.log(duration); // 0

実際は、正の値, 負の値, 0の値になり得てしまう。

実装

Nodeで使ってみる

processperformanceというメソッドが追加された。

> process.performance
{ timeOrigin: 14194760.508743,
  nodeTiming:
   PerformanceNodeTiming {
     duration: 2735.97479,
     startTime: 14194760.508743,
     type: 'node',
     name: 'node',
     arguments: 14194763.6652,
     initialize: 14194764.104207,
     inspectorStart: 14194769.714933,
     loopStart: 14194854.360176,
     loopExit: 0,
     loopFrame: 14196891.511942,
     bootstrapComplete: 14194854.356646,
     third_party_main_start: 0,
     third_party_main_end: 0,
     cluster_setup_start: 0,
     cluster_setup_end: 0,
     module_load_start: 14194813.331148,
     module_load_end: 14194813.33181,
     preload_modules_load_start: 14194813.332309,
     preload_modules_load_end: 14194813.356287 },
  nodeFrame:
   PerformanceFrame {
     prior: 0.012497,
     type: 'frame',
     name: 'frame',
     duration: 605.560913,
     startTime: 14196891.511942 } }
>

手順

基本的には、

  1. 開始区間のマーキング(mark)
  2. 終了区間のマーキング(mark)
  3. その区間の名前を定義して保存されます。(measure)
  4. すべて保存されたリストから3で定義した区間の名前を指定し取得(getEntriesByName)

また、同じ区間の名前をつけたときはスタックしていきます。
なのでgetEntriesByNameで取得した時に配列になっています。
これは新しいのから順にpushされます。(つまりタイムライン順)

区間を逆(未来 to 過去)にした場合、数値がすごいことになるのは仕様なのかな・・・?

少し長いですが、以下のコードを読めばわかると思います。

コード

const fs = require('fs');

const perf = process.performance;

perf.mark('A');

(() => {})();

perf.mark('B');

perf.measure('A to B', 'A', 'B'); // tagname, startMark, endMark

const measure1 = perf.getEntriesByName('A to B')[0]; // measure1's length is 1
console.log(measure1.duration); // 0.009461

/* ----------------------------------------------------- */

perf.mark('C');

fs.readFileSync('./node');

perf.mark('D');

perf.measure('C to D', 'C', 'D');

const measure2 = perf.getEntriesByName('C to D')[0]; // measure2's length is 1
console.log(measure2.duration); // 28.502531

/* ----------------------------------------------------- */

perf.measure('A to B', 'C', 'D'); // push to `A to B`

const measure3 = perf.getEntriesByName('A to B'); // measure3's length is 2
console.log(measure3); // display the performance timeline of `A to B`
/*
  [ PerformanceMeasure {
      duration: 0.009461,
      startTime: 15995656.619165,
      type: 'measure',
      name: 'A to B' },
    PerformanceMeasure {
      duration: 28.502531,
      startTime: 15995675.467252,
      type: 'measure',
      name: 'A to B' } ]
*/

console.log(perf.getEntries()); // display the performance timeline(combined `mark` and `measure` into the timeline)
/*
  [ PerformanceNodeTiming {
      duration: 107.495859,
      startTime: 15995598.683741,
      type: 'node',
      name: 'node',
      arguments: 15995602.156617,
      initialize: 15995602.750924,
      inspectorStart: 15995609.924404,
      loopStart: 0,
      loopExit: 0,
      loopFrame: 0,
      bootstrapComplete: 0,
      third_party_main_start: 0,
      third_party_main_end: 0,
      cluster_setup_start: 0,
      cluster_setup_end: 0,
      module_load_start: 15995653.258513,
      module_load_end: 15995653.313254,
      preload_modules_load_start: 15995653.313785,
      preload_modules_load_end: 15995653.341459 },
    PerformanceFrame {
      prior: 0,
      type: 'frame',
      name: 'frame',
      duration: 15995706.323224,
      startTime: 0 },
    PerformanceMark {
      duration: 0,
      startTime: 15995656.619165,
      type: 'mark',
      name: 'A' },
    PerformanceMark {
      duration: 0,
      startTime: 15995656.628626,
      type: 'mark',
      name: 'B' },
    PerformanceMeasure {
      duration: 0.009461,
      startTime: 15995656.619165,
      type: 'measure',
      name: 'A to B' },
    PerformanceMark {
      duration: 0,
      startTime: 15995675.467252,
      type: 'mark',
      name: 'C' },
    PerformanceMark {
      duration: 0,
      startTime: 15995703.969783,
      type: 'mark',
      name: 'D' },
    PerformanceMeasure {
      duration: 28.502531,
      startTime: 15995675.467252,
      type: 'measure',
      name: 'C to D' },
    PerformanceMeasure {
      duration: 28.502531,
      startTime: 15995675.467252,
      type: 'measure',
      name: 'A to B' } ]
 */

API

common

now()

現在の高分解能時刻タイムスタンプを返します。

mark(name: string)

パフォーマンスタイムラインへ新しいPerformanceMarkを追加します。
performanceEntry.typeは常にmarkです。

measure(name: string, startMark: string, endMark: string)

パフォーマンスタイムラインへ新しいPerformanceMeasureを追加します。
performanceEntry.typeは常にmeasureです。

name区間の名前です。
startMarkは開始地点の名前を設定します。もし名前が存在しない場合、timeOriginが基準となります。
endMarkは終了地点の名前を設定します。もし指定しない場合は、エラーが投げられます。

get

getEntries()

startTimeを基準にすべてのPerformanceEntry Objectのリストを時間順に返します。
mark 及び measure のタイムラインとなります。

getEntriesByType(type: string)

performanceEntry.typeと同じtypeを持つすべてのPerformanceEntry ObjectのリストをstartTimeを基準に時間順に返します。
古い物から先頭となります。

getEntriesByName(name: string, type?: string)

performanceEntry.typeと同じnameを持つすべてのPerformanceEntry ObjectのリストをstartTimeを基準に時間順に返します。
古い物から先頭となります。

clear

clearMarks(name?: string)

名前を指定すれば、そのマークを消し、
指定しなければ、すべてのマークをパフォーマンスタイムラインから消します。

clearMeasures(name?: string)

名前を指定すれば、そのメジャーを消し、
指定しなければ、すべてのメジャーをパフォーマンスタイムラインから消します。

仕様分類

High Resolution Time Level 2

High Resolution Time Level 2

toJson()

High Resolution Time

High Resolution Time

now()

Navigation Timing

timing, navigation

Performance Timeline Time Level 2

Performance Timeline Level 2

getEntries()

Performance Timeline

Performance Timeline

getEntries(), getEntriesByType(), getEntriesByName()

Resource Timing Level 1

Resource Timing Level 1

clearResourceTimings(), setResourceTimingBufferSize(), onresourcetimingbufferfull

User Timing

User Timing Level 2

User Timing

mark(), clearMark(), measure(), clearMeasure()

まとめ

Performance Timing APIに関する初期実装がもうすぐ入りそう。
まだまだ未実装な部分が多いので、今後に期待。

Node8.3.0でデフォルトになるTF/Iに関わるベンチマークについて

buildersconでのスライド

speakerdeck.com

8.3.0 プロポーザル

github.com

大きな変更はやはりV8の6.0とWHATWG Encoding Standardが入ることです🎉
今回はV8の6.0の話をします。
これはLTS対象であるNode8へのバックポートもされNodeのバージョンを9へ上げる準備ができました。

github.com

github.com

今現在のcurrent(master branch)はv9.0.0-preです。

TurboFan + Ignition

V8の5.9からデフォルトになるTurboFanとIgnitionというものがあります。 今までは、Crankshaftと呼ばれるコンパイルインフラストラクチャがありましたがそれが置き換わります。

v8project.blogspot.jp

TurboFanとIgnitionを簡単に説明します。

TurboFan

JITコンパイラ
Crankshaftから置き換わるもの。
Crankshaftではtryスコープ、ES2015の最適化(e.g. scope, class literal, for of, etc…)ができなかったですが、TurboFanではそれを可能とします。
chrome 41から段階的に使用されてました。(その頃はbaselineでTurboFanとCrankshaftでルーティングしていました)

Ignition

レジスタマシン。
モバイル端末のメモリ消費削減を目標として作られたインタプリタで、JSのコードをbytecodeにします。
V8のJITの問題点として、コードが一回実行されただけでも大量のメモリ消費をする可能性があり、メモリーオーバーヘッドを避ける必要がありました。

Flow

f:id:about_hiroppy:20170803092506j:plain

docs.google.com

V8の5.9は・・・?

Nodeでは8.3.0でV8の5.9を入れる予定でしたが、6.0を待つことになりました。

github.com

github.com

6.0ではTF関連のパフォーマンスが5.9よりも改善されるからです。
どうしてもエッジケースでパフォーマンスが以前から落ちる可能性があったからです。(もちろん6.0ですべて改善されたわけではないです)

パフォーマンス

medium.com

github.com

$ node benchmark/compare.js --old ./current --new ./8.3.0 arrays assert buffers child_process cluster crypto dgram dns domain es events fs http misc module net os path process querystring stream string_decoder timers tls url util v8 vm > compare-8.3.0.csv

Nodeのコアのベンチマークは上記のようにとります。(といっても普通に数日かかる量なので今回はissueのデータを使います。)

NodeのInternal ModulesのV8の5.8と5.9のパフォーマンスは以下のとおりです。
この頃は6.0がまだNodeのPRとして存在しなかったため5.9

github.com

量が多いので結論だけ言うと、劇的に改善される部分(100%以上)もあれば、劇的に遅くなる部分もあります。
例えば、buffers, events, http (!!), querystring, streams, string_decoder, url, utilは改悪になってしまってます。
今後、コアコードのパフォーマンスチューニングが必要なのではないかと思います。

Node.js Benchmarking

webpack

github.com

8.2.1(V8 5.8)

node benchmark.js  390.80s cpu 8:16.27 total

8.3.0(V8 6.0)

node benchmark.js  385.03s cpu 7:47.66 total

結果

webpackのベンチマークはあまり詳細がでないのでこれぐらいしか言えないですが、数秒程度速くなる可能性が見込まれると思います。

ESLint

$ node Makefile.js perf

8.2.1(V8 5.8)

Loading:
  Load performance Run #1:  370.81079ms
  Load performance Run #2:  138.677693ms
  Load performance Run #3:  162.385871ms
  Load performance Run #4:  147.627503ms
  Load performance Run #5:  138.628092ms

  Load Performance median:  147.627503ms


Single File:
  CPU Speed is 3100 with multiplier 13000000
  Performance Run #1:  5423.646407ms
  Performance Run #2:  5004.476339ms
  Performance Run #3:  5003.407218ms
  Performance Run #4:  5906.832898ms
  Performance Run #5:  5831.056636ms

  Performance budget exceeded: 5423.646407ms (limit: 4193.548387096775ms)


Multi Files (0 files):
  CPU Speed is 3100 with multiplier 39000000
  Performance Run #1:  15058.862498ms
  Performance Run #2:  13073.789987ms
  Performance Run #3:  12624.443172ms
  Performance Run #4:  12712.246881ms
  Performance Run #5:  16854.266736ms

  Performance budget exceeded: 13073.789987ms (limit: 12580.645161290322ms)

8.3.0(V8 6.0)

Loading:
  Load performance Run #1:  353.895106ms
  Load performance Run #2:  146.332188ms
  Load performance Run #3:  137.545153ms
  Load performance Run #4:  137.215065ms
  Load performance Run #5:  141.143209ms

  Load Performance median:  141.143209ms


Single File:
  CPU Speed is 3100 with multiplier 13000000
  Performance Run #1:  5469.148856ms
  Performance Run #2:  5300.968599ms
  Performance Run #3:  5379.501312ms
  Performance Run #4:  4955.262333ms
  Performance Run #5:  5242.219478ms

  Performance budget exceeded: 5300.968599ms (limit: 4193.548387096775ms)


Multi Files (0 files):
  CPU Speed is 3100 with multiplier 39000000
  Performance Run #1:  13120.178363ms
  Performance Run #2:  12653.286066ms
  Performance Run #3:  12639.912582ms
  Performance Run #4:  16274.700631ms
  Performance Run #5:  20859.144258ms

  Performance budget exceeded: 13120.178363ms (limit: 12580.645161290322ms)

結果

LoadingとSingle Fileは速くなっているが、Multi Filesが遅くなっている。
また、部分部分のパフォーマンスを見ると、必ずしもNode8.3.0が速いわけではない。
しかし、基本的には改善されていると思える。

まとめ

  • 8月中に8.3.0がリリースされる
    • 8.3.0でTurboFanとIgnitionがデフォルトになる v5.8 -> v6.0へ
    • WHATWG Encoding Standard(TextDecoderTextEncoder)が実装された
  • 今後、Node、Chromeはどんどん速くなる

PWAの実装をしてみた

一年以上前の記事なので、コードが古いです。気をつけて読んでください。

そういえばPWAの実装したことがなかったなと思ったので少し触ってみた。

PWAとは?

PWA(Progressive Web Apps)

インストールが不要で、不安定なネットワークでも素早く起動し、プッシュ通知を可能にします。
また、ホーム画面にアイコンも表示でき、アプリと同様の扱いをすることが可能となります。

つまり、アプリに近づけたwebですね。

以下の記事が詳しいのでそちらを見てください;)

developers.google.com

目的

  • https, localhostでしかService Workerは動かないので常に安全
  • Service Workerの更新プロセスにより常に最新
  • App Shellモデルによる構成でUIをネイティブにさらに近づける
  • プッシュ通知による再エンゲージメント
  • キャッシュすることにより、ネットワークの依存度を下げる

技術スタック

Service Worker

対応状況は以下の通り
f:id:about_hiroppy:20170727174456p:plain

Can I use... Support tables for HTML5, CSS3, etc

代表的な提供機能

  • オフライン機能
  • push通知
  • バックグラウンドコンテンツの更新
  • コンテンツキャッシュ

レシピ: ServiceWorker Cookbook

PWAのview

PWAにはApp ShellとContentというものがあります。
以下の図を見るとわかりやすいと思います。

f:id:about_hiroppy:20170727175055p:plain

developers.google.com

つまり、アプリケーションシェルというのはダイナミックコンテンツじゃない部分を指します。

App Shell

一番、PWAの実現で難しい部分であり、一番パフォーマンスの向上を図ることが期待される部分(らしい)
シンプルなデザインコンセプトで設計されます。
Service Workerのキャッシング機能により、パフォーマンスの向上が可能です。
最上位のアプリのロジック、ルーターなどがあります。

Content

動的なビューです。例えばTwitterのタイムラインとか。
ここもそれぞれのコンテンツで必要に応じてJSのチャンクは細かく切られます。

キャッシュ戦略

基本的に、App ShellとContentのJSは別チャンクにするべきです。
Service Workerにそれぞれのチャンクを保持させることにより、ユーザが前のページに戻った時に早く読み込むことが可能です。
理論上、App Shellの読み込みとContentの読み込みを別にすることにより、パフォーマンスとユーザビリティの向上が図れるらしいです。
App Shellはどのページでも常に読み込まれ、Contentは必要に応じて読み込むという感じです。

読み込みフロー

PWAは先にその時に必要なものだけを取り、それをキャッシュする仕組みです。
なのでwebpackでチャンクを細かく切ることにより、必要なリソースだけを読み込めるように設計します。
その後、Service Worker側で追加のリソースを事前に取得して、将来的な読み込みを行います。 また、ローディングの順序はApp Shellで基本的なUIを構築し、その後にコンテンツです。

Web App Manifest

manifest.jsonに名前、カラー、ホーム画面に置くアイコンの設定等を書きます。
PWAには必須です。

以下のようなスキーマになります。

{
  "name": "My PWA Sample",
  "orientation": "portrait",
  "display": "standalone",
  "start_url": ".",
  "short_name": "MyPWA",
  "description": "This is a sample App!",
  "background_color": "#f5f5f5"
}

また、HTMLでは以下のように指定します。

<link rel="manifest" href="/manifest.json">

developers.google.com

今回は、webpack-pwa-manifestというプラグインがあったのでそれを使いました。

github.com

デザイン

PRPL patternというのがあります。
より高速にモバイルでwebのエクスペリエンスを提供します。
Push、Render、Pre-cache、Lazy-loadで構成されます。

以下のAddy Osmaniの記事がとてもわかりやすいです!
The PRPL Pattern  |  Web Fundamentals  |  Google Developers

また今度、ブログにでも書こうかと思います。

FirefoxChromeしかService Workerないけどどうするの?

普通のHTML、CSS、JSなので問題はありません。
Service Workerはあくまでもネイティブ機能に近づける実現方法なので今までどおりにフォールバックします。

ネットワーク

Twitter Liteでhttp/2, GraphQLが使われています。

実装

github.com

上記のリポジトリで開発してみました。
SPA + Service Workerで実現しています。
今回はCSRのみです。

ライブラリ

react, react-routerで構築しました。
詳しくは、リポジトリwebpack.config.jsとかを見てください。

webpack-offline

Service Workerのファイル吐き出しと結合を行ってくれるプラグイン

注意点として、キャッシュファイルの保存容量が超えた時のエラーがわかりづらい。
Uncaught (in promise) DOMException: Quota exceeded. service worker は多分そのエラー。

なので、基本的にはdevではofflineを使わないでプロダクションのときにだけ使うようにしたほうがいい。(HMRもおそらくできないので)
ただ、もちろんswに本当に接続できているか確認したいときはあるのでそのときはライブラリ群のチャンクをキャッシュから外してデバッグしている。

様々なオプションがあるのでチューニングによるパフォーマンスとかの変化はありそう。

構成

ファイル

                                    Asset       Size  Chunks                    Chunk Names
                       vendor.2a193704.js     806 kB       5  [emitted]  [big]  vendor
node-8f3bc311d3d7fbab90a659d57e126fbf.png    3.73 kB          [emitted]
         Boron.content.bundle.2a193704.js     2.3 kB       1  [emitted]         Boron.content
         Argon.content.bundle.2a193704.js     2.3 kB       2  [emitted]         Argon.content
          List.content.bundle.2a193704.js    1.89 kB       3  [emitted]         List.content
                       bundle.2a193704.js    9.28 kB       4  [emitted]         bundle
        Carbon.content.bundle.2a193704.js     2.3 kB       0  [emitted]         Carbon.content
                            manifest.json  367 bytes          [emitted]
                               index.html  462 bytes          [emitted]
                                    sw.js    23.2 kB          [emitted]
               appcache/manifest.appcache  265 bytes          [emitted]
                   appcache/manifest.html     3.3 kB          [emitted]

ファイルは上記のように分けました。
vendor.jsではライブラリのコードのみが入っています。
なので一番サイズが大きいです。
ライブラリのバージョンが頻繁に変わらないためコアコードから隔離します。

bundle.jsがApp Shellです。
ルーティングとToolbarを持っています。
ベストプラクティスがわからないですが、これは一緒にしないほうがいいかもです。

*.content.bundle.jsがcontentです。
今回は、Argon, Boron, Carbonの三種類とルートページのリスト、合計4チャンクあります。
ちなみにNodeのLTSの名前がこの三種類です(v4, v6, v8)

ルーティング

慣れているreact-routerを使う。
必要な時にcontentのチャンクを取得するためにlazy loadを使います。

react-routerには慣れているつもりだったが、v4からgetComponentがなくなっていることに気付いてなかった。。

昔は、

<Route
    path="/"
    getComponent={(location, callback) => {
      require.ensure([], require => {
        callback(null, require('./Root'))
      }, 'Root')
    }}
  />

みたいに書けたはずなのに今は書けなくなっている。

調べた限り多分、FBの方が書いてたこれが一番キレイな書き方。

Quick and dirty code splitting with React Router v4 · GitHub

うーん。。。 ラッパーを書かないといけないの。。(あとreact-routerのリファレンス読みづらいんだよね。。)

ということで、これをラップしてたライブラリがあったので今回はそれを使った。

github.com

ただ、残念なことに<Switch>が対応してなくて、つらい。。
今PRが出ているのでそれ待ちという状態です。
Can not use with Switch · Issue #4 · mhaagens/lazy-route · GitHub

しょうがないので、/に対してexactを付けることにした。

// 長いので省略部あり

const Routes = () => (
  <App>
    <Route
      exact
      path="/"
      render={() =>
        <LazyRoute
          component={
            import(/* webpackChunkName: 'List.content' */ './components/contents/List')
          }
        />
      }
    />
    <Route
      path="/argon"
      render={() =>
        <LazyRoute
          component={
            import(/* webpackChunkName: 'Argon.content' */ './components/contents/Argon')
          }
        />
      }
    />
  </App>
);

AppはView全体を構築します。
この中にToolbarが入っており、this.props.childrenが上記に当てはまったルートになりそれをレンダリングします。
よくreact-routerでやる部分的更新の手法ですね。

しかし、今回はレンダリング時にファイルを取得し読み込み流したいので動的に取得する実装が必要です。
なのでstage-3のdynamic importを使う必要があります。(webpack2以降はデフォルトで入っています)

アセットのインストール

f:id:about_hiroppy:20170727190449p:plain

このような感じで保存される。 キャッシュの種類は main, additional, optional の三種類ある。

mainはinstallイベント時にservice workerにキャッシュされ、もし失敗したら全部のキャッシュはされません。
additionalmainが正常にロードされた後、ロードされます。
optionalはサーバからfetchされたときのみキャッシュされるので、事前にダウンロードしません。

github.com

今回はindex.htmlと各種JS,画像を保存しているので、これでたとえserveしていなかったりネットを切っている状態でも恐竜が現れるのではなく通常のページが表示されます。

ネットワークタイムラインはこのようになります。
f:id:about_hiroppy:20170727191352p:plain

sizeのところを見るとわかりますが、Service Workerからコードを取得しています。
ネットワークが切れているので、sw.jsの取得は失敗しますがコアコードはすでに取得済みなのであたかも生きているようにレンダリングされる。
また高速です。(vendor.jsとか重いのに。。)

API周り

今回は、通信周りの実装を行っていないのでコードはありませんが、
Twitter LiteではAPIを叩いた後Normalizrを通してReduxに効率よくデータを渡しています。 また、IndexedDBにもその結果を保存します。

SSR

今回のサンプルではやっていませんが、基本的にはやったほうがいいと思っています。
Twitter Liteでは、認証をし、初期状態の構成をし、App Shellのレンダリングをする設計になっています。
Twitter Liteをインスペクタで色々見ると楽しいかも。

資料

developers.google.com

The PRPL Pattern  |  Web Fundamentals  |  Google Developers

blog.twitter.com

medium.com

さいごに

手探りでやっていてこれがすべてベストプラクティスではなかったり、誤読があるかもしれないので、何かあればPRやIssue、コメントなど出してもらえると助かります:p

英語

今勤めているメルカリにはDMM英会話を契約させてもらって会社でレッスンをしていい素晴らしい制度がある。

自分は、DMM英会話を解約して会社の方の契約でやろうと思って一ヶ月ちょいぐらいたったがその結果を記録しておきたかったので書いた。

結果として、自分でお金を払ってないのは自分の性格上、長続きしないという結論に至った。(本当に会社には申し訳ないです)
どうも日々お金を払っているという感覚がなく、仕事や作業を優先してしまうことがわかった。


さて言い訳はさておき、自分はフロントエンドチームに所属しているが最近、また外国人の方が増えた。
日本語は喋れない方だったので共通語が完全に英語となった。(元々、他の外国人の方もいたが日本語が理解できる方だったのでたまに日本語でもよかった)

結論としてご飯やMTG、雑談等で英語で会話する機会が増えたので日々英語を喋るということはクリアーしており、一旦これでいいのではないかなと思っている。 DMM英会話、予約取るまでがめんどいというか腰が重い。。

メルカリでは、GitHub上では基本英語で会話しており英語に触れる機会が昔よりかなり多くなった。

特に同じフィールドのエンジニアと英語で会話できるのは一番の幸せであり、いい練習にもなっていると思う。
とりあえず英語喋るときに緊張するのをいい加減にやめたいのと単語力を高めたい。。。

Node.js FoundationとNode.jsについて

Node.js Foundation

Node.js

JoyentのNode.js開発停滞を見直すためにLinux Foundation以下に作られた財団。後にio.jsも合流しました。
オープンガバナンスモデルを採用しています。

www.slideshare.net

CIのサーバのホスティングやCollaboratorsのsummitやcode & learnなどの旅費などの管理(出費)をしています。
Node.js foundationは後援している企業によって支えられています。 Members - Node Foundation

相関図

f:id:about_hiroppy:20170703093327p:plain

委員会

TSC(Technical Steering Comittee)

github.com

Node.jsのCore, それに関連のあるワーキンググループのすべての統括をします。
https://github.com/nodejs/TSC#tsc-scope

CTC(Core Technical Committee)

github.com

Node.jsのCoreの技術委員会です。
Coreというのはnodejs/nodeを指します。

CTCでは毎週MTGを行っており、そこでPRやIssueで相談があるものは話されます。(ctc-reviewが必要になった場合)
また、CTCのメンバーは投票に偏りが出る可能性があるため、同じ雇用先のメンバーがCTC全体の1/3いてはいけません。

Core Working Groups

Technical Working Groupsの中でもCoreなのが以下になります。 これらはTop-Level Working Groupsに所属します。
CTCによって作成されるワーキンググループです。
CoreのNodeとは独立して扱われます。(Coreのコミットを権限持っていても以下のWGに対して必ずしも権限を持っているわけではない)

  • Website
    • Node.js のサイトのメンテナンスを行います
  • Streams
    • Node.jsのStreams APIのサポート及び改善を行います
  • Build
  • Diagnostics
    • ツールベンダーに対して信頼性の高い診断ツールを提供します
    • inspectorプロトコルやAsync Hooks
  • i18n
  • Evangelism
    • Node.jsの開発状況等を世界、コミュニティに知らせることを行います
    • 後ほど、CommCommへ移動されます(まだ正式にはこちらで書かれているのでここにも書きます)
    • github.com
  • Docker
    • 公式のDockerイメージを管理します
  • Addon API
    • NANのようなネイティブアドオンを作る作者のための抽象レイヤーのプロジェクトのメンテナンスを行います
  • Benchmarking
  • Post-mortem
  • Intl
    • Node.jsの国際化(i18n)、及び地域化(l10n)のサポートと改善を行います
    • コンテンツの翻訳に関してはi18n working groupが責任を負います

Working Groups | Node.js

また、Core Working Groupではないが他のworking group(e.g. promise, API, etc...)、及びteam(HTTP, HTTP/2, Smoke Testing, etc..)などがあります。
https://github.com/nodejs/TSC#dependent-projects https://github.com/nodejs/TSC#adjacent-projects

CommComm(Community Committee)

github.com

Node.jsの全体のコミュニティに関して統括する委員会です。
最近できたばかりなので今後発展していくと思います。

もともと、Top-Level Working GroupsのInclusivityがCommCommになった感じです。
なので、Top-Level Working Groupsは現在、Technical Working Groupsしか存在しません。

github.com

Working Groups

Teams

  • nodejs-collection

    • Node.jsに関する記事を管理します
    • 記事を提出し、それがレビューされNode.js Foundation Mediumに置くことが可能となります
    • medium.com
  • community-events

    • コミュニティのイベント主催者同士が協力しあう場所
  • education

    • 教育も今はTSCの下ですが、CommCommへ移動する流れです
    • github.com

今後のTSCからCommCommへの移行リストは以下のとおりです。 github.com


会議

それぞれのワーキンググループでは会議が開かれます。
この会議を見ることにより、最新のNode.jsの情報を得ることができます。

カレンダー

Node.js (obsolete)
久しぶりに見たけど、5月ぐらいから記録されてないですね。。

CoreのMTGノート

https://github.com/nodejs/CTC/tree/master/meetings

MTGの動画リスト

www.youtube.com

Summit

github.com

Node.js Collaborator Summitと呼ばれる、Node.jsのコラボレータが集まる定期的なsummitがあります。
前回の開催は5/4, 5で行われました。
ここではNode.jsの問題点、改善点などのコアな話を現地で話し合います。


Node

github.com

NodeはCore Collaborators(CTCを含む)により管理されます。

LTS(Long Term Support)

github.com

LTS Working Groupにより管理されます。
Node.jsの長期サポートを行い、偶数バージョンがそれに当たります。

f:id:about_hiroppy:20170703093852p:plain

毎年4月(今年の8はv8のバージョン周りで5月)にリリースされる偶数バージョンが対象で毎年10月から開始されます。
この時の10月に奇数バージョンが切られそれがmaster(current)になります。
LTSは18ヶ月サポートされ、その後にメンテナンスが12ヶ月あります。
currentに入ったバグ修正や脆弱性修正がこのサポートされているバージョンへバックポートされる仕組みです。

LTSは今のところ、v4, v6, v8(これは10月から)です。
Latestはcurrentになります。(masterブランチのバージョン)

担当リポジトリ

すべてNodeのリポジトリにIssueやRFCを投げるのではなく、用途にあったリポジトリに投げる必要があります。

Node.jsに具体的な機能追加がある場合

github.com

将来的な機能追加の提案

github.com

ヘルプ

github.com

本体のバグ、修正はCoreへ提出してください。

CI

Nodeではjenkinsを使って様々なプラットフォームのテストをしています。
arm-fanned, aix, arm, freebsd, linux, linux-fips, linux-one, osx, ppc-linux, smartos, windows-fanned上でテストが行われます。
また、本体コードはもちろんですが、ドキュメントのlintもあります。

GitHub - nodejs/build: Better build and test infra for Node.

PR

PRのマージには最低48時間、休日は72時間の時間を必要とします。
これはレビュワーが世界中にいるため時間がレビューされる前にマージされるのを防ぐためです。
またマージには2人以上の承認が必要です。

貢献する

読むべきもの

CoC(Code of Conduct)

行動規範です。 これは必ず守るべきものです。
TSC/CODE_OF_CONDUCT.md at master · nodejs/TSC · GitHub

Contributing to Node

PRを提出するまでの手順が書かれています。
https://github.com/nodejs/node/blob/master/CONTRIBUTING.md

Good First Contribution

簡単に修正できるIssueに関しては、この good first contribution というラベルが付けられているのでそれを拾って作業を始めるのは最初の一歩としていいと思います。
Issues · nodejs/node · GitHub

他には、実装してないけど先にコメントアウトしてテストだけ書いてくれてたりするのでそれを見て実装するのもありだと思います。

Documents

Nodeリポジトリにはapiのドキュメントがあります。
ドキュメントは大切ですが、なかなか整備が追いつかない部分(外部リンク切れ等)があります。

サポート

もし、「やってみたいけどよくわからない」や「これ大丈夫なの?」などがあればNode.js日本ユーザーグループのslackにある#node-contributionで気軽に聞いてください。
Japan Node.js Association

さいごに

Node.jsが今どのように管理されていて、どういう活動をしているかというのを多くの人に知ってもらえれば嬉しいです。
また、少しでも興味を持っていただけたら嬉しいと思います。