メルカリのインターンシップに行ってきた
夏休み中の 1 ヶ月間,メルカリの Summer Internship 2018 に行ってきた.
メルカリがどのような会社で,どのような働き方をしているのか知ることができたし,働いてみて人が吸い込まれていく理由がよくわかったインターンシップだった.
動機
今年は学部の 4 年生だけど大学院に進学するし,そもそもインターンシップは学生のうちしか行けないので色々と見ておきたいという気持ちがあって 魔法のスプレッドシート を眺めたりしていた.
個人的には働き方を知るために短期よりも長期で,就業型のインターンシップに行きたいと思っていて,学部 4 年生でも行けて自分の条件に合うところを探していたらメルカリを見つけたので申し込んだ.
職種は自分は普段から携わる機会が多い Software Engineer (Frontend) を選択した.
選考
選考は,技術選考とオンライン面接があった.
技術選考は 2 時間で 5 問の問題を解くもので,普段から開発をしていたり,競技プログラミングの経験があれば難なく解くことができる程度の問題だと思う.
面接に関しては実際に行って受けることもできるけど,自分は福岡に住んでいるということもありオンラインで面接することにした.めっちゃ緊張してた.
内容
自分は Web 版のメルカリ,また社内ツールの改修などを行なった.実際にリリースまでできたのは嬉しい!
実際に働いてみてメルカリでは 3 つのバリューを大切にしているということがよくわかった.初日に,個人として目標を設定してその目標を達成することを念押しされたのもとても印象に残っている.メルカリでは,全ては成功のために,大胆に行動すること,プロフェッショナルであることを大切にしている.何かに迷ったり,行き詰まったらこのバリューを思い出してメルカリらしい選択をする.このバリューについては 「メルカリらしさ」を守り進化させる新体制が誕生! VP of People & Culture・唐澤俊輔インタビュー | mercan (メルカン) を見るとわかると思う.
最終発表は職種が異なるというのもあると思うけど,内容があまり理解できないものもあった.やはり強い人たちばかりだなと.その中で,心残りはあるけど自分もやれるだけのことはやれたのかなと思う.
また,このインターンシップの期間中に新卒の選考を受けることができ,大学院卒業後の 21 卒としての内定までいただくことができた.インターンシップ中に選考を受けれること,これも魅力のひとつだと思う.
感想
こういうと少しうさんくさいけど,社員の方はメルカリの成功のために Go Bold で All for One だし,技術に対しても Be Professional だし,情報も社員に対して全てオープンだし,働きやすい環境がこれでもかと整えられていて控えめに言って最高だった.
また色々と話を聞いて,サービスを運用していく過程で利用者だけではなく経営者や開発者なども含め,そのサービスに関わる全ての人たちが幸せであるためにどう行動していくべきかを考える良い機会になったと思う.
まだ自分がメルカリでやれることはあると思ってるし,やりたいことも沢山ある.確実に成長できたし色々な考え方にも触れることができた良いインターンシップだった.
オフィスから東京タワーが見える✨
Mint を試してみた
見かけたので試してみた.メモ.
Mint とは
- 再利用可能なコンポーネント
- スタイリング
- ルーティング
- グローバル,ローカルの状態のハンドリング
- 失敗する可能性がある同期,非同期処理
という特徴があって
- 開発者の幸せ
- 高速なコンパイル
- 可読性
に焦点を当てている SPA のための言語みたい.
インストールする
ここの INSTALL BINARIES を試したけれど
$ ./mint-0.2.0-osx dyld: Library not loaded: /usr/local/opt/bdw-gc/lib/libgc.1.dylib Referenced from: /Users/calmery/Projects/LearningMint/./mint Reason: image not found zsh: abort ./mint
となったので INSTALL FROM SOURCE を参考にしつつビルドした.
$ mint Mint - Help ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Usage: mint [flags...] [arg...] Mint Flags: --help # Displays help for the current command. Subcommands: build # Builds the project for production docs # Starts the documentation server format # Formats source files init # Initializes a new project install # Installs dependencies loc # Counts Lines of Code start # Starts the development server test # Runs the tests ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ All done in 49μs!
試してみる
ガイドを見ながら進める.
新しいアプリケーションを作成する
$ mint init my-app Mint - Initializing a new project ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ⚙ Creating directory structure... ⚙ Writing initial files... ⚙ Constructing dependency tree... ✔ Cloned mint-core(https://github.com/mint-lang/mint-core) ⚙ Resolving dependency tree... ◈ mint-core ➔ 0.2.0 ⚙ Copying packages... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ All done in 1.522s!
こんな感じになった.
$ tree -a -L 3 . ├── .gitignore ├── .mint │ └── packages │ └── mint-core ├── mint.json ├── source │ └── Main.mint └── tests └── Main.mint
動かしてみる
$ mint start Mint - Running the development server ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ⚙ Ensuring dependencies... 126μs ⚙ Compiling... 67.456ms ⚙ Development server started on http://127.0.0.1:3000/
テストする
$ mint test Mint - Running Tests ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ⚙ Ensuring dependencies... 174μs ⚙ Compiling tests... 73.616ms ⚙ Starting test server... ⚙ Starting browser... ⚙ Test server started on http://127.0.0.1:3001/ ⚙ Running tests: . ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1 tests ➔ 1 passed ➔ 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ All done in 461.161ms!
ビルドする
$ mint build Mint - Building for production ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ⚙ Ensuring dependencies... 7μs ⚙ Clearing the "dist" directory... 100μs ⚙ Compiling your appliction: ➔ Parsing 40 source files... 55.173ms ➔ Type checking: 4.486ms ➔ Compiling: 2.568ms ⚙ Writing index.html... 238μs ⚙ Generating icons... 30.551ms ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ All done in 96.88ms!
$ tree dist dist ├── icon-120x120.png ├── icon-128x128.png ├── icon-144x144.png ├── icon-152x152.png ├── icon-167x167.png ├── icon-16x16.png ├── icon-180x180.png ├── icon-196x196.png ├── icon-256x256.png ├── icon-32x32.png ├── icon-57x57.png ├── icon-76x76.png ├── icon-96x96.png ├── index.html └── index.js 0 directories, 15 files
ドキュメントを見る
良さそう.インストールしたパッケージとかのドキュメントを見ることができる.
$ mint docs Mint - Running the documentation server ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ⚙ Documentation server started on http://127.0.0.1:3002/
構文など
Atom にシンタックスハイライトのプラグインがないっぽい.とてもつらい.
where
fun greet (name : String) : String { message + name } where { message = "Hello, " }
record
Elm っぽい.
record User { email : String, name : String, id : Number } user = { email = "john.doe@gmail.com", name = "John Doe", id = 0 } updatedUser = { user | name = "Stuart" }
case
case (condition) { match1 => value1 match2 => value2 match3 => value3 => defaultValue }
try
Result を返す.catch は複数持てるみたい.詳しくは try - Mint を見ると良さそう.
do
try とほとんど同じ.返り値は Promise 型か Result 型になる.ちなみに try 自体は Result 型になるのに対して do 自体は Void 型になるみたい.
store
状態を管理する Store を作成する.Connecting Stores - Mint を見るとわかる.
provider
非同期のイベントを扱うためのものみたい.
use Provider.Tick { ticks = () => { next { counter = state.counter + 1 } }
mint-core の中を見ると AnimationFrame と Mouse,Scroll,Tick があった.
コンポーネント内で状態を管理する
コンポーネントの内部に状態を持つことができる.Internal State - Mint を見るとわかる.
気になったこと
使ってみて気になったところをまとめる.
- Store とは別にコンポーネントの内部で状態の管理ができるのはどうなの
- 吐き出されたコードを見ると React を使っているっぽい
- mint コマンドから他のパッケージを追加することはできないっぽい
- コンポーネント内に直接 CSS を記述していくと量が増えたとき読みにくそう(スコープは付けたいけど分けたい.そもそもそこまで大きなコンポーネントはできないはずなのであまり問題ではない?)
- mint.json の source-directories で指定したディレクトリ内のコンポーネントとか Store とかはインポートせずに使えるっぽくて気持ち悪い
- こことかがっつり Inline Javascript でとても辛そう
良さげな開発環境を作る
最近やっていることをまとめる.忘れないようにメモ.適宜更新したい.
何をしているの
身内で使用するための Twitter のアカウントに紐づいた Web アプリケーションを開発している.
ここではサーバ側とクライアント側で完全にコードを分けている.サーバーサイドレンダリングとかはしてない.サーバ側は REST API っぽく Node.js,Express を使用して開発して,クライアント側は React を使用して開発している.認証周りは Firebase の Twitter 認証,認証後はサーバ側で API キーを発行してヘッダーに X-Api-Key を追加してやり取りを行う.データ自体は Postgres に,Node.js の Sequelize を使って良しなに管理している.
ちなみにサーバ側は Heroku を使用して,クライアント側は GitHub Pages を使用している.
色々
使っているツールとかをまとめる.アルバイト先で教えて頂いたものが多い.
見た目を整える
クライアント側の見た目は material-ui を使用している(どこかに使用できるアイコンまとめないかな?)
認証する
Firebase を使用している.クライアント側で Twitter にログインして発行されるトークンをサーバ側に送ってサーバ側は firebase-admin - npm を使用してそのトークンを認証する.認証できたら uid が取得できるのでそれをデータベースに保存するという感じ.サーバ側は認証後にクライアント側に API キーを返して,クライアント側はリクエストを行うときにこの API キーをヘッダーの X-Api-Key に追加するようにしている.
データベースは Heroku 上でも使える Postgres を使用している.Sequelize を TypeScript から使える sequelize-typescript - npm が良さげだった.
自動デプロイする
サーバ側もクライアント側も GitHub のリポジトリに変更を加えられたときに自動でデプロイするようにしている.
クライアント側
CircleCI を使用してリポジトリに変更が加えられた際にテストとビルドを実行する.master に限ってはビルドの後にデプロイまで実行される.GitHub - facebook/create-react-app: Create React apps with no build configuration. を使用しているのでテストとビルドに関しては react-scripts をそのまま利用する.デプロイに関しては gh-pages というブランチにビルドで作成された build というフォルダの内容を GitHub 上の gh-pages というブランチに追加すれば良いので gh-pages - npm を使用して良しなにやっている.また gh-pages ブランチでは CircleCI を実行したくないのでコミットのコメントに [skip ci] を加えている.Skipping and Cancelling Builds - CircleCI を見ればわかる.
package.json の内容はこんな感じ.
{ "scripts": { "test": "react-scripts test --env=jsdom", "build": "react-scripts build", "deploy": "gh-pages -d build -m \"Updates\nCircleCI [skip ci]\"" } }
長くなるので jobs 部分は省略するけど CircleCI で使用する config.yml はこんな感じ.
... workflows: version: 2 test-build-and-deploy: jobs: - test: filters: branches: ignore: gh-pages - build: requires: - test - deploy: requires: - build filters: branches: only: master
使用している外部サービスが CircleCI だけなので簡単で作りやすい.
サーバ側
Node.js を使用して TypeScript,Express で開発しており,テストには Jest を使用している.基本的にはクライアント側とほとんど同じだが,こちらは Heroku にデプロイする必要があるので CircleCI で行うのはテストとビルドまでで,デプロイは Heroku の Automatic deploys を使用して行なっている.Automatic deploys の Wait for CI to pass before deploy にチェックを入れておくと CircleCI の処理が終わるまで待ってくれるので良い.
package.json はこんな感じ.Heroku の Automatic deploys は GitHub 上のコードを使用してデプロイを行おうとするので package.json の scripts に heroku-postbuild を追加してそこでビルドを行うようにする.
{ "scripts": { "test": "jest --forceExit --coverage --verbose", "build": "rimraf dist/ && tsc", "heroku-postbuild": "npm run build" } }
サーバ側はステージングとプロダクション環境で分けており,どちらも Automatic deploys で同時にデプロイされる.これステージングがもはやステージングと言えるのかが怪しい.ただ使用する Postgres のデータベースは分けているので壊せる環境としてある感じ.
レビューしやすくする
クライアント側は GitHub 上でプルリクエストを出した際に Heroku の Review Apps で自動で動作する環境を作ってくれる.Heroku Review Apps now Generally Available | Heroku を見るとわかりそう.コードのレビューと動作のレビューを同時に行えるので良い.ちなみにここで作った環境からはサーバのステージングの環境を使用するようになっている.ステージング云々というよりは,このためにサーバの環境を分ける必要があった.
ちなみにプルリクエストを作成して時間経過,またはプルリクエストのクローズでレビューのための環境は自動で壊される.Personal の場合はクレジットカードの登録で Free プランでも 1000 時間稼働させることができるし,小規模であればこれで全然良さそう.
まとめ
めっちゃ便利になったし感動してる.