ざきの学習帳(旧 zackey推し )

日々の学びを書きます

副業を始めて良かったこと、悪かったこと

この記事はwrite-blog-every-week Advent Calendar 20201日目の記事です。

adventar.org


今年の9月から副業を始めました。始めた経緯や理由は以下記事に記載しています。

kic-yuuki.hatenablog.com

この記事では、実際にやってみて良かったこと、悪かったことをエンジニアとしての経験やプライベート等々、振り返りながら分けずに記載していきます。

良かったこと

普段の業務で学んだことを実践し、成長する機会を強制的に得られた

副業先で求められる成果を果たすことが第一ですが...自分の場合は、現職と副業でVue.jsという同じ技術を使っていることにより、現職を通して感じた自分の知識・技術的な課題を副業先で実践し、血肉にできた場面が何回かありました。

例としては、以下のような内容です。

これらは個人開発でもやろうと思えば実践できます。

が、自分は個人開発に対してそこまでのモチベーションが湧かない(もしくは、あくまで勉強だから...という理由に逃げ、頓挫してしまう)ため、副業という成果を求められるものに頼り、強制的に成長する機会を得ています。

副業(勉強)に締まりが出ている

副業をこなすと、報酬をいただけます。

「報酬が発生する=お金がもらえる」という考えから手抜きを許さず、成果を出そうと自分を戒めることができます。

私は、個人開発や写経だとたるんでしまいがちです。成果を出さないといけないという縛りをつけることで、現職・副業にまつわる勉強に締まりが出たと感じています。

以前関わった人々とプロダクトに貢献し続けられている

私の副業先は前職なのですが、また一緒に仕事ができて嬉しい...というのが本音です。

前々職以前は業務形態等々の関係で、人とのつながりをあまり持続できていませんでした。しかし、前職のみなさんは肯定的に自分の副業を受け入れてくれています。

以前関わった人々とプロダクトに貢献し続けられている

このことが個人的に一番嬉しくて、楽しいことです。

継続が難しい状況にならない限りは、副業を続けていこうと思います。

悪かったこと?

遊びの時間が減った

当然ですが、平日業務後や休日の時間を副業に割り当てるため、遊びの時間が減りました。

COVID-19の影響も少なくないですが、週末は副業に時間を割く必要があり、外出(とくに遠出)する機会も減りました。

が、副業を始めた目的である成長機会を得ているので、この辺は仕方がないかぁ...と思っています。

手続きがめんどい

副業で収入が増えるのは良い事柄の1つですが、代わりに請求書提出、確定申告等の手続きが増えます。

青色申告の準備

来年は青色申告を行う予定です。

www.nta.go.jp

電子で完結したいがために、以下を行いました。

  • 会計freeeの契約
  • マイナンバーカードの発行(いまさら)

屋号登録や口座登録有無等、まだまだやることはあるのですが、とりあえずここまで。あとは確定申告手前になったら考えようと思います。。。

カイゼン・ジャーニーを読んだ / ハンガーフライト良さそう

ずーっと積んでいたカイゼン・ジャーニーを読み終わりましたので、気になったところ等々をメモします。

感想

手に取ったのは「チームやプロジェクトで問題にぶち当たったけど、それは自分だけの問題?それともチームの問題?」ってのがわからなくなり、その答えを見つけたいという理由からです。

ストーリー仕立てでプロジェクトの改善を推し量っていく手法や立ち向かう問題・解決策が紹介されていました。筆者である市谷さんの実際の経験に基づいて書かれており、普段の開発現場で起こり得る問題への対処方法や理論は、非常に勉強になりました。(ストーリーも楽しみました。)

結論、答えは見つからなかったですが、チームとして協働していくことを記載したチーム・ジャーニーも続けて読み進めていこうと思います。

気になったところ

提唱されている理論や手法が主です。

成功循環モデル

単にワークショップを開いて、チームの関係を仲良くするだけで本当に仕事の成果は上がるの?って思ってましたが、組織において結果の質をあげるためのグッドサイクルというものがすでに提唱されており、本書で紹介されていました。

www.salesforce.com

関係 -> 思考 -> 行動 -> 結果 -> 関係...のサイクル。会社で働くにあたって、チーム・個人としても目標に対する結果が求められる中、グッドサイクルを目指すのって気が遠くなりますが、この理論等をお互いに理解・共感してやっていくしかないんですかね...。

ドラッガー風エクササイズと星取表(=スキルマップ表)

自分への期待値を整合する機会を得るドラッガー風エクササイズと、スキルの得意・苦手・今後習得したいを記載する星取表はチームの相互理解を深めるために使えると思いました。

www.ryuzee.com

なんとなく「あの人はフロント / サーバサイドができる」ってイメージで捉えてますが、実はやっているだけで得意ではない(勉強中)というケースもあり得ます。チームメンバー増減が頻繁におきたり、グループではなくチームとして協働するプロジェクトなどが立ち上がった際は、これらを活用すると開発時の細かいコミュニケーションズレや軋轢が少なくできるんじゃないかと思います。

むきなおり

「ふりかえり」じゃなくて、「むきなおり」が紹介されていました(初めて聞きました)。方向性を定め直して、共通認識する機会を作ることだそうです。

devtab.jp

事後ではなく、これからの未来を見つめ直したい場合に使ってみようと思います。

CCMP

個人ごとにバッファを持つのではなく、プロジェクトとしてのバッファを設ける手法...と解釈しました。(以下を拝見した感じ、実際はプロジェクト管理手法の一種っぽい)

qiita.com

ハンガーフライト

ざっくり言うと、みんなの経験と知恵を繋ぐ機会。本書の説明と、以下の記事を読むと理解が捗りそうです。

papanda.hatenablog.com

leetcodeの回答をリポジトリ管理、 ts-jest でテストを書いているはなし

コミュニティの人たちと、leetcodeの問題を週1で解いていく活動をはじめました。

この記事では、leetcode回答までの流れを書き留めておきたいと思います。

leetcode始めたい...という方の参考になれば、幸いです。

leetcode回答の流れ

leetcodeは様々な言語で回答可能となっており、自分はTypeScriptで選択しています。

budougumi0617.github.io

budougumiさんの上記記事を拝見し、自分もCLIを自作したい...と思ったのですが、

LeetCodeのAPIの仕様はドキュメント化されていないので、RustのCLIリバースエンジニアリングして解析する必要があった(Rustわからない)

で、心が折れ

  1. 愚直に回答を手元のVSCode x TypeScriptで記述
  2. Jestでテストを記述
  3. テストで通った回答コードをleetcodeのエディタへペースト、Submit

という流れで実施しています。

テストを書いているのは、単純にJestの素振りをしたいがためです。

リポジトリ

typescript-sandboxleetcodeというディレクトリを作り、leetcode回答専用の環境を整えています。

ts-jestのセットアップ

TypeScript x Jestの環境でテストを書くため、ts-jestのドキュメントを元に環境セットアップをしました。

kulshekhar.github.io

以下抜粋です。

# typescript未導入なら `npm i -D typescript` も必要
npm i -D jest ts-jest

# jest.config.jsの生成
npx ts-jest config:init

結果、やってみてどう?

始めてからまだ3週間かつ比較的簡単な問題ばかりを解いていますが、

  • 自分と他人のコードを比較し、処理効率等で学べる部分がある
  • Jestを少し学んだ
  • 型に詳しくなった
  • 頭の体操になる(何もしないよりはいい)

というような効果があると感じています。

何を勉強しようか...と悩まれている方は、とりあえずleetcodeに手を伸ばしてみるのも一興と思います。

【JavaScript】Facebookログイン〜Instagram Graph APIの実行 までできたサンプルと所感

前提条件として、バージョンは以下。

タイトル通り、Facebookログイン〜Instagram Graph APIの実行までできたので、雑に作ったサンプルと手順を以下リポジトリディレクトリに置きました。(コードからREADMEまで雑なので、よければ参考程度にしてください)

github.com

本記事では、素振りしたときのことや所感を書き残しておきたいと思います。

Facebookログイン〜Instagram Graph API実行の手順

は、以下のスタートガイドに記載されていました。

developers.facebook.com

先ほど紹介したサンプル実装は、スタートガイドに長期トークン取得処理を加えたものになっています。

長期トークンの取得

Facebookログイン時に得られるトークンは期間が短いため、システム要件に応じて、60日間有効な長期トークンに変換した方がよいかもしれません。

developers.facebook.com

ただし、長期トークンの取得にはappSecretの指定が必要なため、実装するならフロントではなくサーバサイドが望ましいと思います。

事前準備

スタートガイドBefore You Startに漏れなく書いてありました。

ざっと必要なものは以下です。

自分の場合は、FacebookページとInstagramビジネスアカウントのリンク設定を失念し、APIは成功している(200OKを返している)のにInstagram Business IDが取得できない...という状態に陥ったので、注意してください。

www.facebook.com

所感

以上です。

【JavaScript】URLSearchParams でクエリパラメータを操作する

フロントで、クエリパラメータをいい感じにkey-valueのObjectに変換したい...っていうことをやりたくて、探したところ、Web標準APIとして提供されていました。

developer.mozilla.org

正規表現やVueRouterのようなライブラリを用いる手段のみと思っていたので、忘れないよう書き留めときます。

使い方

URLパラメータの構築

typescript-sandbox/fb-login-sample at master · zakizaki-ri9/typescript-sandbox · GitHub

上記リポジトリで、FacebookログインおよびSDKの素振りをおこなっています。

長期ユーザートークンを発行するため、以下のようにURLSearchParamsを利用し、クエリパラメータを構築しています。

// https://github.com/zakizaki-ri9/typescript-sandbox/blob/03b4e49fb64dfbe116620827a666946922780a72/fb-login-sample/src/components/FacebookLoginForm.vue#L74-L92
// から抜粋
    // https://developers.facebook.com/docs/instagram-api/getting-started Step3
    const onGetLongAccessToken = async () => {
      const params = new URLSearchParams({
        grant_type: "fb_exchange_token",
        client_id: appId.value,
        client_secret: appSecrets.value,
        fb_exchange_token: getAccessToken() // Long Access Tokenでもいける
      });
      const response = await fetch(
        "https://graph.facebook.com/oauth/access_token?" + params
      );
      // 〜省略〜
    };

axiosを使わず、Web標準fetchを用いる場面だと、有効活用できそうです。

github.com

developer.mozilla.org

クエリパラメータをkey-valueなObjectに変換

クエリパラメータを抜き出したいURLをURLインスタンス化 -> searchParamsURLSearchParamsを取得 -> key-valueなObjectを取得できます。

以下、コード例です。

TypeScript: TS Playground - An online editor for exploring TypeScript and JavaScript

// "クエリパラメータ"でGoogle検索したときのURL
const url = "https://www.google.com/search?q=%E3%82%AF%E3%82%A8%E3%83%AA%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF&rlz=1C5CHFA_enJP848JP848&oq=%E3%82%AF%E3%82%A8%E3%83%AA%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF&aqs=chrome..69i57j0l7.2154j0j7&sourceid=chrome&ie=UTF-8";

console.log({
  params: new Array(...new URL(url).searchParams.entries())
});
/*
output↓
{
  "params": [
    [
      "q",
      "クエリパラメータ"
    ],
    [
      "rlz",
      "1C5CHFA_enJP848JP848"
    ],
    [
      "oq",
      "クエリパラメータ"
    ],
    [
      "aqs",
      "chrome..69i57j0l7.2154j0j7"
    ],
    [
      "sourceid",
      "chrome"
    ],
    [
      "ie",
      "UTF-8"
    ]
  ]
} 
*/

おわり

以上です。

Web標準でこういうのあると、ライブラリやフレームワークに依存しなくて良いすね。(もっと早く知りたかった...)