技術探し

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

英語

今勤めているメルカリには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が今どのように管理されていて、どういう活動をしているかというのを多くの人に知ってもらえれば嬉しいです。
また、少しでも興味を持っていただけたら嬉しいと思います。

Node学園26時限目まとめ

25時限目に引き続きオーガナイザーをしました about_hiroppy です。

今回の26時限目は、150人来ていただき本当に楽しく勉強になる時間でした。
改めてありがとうございました。
また、メルカリさんには会場整理、食事様々なことを手伝っていただき感謝します。ありがとうございました。

さて、今回の勉強会ですが、各フレームワークの話や型の話、低レイヤーのモジュールの話、 Chunked Encodingの話と結構コアな話が多い印象を受けました。
また懇親会では、古川さんからNode Collaboration Summit(Nodeのコアな人が集まるサミット(自分はこの回は行ってないです))やJSConf EU 2017で上がった議題の話がありました。(主にv8の最適化の話)
自分のwbepack3の発表を期待していた方はスミマセン(資料作ってなくて発表できなかったので。。。)

特に、React、vue、angualrの話が集まったことにより各フレームワークのことが知れて大変面白かったです。
次は自分もNodeの話をしようと思います😙

nodejs.connpass.com

進行しながら各LTの話をメモしようと思っていたのですが予想以上にできなかったので資料だけまとめておきます

資料一覧

capability of react fiber

speakerdeck.com

vue on storybook

speakerdeck.com

dependent type and typescript

speakerdeck.com

production E2E test with ProxyServer

speakerdeck.com

Angular PWA

slides.com

Nested Native Modules

ごめんなさい、資料見つけれなかったのでもし見つけたら更新します><

Chunked encoding を使った高速化の考察

www.slideshare.net

[懇親会] Node Collaborators Meetup & JSConf.EU

speakerdeck.com

まとめ

今回はNodeという単語を(おそらく)一回しか聞いてない!
次はまた二ヶ月後の8月です! お楽しみに:)

個人的には、Node, React, Vue, Angularでもっとこまめに情報交換とか色々できたらいいなと思いました。

宣伝

11月25, 26にNode学園祭があります! 登壇者、参加者募集していますので是非よろしくお願いします!

nodefest.jp

react-router, redux-sagaのテストの書き方

以下のリポジトリを参考にしてください

github.com

記事が長くなってしまうので、プロダクションのコードは折りたたみしておきます。

使用ライブラリ

  • Jest
  • Enzyme
  • jest-serializer-enzyme(enzymeでsnapshotとるため)
  • redux-mock-store
  • redux-saga-test-plan

enzymeですが、snapshotに対応してないため react-test-rendererが最近の流れかもしれません。(むしろ推奨?)

facebook.github.io

github.com


react-router

github.com

react-router@4とreact-router-redux@5を使っています。

Routes.js

各パスをルーティングする部分です。
親がこのファイルをimportします。

import Routes from '../Routes';

const Root = () => (
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <Routes />
    </ConnectedRouter>
  </Provider>
);

このようにファイルを分離することによりテストをしやすくします。

テストコード

import React from 'react';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import { MemoryRouter } from 'react-router';
import configureStore from 'redux-mock-store';
import { render } from 'enzyme';
import Routes from '../../src/renderer/routes';
import rootReducer from '../../src/renderer/reducers';

describe('routes', () => {
  const createDOM = (path = '/') => {
    const state = createStore(rootReducer).getState();
    const store = configureStore()(state);

    return render(
      <Provider store={store}>
        <MemoryRouter initialEntries={[path]}>
          <Routes />
        </MemoryRouter>
      </Provider>
    );
  };

  it('should render the root page', () => {
    expect(createDOM()).toMatchSnapshot();
  });


  it('should render the login page', () => {
    expect(createDOM('/login')).toMatchSnapshot();
  });
});

4系から入ったMemoryRouterを使い、テストをします。
基本的に、スナップショットで比較するだけで自分はいいと思っています。(もちろん確認でwrapper内に対してfind, contains等してもいいとは思います)
react-router-reduxを使っている場合、storeに入れるrouteのlocationのkeyがテスト毎ごとに異なるので、mountではなくrenderを使います。


Redux-saga

github.com

非同期処理をmiddlewareで行うために使います。

Root

各ファイル(e.g. ページ毎)のforkを一括で行います。

テストコード

import rootSaga from '../../../src/renderer/sagas';

describe('root saga', () => {
  it('should register sagas', () => {
    const tasks = 2;

    expect(rootSaga().next().value.length).toEqual(tasks);
  });
});

昔は、rootSaga()._invoke().value.length で取れていまいたが、今は取れません。
ここでは登録されているタスク数(各ファイル数)の個数を確認します。

Partial

それぞれのファイル内のタスクのビジネスロジックが書かれます。
このファイルのrootでそれぞれのactionとタスクを紐付けし、その処理を追えた後再度アクションを発行します。

テストコード

import { expectSaga } from 'redux-saga-test-plan';
import auth from '../../../src/renderer/sagas/auth';

describe('auth saga', () => {
  const storeState = {
    auth: {
      mail: 'a@b.com'
    }
  };

  it('should take on the LOGIN action', () => {
    return expectSaga(auth)
      .withState(storeState)
      .put({
        type   : 'LOGIN_SUCCESS',
        payload: {
          mail: '--a@b.com'
        }
      })
      .dispatch({
        type: 'LOGIN',
        mail: '--a@b.com'
      })
      .run();
  });

  it('should fail on the LOGIN action', () => {
    return expectSaga(auth)
      .withState(storeState)
      .put({
        type : 'ERROR',
        error: {
          code: 'ERROR_LOGIN'
        }
      })
      .dispatch({
        type: 'LOGIN',
        mail: 'a@b.com'
      })
      .run();
  });

  it('should take on the LOGOUT action', () => {
    return expectSaga(auth)
      .withState(storeState)
      .put({ type: 'LOGOUT_SUCCESS' })
      .dispatch({ type: 'LOGOUT' })
      .run();
  });

  it('should fail on the LOGOUT action', () => {
    return expectSaga(auth)
      .withState({
        auth: {
          mail: ''
        }
      })
      .put({
        type : 'ERROR',
        error: {
          code: 'ERROR_LOGOUT'
        }
      })
      .dispatch({ type: 'LOGOUT' })
      .run();
  });
});

redux-saga-test-planを使ってテストしていきます。
基本的にdispatchして、putでyieldされた結果(reducerへ渡す部分)を期待します。
自分はエラー系を全部sagaとして一枚挟んでいます。
template-electron/error.js at master · my-dish/template-electron · GitHub

Selectors

saga内で状態がほしいときに取得する関数を定義します。

テストコード

import { createStore } from 'redux';
import rootReducer from '../../../src/renderer/reducers';
import * as selectors from '../../../src/renderer/sagas/selectors';

describe('selectors', () => {
  const storeState = createStore(rootReducer).getState();

  it('should get auth.email', () => {
    expect(selectors.getMail(storeState)).toEqual('');
  });
});

自分はselectorsに関してはredux-saga-test-planを使いません。
selectorsは単純な関数であるので、stateだけしっかりしていればいいかなと思っているからです。


さいごに

storeでredux-devtools-extensionとかを使っているとテストできない箇所が出てしまうのどうにかならないかな。。。

今月の28日、Node学園 26時限目やりますので是非きてくださいね!(募集は26から)
react, vue, angular, jsconf and Node Collaboratos Summit, webpack3(多分...), etc...の話が聞ける予感する 😁 nodejs.connpass.com

util.callbackify()というのがそろそろNodeへ入りそう

github.com

util.promisify() に関連して提案されました。

abouthiroppy.hatenablog.jp

github.com

名前の通り、非同期関数をコールバック関数に変換する関数です。
つまり、util.promisify()の反対版です。

const util = require('util');

async function fn() {
 return await Promise.resolve('hello world');
}

// or
// function fn() {
//   return new Promise((resolve, reject) => {
//     resolve('hello world');
//   });
// }

const callbackFunction = util.callbackify(fn);

callbackFunction((err, ret) => {
 if (err) throw err;
 console.log(ret);
});

引数にAsyncFunctionをとり、戻り値にコールバックが入った関数が返ります。

semver-minorとして入り、早ければ次のNode8.2.0に入るかもしれません。

babelへOptional Chainingが追加される

Optional Chaining

github.com

// before
const fooInput = myForm.querySelector('input[name=foo]');
const fooValue = fooInput ? fooInput.value : undefined;

// after
const fooValue = myForm.querySelector('input[name=foo]')?.value;

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

obj?.foo?.bar?.baz; // 42
obj?.qux?.baz; // undefined
obj?.foo.bar.qux?.(); // undefined

function test() {
   return 42;
}

test?.(); // 42  
exists?.(); // undefined

class Test {
}

new Test?.(); // test instance
new exists?.(); // undefined

?.演算子の左の式の評価がundefined または nullのときに右の式が評価されず、undefinedを返します。

現在のステータスはstage-1です。

Babylon

babylonへOptional Chainingの追加と?.トークンタイプが追加されました。 babylonとは、Babelのために作られたJSのパーサで、acornがベースで作られています。 github.com

Babel

github.com 現在レビュー中です。
またこのPRのマージ先は 7.0.0 なので少し待たないといけないかもです。(現在 alpha.12)
このPRでできるbabel-plugin-syntax-optional-chaining というパッケージが後ほど babel-preset-stage-1 へ入ると思います。

ドワンゴを退職してメルカリに入社した

2年ちょっと働いたドワンゴを昨日退職して、今日からメルカリに入社します。

誰?

今年のニコニコ超会議で25歳になったエンジニアです。
JavaScriptが好きです。

ドワンゴという会社

本当に自由です。
こんな会社あるのかなって思うぐらい自由でした。
もちろん、仕事はするのですが会議とかに遅れなければ何時に出社してもいいという印象です。(チームによるかもですが)
また、エンジニア主体で企画を出しやすいです。 例えば最近だとマストドンの件とか。
ドワンゴのslackは日本で一番すごいと思うのですが、自分が見える範囲で2962チャンネル、絵文字が大量にあり見てて飽きなかったです。
技術的には、ドワンゴScalaErlangの印象が強いかもしれないですがフロントエンドも強いと自分は思います。
あまり外にコミットしている印象は無いのでそういう印象はないかもしれないですが。。
自分が所属していた部署は特殊で、自分が入社した時にできた部で2015年に入社した早期配属の人が所属する部署でした。
なので、同期が多く(10人ぐらい?)大変楽しく刺激的でした。
社内全体的に本当にみんなフレンドリーで風通りがすごいいいです。
また、自分の大学で仲のいい人がたまたま(?)たくさん入ってきていて大学と同じ生活ができてましたのもすごい好きでした。
今振り返ると、ドワンゴは理系の研究室と変わらない生活ができる会社だと思います。

ドワンゴでやったこと

自分はフロントエンドエンジニアとして働いていました。
ドワンゴでは3年で2回のサービスインを経験させて頂きました。

ニコナレは2つ目の仕事で、N予備校は3つ目の仕事でした。

転職理由

メルカリは今もっとも急成長している企業です。
その開発に参加してみたかったです。
それと英語力不足。
OSSでメンバーになったりするとハングアウトで通話をしたりサミットに出たりが多くなります。
例えば、Nodeだったら毎年最低一回はcore collaboratorが集まって議論し合うサミットだったり別プロジェクトだと月1で電話したりとか。。
そういう状況のときに会話ができない自分がいました。
メルカリでは日本だけではなく、アメリカやイギリスにスコープを向けています。
自分は必要にならないと勉強しないダメな性格なので仕事で英語を喋れる環境が欲しかったです。


メルカリではもちろんJSを書いていくつもりです。
自分はまだ、JSにコミットし続けたいと思っています。
また、今年は日本での活動を積極的にがんばれたらいいなと思います。
GitHubの活動はもちろん今まで通りですが、Node.js 日本ユーザーグループでの活動をもっと積極的にしていきたいです。

これからもどうぞよろしくお願いします!!

amzn.asia