1日一つ強くなる戦略としての UCDDD (Udemy Course Development Driven Development)

私は「1日一つ強くなる」ということをスローガンとして掲げ、活動しています。

1日一つ強くなれば、昨日の自分よりも今日の自分の方が強いので、結果今日が最強です。そしてこれが死ぬまで続けば、死ぬ瞬間が、自分の人生において最強な訳です。最強になってどうするんだ…という問題は置いておくとして…非常にいい考え方だと思います。

これは私の尊敬する梅原大吾さん (プロゲーマーで特に格闘ゲームのストリートファイターとして有名な方です) の提言する最強になるための理論で、梅原さんの新書のタイトルにもなっています。

さて、1日一つ強くなれば最強になれるのはわかったので、次にどうやって強くなるか、ということについて考えてみると、一般的に以下のような方法が有効だと言われています。

  • アウトプット
  • 自分でテストを作って解いてみる
  • 仕事でその技術を使う
  • 自分でアプリケーションを作る
  • ブログを書く
  • 教える

この中でも特に今回は教えるということの有効さについて話をしたいと思います。

この四半期に教える機会を2ついただいたことで、圧倒的に成長をすることができました。

まず、2月から「もくもく temple」で React ハンズを講師を担当させていただく機会をもらい、合計二回、React の超基礎から初めて ToDo App を作るところまで講義させていただきました。まずこの機会に大きく成長ができました。

ハンズオン当日までに、全ての内容を動画にして Youtube にアップして、テキストも作って、それから CodeSandbox というブラウザ上で動く IDE に過程も含めて全てのコードを書いて公開したのですが、動画を取るためには、かなり完全に理解していて、さらさらとコードを書けないとうまくいかないんですね。

うろ覚えだと、説明しようとしてもつまづくし、コードを書いていてもあやふやなところがあるとエラーが出て止まってしまって、動画は取り直しです。講義資料として使えるくらい、スラスラと説明して、コードを書いて、ということを実現しようとすると、完全に理解する必要が出てきます。

それから、動画を取ると、自分が何をわかっていないのか、明確になります。当然ですけど説明ができないし、コードがうまく書けないからです。

つまり動画を取ることで次のような成長が発生します。

  • 自分が理解していないことが明確になる
  • 明確になったところを学習して、説明できるまで身につく

つまり、動画を撮影して指導のための資料を作っているように見えて、結果的に自分に教えていることになります。

これが指導用の動画を取ることによって、自分が圧倒的成長できる原理です。

教えることが自分に効くということは、みなさんにもご理解していただきやすいと思うのですが、実はコードを何回も書く、というのもかなり効いてきます。

動画を撮ってみてわかったのですが、こう書けば動くだろうという自分の予想が、かなり外れて、つまり本当はわかっていないのにわかったつもりになっていたコードがたくさんあったんですね。コードを取り直しの際になんどもなんども書くことで完全に身について、その結果、コードの全体像が完全に頭に入ってくるので、見通しが驚くほどクリアーになります。途中で間違えると取り直しになるので、とにかく一発で動かせるまで理解できます。

今書いている部分が完全に理解できると、新しく追加する要素についても、以前よりも理解ができます。曖昧なところがないので、追加される要素だけ学習すればいいからです。

こうして、動画を取るたびに、その領域をマスターできるので、コースを進めれば、どんどん成長できます。

さて、本題の UDDDD ですが、React ハンズオンの1回目と2回目の間だったと思うのですが、Udemy の担当者から Redux のコースをやらないかという打診をいただきました。Redux のドキュメントを一部日本語訳して公開しているので、それを検索で見つけて声をかけていただいたようです。

正直言って、自分のエンジニアとしてのレベルは、お金をとって人に指導するレベルではありません。コースを完成する前には、一応書いて動かせはできるけど、人に流暢に説明することはできませんでした。しかし、受けさせていただくことにしました。

その理由は、日本語 React のコースが Udemy には一個しかなく、それは既にエンジニアとして一定レベルにある人向けのコースだったので、そのコースでは説明されないもっと基礎的な JavaScript の知識から説明して底上げをするコースを作ることで、自分が提供できる価値はあるだろうと思ったからです。

React と jQuery の間にあるのは、React の理解の有無というよりは、JavaScript の理解、特に Babel 等を使ってトランスコンパイルする必要がある「新しい JavaScript 環境」による開発だと思っていました。それは資料の前文でも書きました。つまり Node.js が開発の中心にあって、新しい JS をブラウザで動く JS にトランスコンパイルしながら進める、という開発スタイルに参入している人と、そうではない人の差が、React 学習においては大きな違いになると思ったのです。

これは自分が React を学習していて難しかった部分でもありますし、またハンズオンを通して感じたことでもありました。多分多くの人は Webpack の設定でかなりつまづいていて、React のコンポーネントを書くところまでいっていないと思います。

だって、node を使わない開発環境の人は、まず node を入れて、しかもバージョン管理するために nvm を入れて、おっとパスがあってないからパスも追加して、うーん動かない…このあたりでまず第一につまづきポイントがきます。

次は、Webpack で JS module をバンドルして、さらにその際に Babel でトランスコンパイルもする?バンドルって何?なぜコンパイルする必要があるんだ?

そこを乗り越えても、

const List = ({data}) =>  data.map(o=><li>data.name</li>);

みたことのない表記が多すぎる!

つまづきポイントがたくさんあります。ここを掬いあげれる動画はまだないなと思ったので、自分がそこを埋めることはできるのではないかなと思いました。

そこから一ヶ月ちょっとですが、ずーっと資料を作ってはボソボソ喋って動画を取り、わからないところがあれば調べて、ということを繰り返した結果、Udemy の動画を完成させることができました。

今は審査待ちで、通って欲しいのですが、仮に通らなかったとしても、圧倒的成長をできた一ヶ月でしたので、ラッキーという感じです。

特に非同期処理、Promise, Async/Await, Redux-thunk あたりは動かせるけどあやふやだったので、そこを完全に理解できたのが大きいです。自信を持って JS アプリケーションの開発をできるようになりました。

ということで、指導動画を取る、特に今回は Udemy のコースを作ることによって成長するという戦略は、最強になる上で非常に有効だということがわかりました。

なので、今後もですね、Youtube に動画を上げていって、ある程度まとまったら Udemy にコースとして公開するというフローを続けていきたいと思います。具体的には Node.js のコースか、もしくは今回の React コースでは取り上げることが間に合わなかった「react-router, Material UI, React-bootstrap, transition, 開発者ツールの使い方、ローカル環境の作り方、エディターとの連携等々…」

Node.js はサーバーでもローカルでも動く最強のツールで、ウェブエンジニアの私としては Python よりもしたしみがあるので、もっと使いこなして、なんでも node にやらせて楽をしたいと思ってます。自分の開発で使うちょっとしたツールなら自分でかける!となったら面倒な仕事も少し楽しくなりますよね。

ということで、Udemy Course を開発することで、圧倒的成長を日々するという戦略でした!

 

 

 

 

ウェブ制作のための npm script と js バンドラーに Parcel を 用いたシンプルな開発環境

完成したもの

https://github.com/superyusuke/webDevStarterKit

背景

React の開発環境には create-react-app をいつも使っていて、全く不便がないし、ちょっとした変更で必要なことはすべてできていた。さらに自分の React 大好きの勢いに乗じて、静的なウェブサイトさえも、React のコンポーネントベースで作成できる Gatsby を用いて作ってしまいたいと検討していた。

しかし React ベースで静的なサイトを作る問題は、他の人が修正しずらい、ということである。React ベースで作られるサイトは、基本的に HTML ではなく、JavaScript で書いていくことになるので、一般的なウェブサイト制作メインのエンジニアのスキルから少し外れることになる。HTML, CSS, JavaScript からあまり外れない、ということが共同作業においては有効になる。

そこで改めてウェブサイト制作のための開発環境作りをする必要がある。以下の要件を満たしたい。

  • ES2015+ で書ける。
  • Sass をトランスコンパイルする。
  • WebPack ではなく Parcel を使うことで、なるべく設定を減らす。
  • WebPack の image バンドルはしない。
  • さしあたってテンプレートエンジンは使わなくてもいい。

ウェブパックを使って画像や CSS をバンドルする方が速度や軽さの点で有利なのは間違いないが、そこまでやるのであれば Gatsby で SPA + 静的ファイルのほうが断然早い。ので、パフォーマンスの最適化は、別の手法で達成したいと思う。

あくまで第三者が後から見た時に修正しやすい、ということを重視する。

ES2015+ のトランスコンパイル+バンドル

ES2015+ を ES5 にコンパイルするためには Babel 周りが必要。さらに js-module をバンドルする(import/exportを使って行く) ためには Browserify を以前は使っていた。

以前は具体的には、browserify でバンドルするわけだが、その際に ES2015+ を ES5 にコンパイルするために、babelify を用いていた。さらにファイル変更を監視するために watchify も使っていた。

browserify, babelify, watchify, さらに本体の babel と非常に設定が多い。

なのでこれを Parcel に置き換えたい。ただし Parcel は JS だけを担当させ、Sass や画像の処理は担当させない。というのも、Sass のソースマップを出力できないようだったので これはさすがに不便だと思ったからだ。JS だけ担当させるなら早いと思う。

まず package.json を作って、

npm init -y

以下をインストール

npm i -D parcel-bundler

以下のようなファイル構造

scripts に以下を追加

  1. parcel watch は parcel 独自の開発サーバーを立てずにウォッチ
  2. 出力先、出力ファイル名を設定
"js:watch": "npx parcel watch ./src/js/entry.js --out-dir ./src/assets --out-file app.js"

さらに babel のプリセットを設定していく。

npm i -D babel-preset-env

その後 .babelrc を作成し以下のように記述

{
  "presets": ["env"]
}

オブジェクトスプレッドに対応していないので、これも入れる。

npm i -D babel-plugin-transform-object-rest-spread

.babelrc を以下のように追加

{
  "presets": ["env"],
  "plugins": ["transform-object-rest-spread"]
}

これで開発は OK。完パケ用はあとで作る。

sass をコンパイルする

これは簡単。

npm i -D node-sass

スクリプトに以下を追加

"css:watch": "node-sass --watch ./src/sass/index.sass ./src/assets/screen.css --source-map true --include-path ./src/sass"

ソースマップ付きで、./src/assets/screen.cssに出力

開発用サーバーを browser-sync で立てる

npm i -D browser-sync

"server:watch": "browser-sync start --server ./src/assets --files ./src/assets"

–server でルートを設定

–files でリロードの監視先を設定

パラレルシリアルでスクリプトを動かす

npm は && & でパラレル/シリアルにnpm-script を走らせることができるが、これはシェルに依存するとのこと。mac / win / Linux 等どれでも動かすためには npm-run-all を使う。

"start:dev": "npm run watch",
"watch": "npm-run-all -p js:watch css:watch server:watch",
"js:watch": "npx parcel watch ./src/js/entry.js --out-dir ./src/assets --out-file app.js",
"css:watch": "node-sass --watch ./src/sass/index.sass ./src/assets/screen.css --source-map true --include-path ./src/sass",
"server:watch": "browser-sync start --server ./src/assets --files ./src/assets"

全体としては以下のようにした。

build では完全に異なるディレクトリにソースを出力した。ソースマップを取り除き、圧縮している。

"scripts": {
  "start:dev": "npm run watch",
  "watch": "npm-run-all -p watch:js watch:css watch:server",
  "watch:js": "npx parcel watch ./src/js/entry.js --out-dir ./src/assets --out-file app.js",
  "watch:css": "node-sass --watch ./src/sass/index.sass ./src/assets/screen.css --source-map true --include-path ./src/sass",
  "autoprefixer:assets": "postcss ./src/assets/screen.css --use autoprefixer --replace",
  "watch:server": "browser-sync start --server ./src/assets --files ./src/assets",
  "build": "npm-run-all -s build:clean build:copy -p build:js build:css",
  "build:js": "npx parcel build ./src/js/entry.js --out-dir ./build --out-file app.js",
  "build:css": "npm-run-all -s build:sass build:autoprefixer",
  "build:sass": "node-sass ./src/sass/index.sass ./build/screen.css --include-path ./src/sass --output-style compressed",
  "build:autoprefixer": "postcss ./build/screen.css --use autoprefixer --replace --no-map",
  "build:clean": "rimraf ./build",
  "build:copy": "cpx \"./src/assets/**/!(*.js|*.css|*.map)\" ./build"
}

圧倒的成長の記録2018

  • 1/1 Redux-saga, Generator, Async/Await, Promise, high-order-component
  • 1/2 Redux, React をリアルタイムに書く練習
  • 1/3 Redux をリアルタイムに書く練習
  • 1/4
  • 1/5
  • 1/6
  • 1/7
  • 1/8
  • 1/9 HOF による イベントハンドリングコンポーネントの実装
  • 1/10 async のエラー処理
  • 1/11 create.JS, 三項演算子/&&の使い分け
  • 1/12 e2e テストを WebDriverIO, power-assert で
  • 1/13 React 勉強会打ち合わせ
  • 1/14 TRPG
  • 1/15 初めてのJavaScript リテラル、クロージャ
  • 1/16 テストの概要の記事を翻訳
  • 1/17 テスト用のフレームワークの学習(mocha?karma?jest?)
  • 1/18 createjs import では使えない、codepen で直接読み込みで使う
  • 1/19 Redux の動画作成準備
  • 1/20 React ドキュメント翻訳開始、Node.js の翻訳開始、スキル学習計画の見直し,ポートフォリオ用 React アプリケーションの開発開始
  • 1/21 redux の配列操作、アプリケーション進展
  • 1/22 mapstatetopropsの使い熟し度アップ
  • 1/23 CSS keyFrameAnimation と Style コンポーンネントの組み合わせ、条件分岐
  • 1/24 自力で解決策を見つける力
  • 1/25 自力で解決策を見つける力
  • 1/26 コードを読む力の向上
  • 1/27 デバグ力の向上
  • 1/28 React の input のun/controlled がスイッチしてしまうバグを潰す。根性
  • 1/29 zeit, ソースを読む根性、now
  • 2/3 react hands on  の練習で、プレゼン向けの画面比率の練習
  • 2/4 react hands on 当日
  • 2/5 Redux と connect した HOC の作成

High Order Component

https://codesandbox.io/embed/400jy0j15x?module=%2Fsrc%2FHOC.js

High order component は コンポーネントを引数として受け取って、コンポーネントを返すファンクション。

参考記事

こちらの方が簡単

https://spin.atomicobject.com/2017/03/02/higher-order-components-in-react/

より高度な内容

https://reactjs.org/docs/higher-order-components.html

以下のコードでは、HOC が受け取ったコンポーネントに対して、react-redux の connect で state と dispatch を connect した上で、クラスコンポーネントを返している。渡されたコンポーネントに、少しだけ何かを足して返す、というのがポイント。

HOC によって、データを与える機能と、受け取ったデータを元にレンダリングする機能を分けることができる。

英文記事まとめ

How To Successfully Teach Yourself How To Code 済1/1 5点

学習の記録をつけることで成長を実感すること。動画コンテンツは流し見するだけでは理解できないので、みながら自分のプロジェクトの作業をし、わからないことはしっかり調べる。進捗が遅いように見えても、それが一番確実。すごい人と比べると自分は無力のように思うが、そんなことはない。仕事以外の自分のプロジェクトを持つこと。

Developing NPM Packages 途中1/1 5点

NPM パッケージを自分で開発するために必要な、GitHub の使い方、コンパイル、パブリッシュの手順が詳しい。より一層の JS の理解のために NPM 開発が必要だ。

HOC ハイオーダーコンポーネント系。

 

redux-saga 使い方 まとめ

https://redux-saga.js.org/

redux-saga は、React において state の管理を redux にさせている場合に、非同期処理を担当する middleware。同様のアプリケーションに redux-thunk がある。

redux-thunk から redux-saga に乗り換え

https://hackernoon.com/moving-form-redux-thunk-to-redux-saga-5c19d0011ca0

まずは Generator がコア

The Basics Of ES6 Generators

View story at Medium.com

function *generatorFunction (){} でgenerator を作る。

const it = generatorFunction () で it という イテレーターオブジェクトを作る。

it.next() で進める。 it.next().val で yield の値が取れる。

function *generatorFunction (){
yield 1;
yield 2;
yield 3;
}

console.log(it.next().value) //1
console.log(it.next().value) //2
console.log(it.next().value) //3

yield したものが return される。

for ( const value of generatorFunction ()){}

でとれる。

Generator, yield と async/await の類似性

async/await は、await によって promise オブジェクトが返されるまで待つ。これによって非同期処理を、書き方としては同期処理のように上から下へと書くことができる。

Generator における yield は、await と同じように、next() を待つ。これによって redux-saga は、処理を止めたり進めたりしている。

シンタックス

https://redux-saga.js.org/docs/introduction/BeginnerTutorial.html

saga.js を用意する。

import { delay } from 'redux-saga' // 時間差を作り出す
import { put, takeEvery, all } from 'redux-saga/effects'
// put はアクションのディスパッチを予約
// takeEvery は action を待ち受けるために使う
// all は saga をまとめて出力するために使う

// generator で定義。非同期処理を実行するもの
function* incrementAsync() {
  yield delay(1000) //saga のdelay を使う。終わるまでここで待つ
  yield put({ type: 'INCREMENT' }) // delayが終わればこの行に来る
  // action をディスパッチする
}


// アクションを待ち受ける
function* watchIncrementAsync() {
  yield takeEvery('INCREMENT_ASYNC', incrementAsync) 
  //受けたら関数を実行
}

// まとめておく
// notice how we now only export the rootSaga
// single entry point to start all Sagas at once
export default function* rootSaga() {
  yield all([
    helloSaga(),
    watchIncrementAsync()
  ])
}

ミドルウェアの適応

import "babel-polyfill" // generator とかに必要っぽい

import React from 'react'
import ReactDOM from 'react-dom'
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'

import rootSaga from './sagas' // saga関係がまとまっているもの

import reducer from './reducers'

const sagaMiddleware = createSagaMiddleware() //ミドルウェアを作る

//redux にミドルウェアを噛ませる
const store = createStore(
  reducer,
  applyMiddleware(sagaMiddleware)
)

//サーガを起動
sagaMiddleware.run(rootSaga)

関数の実行と引数の渡し方

call を使って function を実行する。これはイテレーターか、もしくは promise を返す function を使う。例えば fetch など。promise が返されるまで、yield は待つ。

import { call, put } from 'redux-saga/effects' 
// call が非同期処理をする関数を呼び出すために必要

export function* fetchData(action) {
   try {
      // Api.fetchUser ha promise を返すものとする
      // call(function,arg) ここでは action を引数として渡した
      // promise の返り値が const data に入る
      const data = yield call(Api.fetchUser, action.payload.url)
      // アクションをディスパッチ
      yield put({type: "FETCH_SUCCEEDED", data})
   } catch (error) {
      yield put({type: "FETCH_FAILED", error})
   }
}

sandbox

sksk

 

async/await promise の使い方の記事まとめ

https://codesandbox.io/embed/oopvk114p9

最初に読んだ

https://medium.freecodecamp.org/oh-yes-async-await-f54e5a079fc1

次に読んだ

https://tutorialzine.com/2017/07/javascript-async-await-explained

図示

http://nikgrozev.com/2017/10/01/async-await/

const async1 = async () => {return await returnPromiseFunction()}

const async2 = async () => {console.log(await async1())}

async と arrow function の前につける。そのファンクションの中で await を使える。await は promise オブジェクトが返されるまで、待つ。return value は return Promise.resolve(value) と同じ。つまり promise オブジェクトを返している。

25日目 シリコンバレー戦略4 編「シリコンバレーに本社がある企業の日本での求人を読む」 2017年圧倒的成長振り返り一人アドベントカレンダー

この記事は ” 2017年圧倒的成長振り返り一人アドベントカレンダー ” の 24日目です。

https://adventar.org/calendars/2747

アドベントカレンダーに乗り遅れ、参加できそうなものがなかったので行われる、孤独な一人アドベントカレンダー。最終日25日目の今日は、シリコンバレーの会社の応募項目を読む 編です。

惜しくも25日には間に合わず、仕事納めの翌日30日に書いております。25日にかけたはず。甘え。こういうちょっとしたディレイが最終的にシリコンバレーを遠くしていくので、きっちりやっていきたい。まずは、25日分のアドベントカレンダーの完成です!

Google と Facebook の求人を読む

まずは Google

JavaScript で検索するとこれが

とりあえずおもむろにボタンを押してみると、基本情報に加えて、resume つまり経歴書、もっている技術を示すための書面を添付すれば OK のようだ。なので、英文 Resume を書く能力がさしあたって必要という気がしました。

ということで英文レジュメの書き方を早速買ってみた。

英文履歴書の書き方Ver.3.0
有元 美津世
固定リンク: http://amzn.asia/7F4LyEd

書くぞい!

これでアドベントカレンダーは終わり!よくやった俺!

この記事は ” 2017年圧倒的成長振り返り一人アドベントカレンダー ” の 24日目です。

https://adventar.org/calendars/2747

アドベントカレンダーに乗り遅れ、参加できそうなものがなかったので行われる、孤独な一人アドベントカレンダー。最終日25日目の今日は、シリコンバレーの会社の応募項目を読む 編です。

 

24日目 シリコンバレー戦略3 編「シリコンバレーの会社をリストアップ」 2017年圧倒的成長振り返り一人アドベントカレンダー

この記事は ” 2017年圧倒的成長振り返り一人アドベントカレンダー ” の 24日目です。

https://adventar.org/calendars/2747

アドベントカレンダーに乗り遅れ、参加できそうなものがなかったので行われる、孤独な一人アドベントカレンダー。24日目の今日は、シリコンバレーの会社をリストアップ 編です。

そもそもどんな会社があるのか

そもそもどんな会社があるのか知らないことには戦略がぶれます。調べます。

わかったこと

調べればなんでもわかる。調べる前と後では、できそうな雰囲気がかなり違う。調べれば調べるほど近づいている実感がある。今後もどんどん調べる。

日本支社がある企業に入るという素直な戦略もあり。

  • Google(グーグル)日本支社がある。求人もあった。
  • Facebook(フェイスブック)まさにシリコンバレー。React。東京の募集あった。
  • ネットアップ ストレージ、データ管理。日本支社あり。
  • アジレント・テクノロジー  化学分析機器や電気・電子計測機器の開発・製造・販売・サポートを行う、業界最大手の企業。ということで、メインはウェブではないけれど、なんらかのウェブエンジニアの仕事はありそうだ。八王子に日本支社がある。日本支社経由という戦略もありうる。

地味だけど仕事が多そうな会社は潜りこめそう。

普通こういう会社はエンジニアはあまり好まないのではないか。地味なので。日本で地味な仕事をやるならシリコンバレーでやったほうが当然面白いと思う。

明日は

この二社が日本でも募集しており、しかも詳細な資料があるので、これを読んでみようと思います!

この記事は ” 2017年圧倒的成長振り返り一人アドベントカレンダー ” の 24日目です。

https://adventar.org/calendars/2747

アドベントカレンダーに乗り遅れ、参加できそうなものがなかったので行われる、孤独な一人アドベントカレンダー。24日目の今日は、シリコンバレーの会社をリストアップ 編です。

23日目 シリコンバレー戦略2 編「苦手な方からやってみる」 2017年圧倒的成長振り返り一人アドベントカレンダー

この記事は ” 2017年圧倒的成長振り返り一人アドベントカレンダー ” の 23日目です。

https://adventar.org/calendars/2747

アドベントカレンダーに乗り遅れ、参加できそうなものがなかったので行われる、孤独な一人アドベントカレンダー。23日目の今日は、シリコンバレー戦略2 編です。

具体的な行動に落とし込む

19日のシリコンバレー戦略編1の記事で 今思いつく戦略を書き出しました。これをさらに具体的にやっていきたいと思います。

  • 応募先の会社のリストアップ
  • 申し込みの履歴書的なものの英文での作成
  • 英語での面接対策
  • 行ってから生活に不便しない英語力を身につける(オンライン英会話)
  • エンジニアとしてのスキルのアップ(ただこれはどこまでも無限にあるので必須ではないかも)
  • 海外エンジニアのコミュニティへの所属
  • 海外で働いているエンジニアにコンタクト

苦手そうな方からやる

この中で一番自分にとって難しそうだなと感じるものはどれか。順番にしてみるとこうなります。

  1. 応募先のリストアップ
  2. 英文での申し込みレジュメ作成
  3. 海外で働いているエンジニアへのコンタクト

他のものはコツコツ一人でできるので、いけそうです。この三つはいろんな人に協力してもらわないとできなさそうです。のでここを重点課題としたいと思います。

苦手なことは、後回しにされます。でも苦手というのは実は雰囲気だけであって、やりさえすれば、できるんじゃないかなと思います。

ということでリストアップしたので、これを次の記事で順番にやっていきます!

この記事は ” 2017年圧倒的成長振り返り一人アドベントカレンダー ” の 23日目です。

https://adventar.org/calendars/2747

アドベントカレンダーに乗り遅れ、参加できそうなものがなかったので行われる、孤独な一人アドベントカレンダー。23日目の今日は、シリコンバレー戦略2 編です。