Calmery.me

みっかぼうずにならないようがんばる

メルカリのインターンシップに行ってきた

夏休み中の 1 ヶ月間,メルカリの Summer Internship 2018 に行ってきた.

f:id:calmery:20180922133358j:plain

メルカリがどのような会社で,どのような働き方をしているのか知ることができたし,働いてみて人が吸い込まれていく理由がよくわかったインターンシップだった.

動機

今年は学部の 4 年生だけど院進学するし,そもそもインターンシップは学生のうちしか行けないので色々と見ておきたいという気持ちがあって 魔法のスプレッドシート を眺めたりしていた.

個人的には働き方を知るために短期よりも長期で,就業型のインターンシップに行きたいと思っていて,学部 4 年生でも行けて条件に合うところを探していたらメルカリを見つけたので申し込んだ.

職種は自分は普段から携わる機会が多い Software Engineer (Frontend) を選択した.

選考

選考では,技術選考とオンライン面接があった.

技術選考は 2 時間で 5 問の問題を解くもので,普段から開発をしていたり,競技プログラミングの経験があれば難なく解くことができる程度の問題だと思う.

面接に関しては実際に行って受けることもできるけど,自分は福岡に住んでいるということもありオンラインでの面接となった.

内容

自分は Web 版のメルカリ,また社内ツールの改修などを行なった.実際にリリースまでできたのは嬉しい!

実際に働いてみてメルカリでは 3 つのバリューを大切にしているということがよくわかった.初日に,個人として目標を設定してその目標を達成することを念押しされたのもとても印象に残っている.メルカリでは,全ては成功のために,大胆に行動すること,プロフェッショナルであることを大切にしている.このバリューについては 「エンジニアにとってのBe Professionalとは何か?」メルカリCTO名村卓の定義 - mercan(メルカン) を見るとわかると思う.

最終発表は職種が異なるというのもあると思うけど,内容があまり理解できないものもあった.やっぱり強い人たちばかりだなと.その中で,心残りはあるけど自分もやれるだけのことはやれたのかなと思う.

感想

このインターンシップで,社員の方はメルカリの成功のために Go Bold で All for One だし,社員の方も強くて Be Professional だし,情報も社員に対して全てオープンだし,働きやすい環境が整えられているし控えめに言って最高だと思った.

また色々と話を聞いて,サービスを運用していく過程で利用者だけではなく経営者や開発者なども含め,そのサービスに関わる全ての人たちが幸せであるためにどう行動していくべきかを考える良い機会になったと思う.

まだ自分がメルカリでやれることはあると思ってるし,やりたいことも沢山ある.確実に成長できたし色々な考え方にも触れることができた良いインターンシップだった.

f:id:calmery:20180922135008j:plain

オフィスから東京タワーが見える✨

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/

f:id:calmery:20180804222928p:plain

テストする

$ 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/

f:id:calmery:20180804223142p:plain

構文など

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 を見るとわかる.

作ったもの

github.com

お作法とか全くわからないけど Qiita API を使って 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 の処理が終わるまで待ってくれるので良い.

f:id:calmery:20180704220837p:plain

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 時間稼働させることができるし,小規模であればこれで全然良さそう.

app ドメインを使う

app ドメインを使うには HTTPS の使用が必須となっている.今回は GitHub Pages が HTTPS に対応しているのでリポジトリの設定から Enforce HTTPS にチェックを入れるだけで良い.

Heroku に関しては Hobby 以上でないとカスタムドメインSSL が使用できないので今はそのまま Heroku のアドレスを使用している.

まとめ

めっちゃ便利になったし感動してる.