技術探し

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

Chrome Dev Summitに行ってきた話

SFOで行われたChrome Dev Summitに行ってきました。

developer.chrome.com

メインの話はPWA/AMPだった感じだった。
ただの感想文なので特に技術的な話はココでは無しです。

Chrome Dev Summit2017

f:id:about_hiroppy:20171023080036j:plain f:id:about_hiroppy:20171023081100j:plain f:id:about_hiroppy:20171023095031j:plain f:id:about_hiroppy:20171023080825j:plain f:id:about_hiroppy:20171024154819j:plain f:id:about_hiroppy:20171024123337j:plain

よかったこと

学びが多い

PWA/AMPを進めているGoogleだからこそ自分たちが知らないことを話していて勉強になった。
主に、様々な会社の実例が入っていてよかった。
また、WASM, VR, Media等の自分が詳しくない分野の話を聞けて興味がでた。(特にMedia)
これは後ほど別でまとめますのでお楽しみに;)

海外カンファレンスの敷居が案外低かったことがわかった

実は自分は今回が初の海外カンファレンスだったりする。
知らない外国人の方やあまり話せてなかった日本人の方とも話せてよかった。
(ありがとうございます、及川さん、らこさん、armorik83さん、英志さん、etc...:))
知らない人と技術の話をするのは楽しく、様々な分野(VR, etc...)の方と話していた。
また、有名なコミッターの方も多く、そういう人と会える貴重な機会である。(hzoo, sean larkin, etc...)
行ったことがない人は是非行ってみて欲しいと思った、すごい楽しい。(日本には無さそうなお祭り感があった)
あと日本に昔住んでいた外国人の方が多かった(自分は2人と会った)

Googleの有名なエンジニアと話せた

今回は、Alex Russell さんと Paul Irish さんに 30 - 60 minぐらい話せてよかった。
TC39の話、PWAの話、Lighthouseの話、etc...、な話をしました。
TC39のメンバーの方と顔を合わせて喋るのは初めてだった。
こんな貴重な体験、普通ではできないので 宇都宮さん には感謝しかありません。

将来

自分が仕事として何をしたいのかがわかった気がする。
また、今自分に足りないものがわかった。 それをクリアすればいいだなーっていう感じ。
相変わらず海外で働きたいなっていう考えは変わらずです。

OSSへのモチベーション復帰

自分がメンテをしているOSSが発表中に出てくると現実感がある。
頑張ろうって思った。

地域

サンフランシスコ

ちょうど先週はインディアンサマーだったので、雲ひとつなく大変過ごしやすい気候だった。
本来はもっと寒いらしく革ジャンを持っていったのだが一回しか使わなかった。
また、メルカリにはUSオフィスがありお邪魔した。
SFOは危険な地域もあったりするので、行く前に調べたほうがよさそう。(テンダーロインとか)
どこのマンションにもプールやスポーツジムが家についており、最高だった。
ただ、その反面、お風呂とかトイレとかは日本の方が良さそう。

f:id:about_hiroppy:20171021113546j:plain f:id:about_hiroppy:20171025093513j:plain f:id:about_hiroppy:20171024181900j:plain

マウンテンビュー

こちらも雲ひとつなく晴天であった。
みんなTシャツだったりする。
入ったらすぐにGoogle社だったりする。

Google

本当に大学のキャンバスみたいだった。
多国籍だったり、お昼からビーチバレーしたりとかとりあえずすごかった。
こういう風に開放的な方が生産効率は上がるのかな?(メリハリは付きそう)
f:id:about_hiroppy:20171025110427j:plainf:id:about_hiroppy:20171025110538j:plain

最後に

自分がメンテナンスしているOSSがカンファレンスのスライドで発表されるの最高に嬉しいのでこういう報われ方もあるんだなーって思いました。
また、技術的内容などの報告は別ブログや明日のNode学園で話します;)

nodejs.connpass.com

今後も積極的にカンファレンスに参加したいなーって思う。
そして家帰ったら、Google home miniが届いてたのでNature Remoを買ってすべて一括管理するようにしようと準備をし始めた。

未完成のパズルを思い出す

AyoでWorkerの実装が進んでいる

Chrome Dev Summitのため、サンフランシスコで書いています。

さて、最近、Ayo側でWorkerの動きが活発なのでそろそろまとめてみた。
f:id:about_hiroppy:20171023090343p:plain 昨日一日でこれだけ出ている...!

Ayo側

$ ./ayo --version
v9.0.0-pre

github.com

実装者はAnna、過去にNodeにWorkerを入れようという動きもあったため、petkaantonov/io.jsからベースは引用されています。
例えば、initial implementationはこちら

github.com

この間、第一回目のコアチームミーティングが開催されたが、自分は参加してないので何が話し合われたのかわからないです。
後ほど、アップされるとのことなのでそれを待ちます。

github.com

ただ、WorkerがAyoのコアには入っているので、基本的にはStabilityを2まで持っていく方針だと思われます。
Stabilityとは? About this Documentation | Node.js v8.7.0 Documentation

これが最初のNodeとAyoとの技術的な優位性です。

Node側

NodeもAyoからのコミットを入れるかどうかのPRが上がっています。

github.com

ただ今現在、このPRの1つしか存在せず、進んでいないです。
もし、入れたいと思う人がいればここにコメントするとよさそう;)

Workerとは?

独立したスレッドで動作する環境を構築し、それらの間にメッセージチャンネルを構築します。
WorkerはCPU集約型のJavaScriptの操作を実行するのに便利です。
子プロセスやClusterとは違い、それらの間でWorkerはArrayBufferインスタンス間の転送をしたり、 それらの間でSharedArrayBufferインスタンスを共有をすることによりメモリを効率的に共有することが可能です。

Eventの説明は省きます

const worker = require('worker');
const { Worker, isMainThread, postMessage, workerData } = require('worker');

if (isMainThread) {
  module.exports = async function parseJSAsync(script) {
    return new Promise((resolve, reject) => {
      const worker = new Worker(__filename, {
        workerData: script
      });
      worker.on('message', resolve);
      worker.on('error', reject);
      worker.on('exit', (code) => {
        if (code !== 0)
          reject(new Error(`Worker stopped with exit code ${code}`));
      });
    });
  };
} else {
  const { parse } = require('some-js-parsing-library');
  const script = workerData;
  postMessage(parse(script));
}

メソッド・変数

isMainThread

Workerスレッド内で実行されているかを返します。
実行されてなければ、trueを返します。

postMessage(value[, transferList])

Workerスレッド内でのみ、使用可能です。
worker.on('message')を経由し、受信される親スレッドのWorkerインスタンスにメッセージを送信します。

threadId

現在のスレッドのIdを返します。

workerData

Workerコンストラクタに渡されるデータの複製を含む任意のJavaScriptデータ。

クラス

MessageChannel

このインスタンスは、非同期の双方向通信チャネルを示します。
独自のメソッドを持ちません。

const { MessageChannel } = require('worker');

const { port1, port2 } = new MessageChannel();
port1.on('message', (message) => console.log('received', message));
port2.postMessage({ foo: 'bar' });
// prints from L4: received { foo: 'bar' }

上記のコードは、終了しません。(exit)
ずっと待ち続けます。

MessagePort

非同期の双方向通信チャネルの一端を表します。
構造化データ、メモリ領域、および他のMessagePortsを異なるWorkerまたはVMコンテキスト間で転送するために使用できます。 これは、EventEmitterの拡張です。
また、EventTargetsではなくEventEmitterであるMessagePortsを除いて、この実装はブラウザのMessagePortsと同じです。

postMessage(value[, transferList])

Worker

独立したJavaScript実行スレッドを示します。
殆どのAyoのAPIは、この中で実行可能です。

new Worker(filename, options)
filename

filename絶対パスでなければなりません。
options.evaltrueの場合、パスではなくJavaScriptコードを含む文字列となります。

options
  • eval Workerがオンラインになった時に実行されるJavaScript
  • data クローンされ、require('worker').workerDataとして利用可能となるJavaScript値。 複製は、Structured_clone_algorithmと同様に行われできない場合はエラーが飛ばされます(e.g. 関数が含まれている場合)

developer.mozilla.org

  • maxSemiSpaceSize スレッドのヒープのセミスペースのオプションのメモリ制限(MB単位)。
    ほとんどのshort-lived objectsはここに含まれます。

  • maxOldSpaceSize スレッドのメインヒープのオプションのメモリ制限(MB単位)。

const assert = require('assert');
const { Worker, MessageChannel, MessagePort, isMainThread } = require('worker');
if (isMainThread) {
  const worker = new Worker(__filename);
  const subChannel = new MessageChannel();
  worker.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1]);
  subChannel.port2.on('message', (value) => {
    console.log('received:', value);
  });
} else {
  require('worker').once('workerMessage', (value) => {
    assert(value.hereIsYourPort instanceof MessagePort);
    value.hereIsYourPort.postMessage('the worker is sending this');
    value.hereIsYourPort.close();
  });
}
// prints from L8: received: the worker is sending this
Worker内の大きな違い
  • process.stdinprocess.stdoutprocess.stderrはnullに設定されています
  • domainモジュールは使えません
  • require('worker').isMainThreadfalseに設定されています
  • require('worker').postMessage()が使用可能で、require( 'worker')on( 'workerMessage')がエミットされます
  • process.exit()はプログラム全体を停止せずに単一のスレッドだけを処理し、process.abort()は使用できません
  • process.chdir()及び、グループまたはユーザーIDを設定するプロセスメソッドは使用できません
  • process.env環境変数に対する読み取り専用の参照となります
  • process.titleは変更できません
  • 明示的にWorkerサポートでビルドされていないネイティブのアドオンはロードできません
  • worker.terminate()が呼び出された結果、実行が停止することが可能性があります
  • 親プロセスからのIPCチャネルにはアクセスできません
postMessage(value[, transferList])

require('worker').on( 'workerMessage')を経由し、受信されるメッセージをworkerに送信します。
require('worker').postMessageと違い、require('worker').on( 'workerMessage')を経由することに注意して下さい。
require('worker').postMessageworker.on('message')

terminate([callback])

可能な限り早く、workerスレッド内のすべてのJavaScript実行を止めます。
callbackは終了したら呼び出されます。

threadId

参照されるスレッドIDを返します。

最後に

これらはstabilityが1なのでまだ不安定 + 変更があります。
WorkerはClusterよりもパフォーマンスが良く、利便性があります。
今はAyoだけですが、今後Node側へも入る可能性はあるので注目しておいても良いかもです。

JavaScriptの現状と将来というタイトルで発表してきた

the present and future of JavaScript

情報処理学会若手の会で発表してきました。
三回目の参加で、二回連続30minのセッションをさせて頂きました。
前回は3年前に発表してその頃はまだ学生でした👨‍🎓

実はこの週、スライドにも書いてある通りバンクーバでNode InteractiveとNode関係者があつまるNode.js Collaborator Summitが開かれてました。
そちらの情報は他の方が何かしら報告してくれると思いますので、それを期待しています🙏

さて、それではスライドの内容を少し読み砕きましょう

ECMAScriptとは?

ECMAScriptとは、Ecma Internationalによって管理されるJavaScriptの標準化仕様です。
JavaScriptとは、ECMAScriptに基づく実装を指します。

エディション

そのころに選定された仕様をまとめたものがエディションです。
1997/06に最初のECMAScript 1が出ました。
そして、2015/06 からは毎年でるように変わりました。 (from ES2015)

TC39

ECMA-262とECMA-402を管理します。 JSの構文と国際化APIです。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Language_Resources

ここの委員会メンバーは各ブラウザの主要ベンダーと会社(e.g. Airbnb, FaceBook, PayPal, Bocoup, etc...)です。
また、委員会メンバーの推薦で所属している人もいます。

TC39プロセス

標準化されるまでに5つのプロセスを踏む必要があります。(stage-0 to stage-4)
このstageは二ヶ月に一回あるミーティングにより、変動していき、stage-4に入ったら次のリリースで正式に仕様として組み込まれます。

今年のスケジュールは以下のとおりです。

Dates Location Host
2017-01-24 to 2017-01-26 San Jose, CA PayPal
2017-03-21 to 2017-03-23 Portland, OR Mozilla
2017-05-23 to 2017-05-25 New York, NY Google
2017-07-25 to 2017-07-27 Redmond, WA Microsoft
2017-09-26 to 2017-09-28 Boston, MA Bocoup
2017-11-28 to 2017-11-30 San Francisco, CA Airbnb

各種stageの説明

stage-0(Strawman)

アイディアのフェイズです。
これは委員会メンバーではなくても、提出が可能です。
提出フォームから提出します。
そして、ドキュメントを作り、tc39/proposalsの方へそのリンクを追加するPRを提出する必要があります。

stage-1(Proposal)

ポリフィル、デモがあり、潜在的な問題の特定が必要です。
このステージではチャンピオンと呼ばれるものが必ず必要です。
チャンピオンは、提出者または共同チャンピオン(片方がTC39メンバー)でならなくては次のステージには進めません。

stage-2(Draft)

仕様に含まれる最初のバージョンです。
このstageにいることで仕様として含まれる可能性が高いです。
正式な構文記述の追加が必要です。

stage-3(Candidate)

このプロポーザルの終盤です。
各種ベンダーとユーザからのフィードバックをさらに求めます。
また、正式な仕様のドキュメントは完成しており、TC39のレビュワーとECMAScriptのエディタにより、レビューとサインオフされる必要があります。

stage-4(Finished)

次のリリースで正式な仕様として含まれるでしょう。
test262に合格していて、ブラウザベンダーの2つ以上で実装が組み込まれる必要が必ずあります。
また、ECMAScriptのエディタは仕様書に署名をする必要があります。

test262がBabylonに統合されました。

BabylonとはBabelのJSパーサです。

github.com

今回のMTG(60th)で変更したプロポーザル一覧

約2週間前に変動したプロポーザルの一覧です。

Proposal Stage Description
mport.meta 2 → 3
export ns from 'mod'; 2 → N/A it moved to https://github.com/tc39/ecma262/pull/1005
Array.prototype.flat{Map,ten} 1 → 2
throw Expressions 1 → 2
String.prototype.matchAll 1 → 2
Extensible numeric literals 0 → 1
First-Class Protocols 0 → 1 it was called `Interfaces` in stage-0
JSON superset 0 → 1
nullary coalescing 0 → 1
Partial application 0 → 1
Pipeline Operator 0 → 1
ArrayBuffer.transfer N/A → 0
Builtins.typeOf() and Builtins.is() N/A → 0
Object Shorthand Improvements N/A → 0

github.com

ES2015 - ES2017

スライドを見てください。
また、これは世の中に沢山いい記事があるので省きます。

ES2018

現在、stage-4にあるのは、Template Literal Revisionのみとなっています。

Template Literal Revision

ES2015にも、String Templateの中に、Tagged Templateという書き方がありますが、それには制限がありました。
Tagged Templateというのは、有名なlibraryだとstyled-componentsyo-yoが採用しています。
その制限というのが、Latexwindowsのpath, 8進数のエスケープなどを表現できない(エラーで落ちる)問題です。

const tag = (obj) => ({
  Raw: obj.raw,
  Cooked: obj
});

tag`\u{4B}`; // ES2015 ~
// { Raw: [ '\\u{4B}' ], Cooked: [ 'K' ] }

// ES2018 ~
tag`\uu ${1} \xx`; // a Unicode escape
// { Raw: [ '\\uu ', ' \\xx' ], Cooked: [ undefined, undefined ] }
tag`\100`; // an octal escape

このリリースでは、その制限をなくし、イレギュラーなエスケープはundefinedとして、Cookedに入れられます。

候補

現在、stage-3には以下のプロポーザルがあり、ES2018として組み込まれる可能性が高いです。

面白そうなプロポーザル

興味あるプロポーザルを話しました。
stage-1が多く、Syntaxが変動する可能性があるので注意してください。
Binary ASTは他の場所で話します😌

Class Fields

class Counter extends HTMLElement {
  x = 0;  // public fields
  #y = 0; // private fields

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

  clicked() {
    this.x++;
    this.#y++;
    window.requestAnimationFrame(this.render.bind(this));
  }

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

Promise.prototype.finally

let finished = false;

fetch()
  .then((res) => {
    // finished = true;
  })
  .catch((err) => {
    // finished = true;
  })
  .finally(() => {
    finished = true;
  });

同じ処理をthenとcatchで書かなくて良くなりました。

Optional Chaining

abouthiroppy.hatenablog.jp

Pipeline Operator

abouthiroppy.hatenablog.jp

Partial Application Syntax

function add(x, y) { return x + y; }

// before
const addOne = add.bind(null, 1); // this, the left(x = 1), the right(y = undefined)
addOne(2); // 3

// after
const addOne = add(1, ?); // apply from the left(x)
addOne(2); // 3

const addTen = add(?, 10); // apply from the right(y)
addTen(2); // 12

const f = (...x) => x;
const g = f(..., 9, ...);
g(1, 2, 3); // [1, 2, 3, 9, 1, 2, 3]

const res = a |> f(?, 1) |> g(?, 2); // const res = g(f(a, 1), 2);

今まではES5のbindで部分適用していましたが、これからは?がある場合に固定化されます。
また、spread operatorでも展開できます。

github.com

Promise.try

bluebirdと同じ、tryです。

function getUserById(id) {
  return Promise.try(() => {
    if (typeof id !== 'number') {
      throw new Error('id must be a number');
    }

    return db.getUserById(id);
  });
}

Temporal

日付の計算等の扱いが簡単になります。

let myCivilDate = new CivilDate(2016, 2, 29);
let newCivilDate = myCivilDate.plus({years: 1, months: 2});
//results in civil date with value 2017-4-28

github.com

まとめ

  • ECMAScriptは毎年更新されます
  • 誰でもプロポーザル出せるぞ!!
  • 次のリリース(ES2018)は2018/06です!

宣伝

2017/11/25 - 26 で東京Node学園祭2017をやるので是非来てくださいね;)

nodefest.jp

The End

それではJavaScriptライフを楽しんで!😎

github.com

Pipeline Operatorがstage-1へ

github.com

先月のTC39のMTGでstage-1になりました。

F#, OCaml, Elixir, Elm, Julia, Hack, LiveScriptなどと似たような機能を提供します。

function doubleSay (str) {
  return str + ", " + str;
}

function capitalize (str) {
  return str[0].toUpperCase() + str.substring(1);
}

function exclaim (str) {
  return str + '!';
}

let result = exclaim(capitalize(doubleSay("hello"))); // "Hello, hello!"

let result = "hello"
  |> doubleSay // ここの引数が `hello`になる
  |> capitalize
  |> exclaim; // "Hello, hello!"

上記のコードを読めばわかりますが、ネストされた関数を読みやすくします。

例えば、引数を複数持つ関数でPipeline operatorを使いたい場合は以下のようになります。

function double (x) { return x + x; }
function add (x, y) { return x + y; }

function boundScore (min, max, score) {
  return Math.max(min, Math.min(max, score));
}

let newScore = boundScore(0, 100, add(7, double(person.score)));

let person = { score: 25 };
let newScore = person.score
  |> double // ここの引数が25
  |> _ => add(7, _) // `_`はdoubleの戻り値
  |> _ => boundScore(0, 100, _); // 57 // `_`はaddの戻り値

自分のページを更新した

about-hiroppy.com

一年ぶりぐらいに更新した。
好きなサイトの色とフォントを参考にした。

sweetpackを使ったので基本設定ファイルは書かなくてよかった。

postcss-forとpostcss-randomを初めて使ったが、混ぜると大変だった。。
forのスコープ内で変数宣言時にrandom使うとそこで確定されると思ったらコールされるたびに値が変わるのなんでだろう。。

@for $i from 1 to 10 {
  $delay: random(0, 30)s;

  .a {
    animation-delay: $delay;
  }

  .b {
    animation-delay: $delay;
  }
}

.a.bのanimation-deplayの値変わるんだよね。。
これってつまり、変数化する必要がないじゃん!!
なので共通で使いたかった部分を変数化したつもりが使えなくて共通を出さない実装に変えざる負えなかった😓

scssはたしか変わらない気がする。

https化を次はする。

おわり

簡単なアプリケーションでwebpackとbabelの設定をしなくて済むライブラリを作った

github.com

最初に

ターゲット

簡単なwebアプリケーション

モチベーション

同じ設定ファイルを書くことが多いのでそれを避けたい

ゴール

babelの設定とwebpackの設定を書かなくてもある程度のことはできるようになる。
ただ、複雑なアプリケーションだとwebpackは無限大なのでそこまでサポートする気はない。
webサイトとかを作るときに、プロダクションや開発の設定(minify, hashed name, server, etc…)を書くのがめんどくさいのでそれを解決する。


sweetpack

できること

webpackとbabelの設定ファイルを書かずにできることは主に以下の通りです。

  • reactを使用できる
  • flowを使用できる
  • css-modulesを使用できる
  • postcssを使用できる
  • htmlテンプレートエンジンが使える
  • 各環境の.envを読み込める
  • 開発時にwebpack-dev-serverが立ち上がり、HMRも有効化される
  • 開発時にreact-hot-loaderが使える
  • ビルド時にファイル名のハッシュを付く
  • ビルド時にコードの最適化が行われる(js, react)
  • ビルド時にファイルの分割ができる

プラグイン・設定

設定ファイル

.sweetpack.ymlで設定します。
以下の設定をサポートします。(値はデフォルト値)

entry: src/index.js
output: dist
js:
 flow: false
  react: false
css:
  modules: false
  postcss: false
html:
  filename: null
  template: null
dev:
  port: 8080
  dashboard: true
prod:
  extract: false

設定ファイルがない場合は、上記が適応されます。

共通プラグイン

  • html-webpack-plugin
    • 基本的にhtmlは自動生成(or テンプレートを指定)
  • dotenv-webpack
    • .envを読み込む
  • case-sensitive-paths-webpack-plugin
    • モジュールのファイル名の大文字、小文字を判断しエラーを出します(osxの標準ファイルシステムのHFS+は判断しないため)
  • file-loader
  • style-loader
  • css-loader
    • css-modulesにも対応(default: false)
  • postcss-loader(default: false)
    • これはローダを挟むだけなので、postcss.config.jsで自分の使いたいプラグイン(e.g. sass, cssnext, precss, etc..)を指定する
  • babel-preset-react(default: false)
    • onの時、react-hot-loaderも使用可能になる(devのみ)
  • babel-preset-flow(default: false)
    • onの時、flow-status-webpack-pluginも使用される
  • babel-preset-env
  • babel-preset-stage-1

開発時プラグイン

webpack-dev-serverが起動し、HMRもオンになります。
webpack-dashboardもデフォルトで使用されます。
また、reactを使用している場合はreact-hot-loader@nextも自動で入ります。

有効化されるプラグイン

  • webpack-dev-server
  • react-hot-loader(reactオプションがtrueの時のみ)
  • webpack-dashboard

github.com github.com

ビルド時プラグイン

NODE_ENV=productionを基本的には使用する前提で書かれています。
また、ビルド時にはindex.html以外のファイル名が自動でハッシュが付与されます。
このときに、reactが有効化されていてもreact-hot-loaderは無効化されます。
clean-webpack-pluginにより出力ディレクトリが削除されます。
最適化としてbabel-minify-webpack-plugin, OccurrenceOrderPlugin, AggressiveMergingPluginが走ります。
もしこのときにextract-text-webpack-pluginを有効化していれば、styles.[hash].cssという形でindex.htmlに挿入されます。

有効化されるプラグイン

  • clean-webpack-plugin
  • babel-minify-webpack-plugin
  • babel-preset-react-optimize(reactオプションがtrueの時のみ)
  • extract-text-webpack-plugin(extractオプションがtrueの時のみ)
  • webpack.optimize.OccurrenceOrderPlugin
  • webpack.optimize.AggressiveMergingPlugin

github.com github.com github.com


サンプル

package.json

{
  "scripts": {
    "start": "sweetpack watch",
    "build": "cross-env NODE_ENV=production sweetpack build"
  }
}

.sweetpack.yml

entry: ./lib/index.js
output: dist/bundle.js

ディレクトリ構成

 .
├── lib
│   └── index.js
└── package.json
1 directory, 2 files

npm startをしたらwebpack-dev-severwebpack-dashboardが起動します。
そして、npm run buildをしたら、/distにビルド済みの生成ファイルができます。

dist
├── bundle.2ea3ca43d449dd5fdc16.js
└── index.html
0 directories, 2 files

html, jsはファイル名にハッシュ値が振られ、最適化済みになります。

すべての設定ファイルを有効化したサンプルはこちらです。
sweetpack/samples/all at master · abouthiroppy/sweetpack · GitHub


さいごに

詳しくはREADME.mdとサンプルを見るとわかると思います。

まだまだやるべきことはあると思いますが、一旦ここである程度サポートできたのではないかなと思い書きました。
もちろんまだ足りないプロパティはあると思います。。。

もし興味あれば、是非使ってみてください;)

今の自分がどのように生成されたか考えた

なんとなく、タスクを捌きながら思ったことを殴り書きしている。
さて、今の自分がどのように形成されたかと考えたときに新卒の頃の周りの環境が大きいんじゃないかなって振り返って思った。

特に新卒の頃は、仕事というフィールドに触れて、特にインフラに詳しくなった気がする。
ドワンゴは知っての通りトラフィックが多いので、どうしても個人で運用して学ぶ知識ではカバーできない部分が多かった。
自分はフロントエンドエンジニアだったが、主にAWS周りのネットワーク設計やDB設計など色々と同期、先輩と討論したお陰である程度知識はあると思っている。

ドワンゴギークな人が多い。これは実際そうでエンジニアとしてのスキルが高い人が多い。(ただ生活リズムが終わってる人も多い)
だから面白いけど真剣な討論が多かった。(多方面の知識を持ってる人が多いので、様々な視野があり指摘がある)

この二年は、自分の専門領域でない部分の学びが多かったと書いていて思った。
なので広く浅く知っていって、興味があれば調べて深掘りしていくという学びができた気がする。(これがいわゆるI型ではなくT型?)

ところで、新卒の頃を思い出してみると、周りの環境が新卒の自分にとってはとても良かった。 自分で言うのもあれだが、新卒の時からある程度実力はあると思っていた。
入社当時、自分は研修スキップの早期配属で新卒が10名ぐらいいた部署で辞めるまで働いていた。

新卒の自分から見た同期は、優秀な人が多かった。 また特に分野が被ってなかったのでキラキラして見えた。Ruby, RoR, iOS, Android, etc..
著名なOSSのコミッターがいたり、iOSめっちゃ詳しい人いたり、RoR詳しい人いたりしていた。
基本聞けば回答が帰ってくる。

どのように自分が学生時代から今の自分へ変わったのか考えたが、一番の理由は多分危機感だったんだと思う。
しかも自分と同じ年齢だったから更に刺激的だったんだと思う。
そこから本格的にOSSとかを始めてコードを読む量を増やしたり、コミットしたり、I/Oを重視して学習していた気がする。
なんでもいいんだけど、コミットだってコード読まないといけないし、登壇だって学びがないと話せないし、ブログも同じ。
I/Oは本当に大切である。
もし新卒のときにこの環境じゃなかったら今の自分は正直ないと思っている。
なので本当に運が良かったなーって思う。

さて、次は中途の自分がそういう風に見られる立場だと思うとこんな自分でいいのか謎である。
まぁとくにそういうことを考えて仕事をしているわけではないが、自分みたいな人間がいたらそうなんだろうなって感じ

次は自分が知識を発信していく番なので、ワクワクしつつ、楽しく自分自身も学んでいきたい。
これからも日本ではNodeの活動をしていけたらと思います;)


何が結局言いたいかって言うと、新卒の同期は一生に一回しかないものだと思うし、仕事する上での環境はとても大切だと思う。
人それぞれだと思うけど、互いに磨き合える同期がいる環境が一番、実力が伸びる近道なのかもしれない。
普通に技術の話を永遠としているだけでも楽しいと思える人がいると良さそう。

という自分の経験上の話をまとめてみた。

なんかすっごい意識高いこと書いているただの老害になってしまったけど、文字で残しておきたかった。

おわり