Vue 2 系で作るコンポーネント設計方針

いよいよ Vue 3 がリリースされるということで、Vue 2 系でどういった考えのもとコンポーネントを設計してきたのかをまとめておきたいと思います。

対象

  • CRUD を主とした BtoB アプリケーションを想定
    • 十数項目以上の登録(Form)画面、多機能な一覧画面 etc
    • 管理画面

前提

  • Vue CLI
  • Vuex
  • UIフレームワーク使用
    • View UI (旧 iview) を好んで使用します。Vue 3 はサポートされるのか。。。
  • @vue/composition-api (2020/07/31 時点ではベータ) の導入に踏み切れていません。
    • Vue 3 では Composition API を利用します。
    • Vue 3 がリリースされたら Vue 2 でも @vue/composition-api を導入します。
      • 趣味では導入経験あり
  • チーム開発では service などの独自パッケージ(ディレクトリ)は作りません。
    • プロジェクトルートや src トップには CLI コマンドで作成されたフォルダのみ。
    • コミュニケーションコストや初見殺しを避けるため
    • メンテナーが総入れ替えするたびに負債化していく事が多いため

設計方針

課題

  • 独自パッケージ禁止縛りのため、値オブジェクトを表現するのが難しい
    • 個人開発の場合は値オブジェクトパッケージを切ります。
  • バリデーション
    • UIフレームワークが内包している場合はそれに従います。
      • 辛いことも多いが、ドキュメントが有るので低コストで運用可能
    • 個人開発の場合はバリデーションパッケージを切ります。
    • できるだけ水際で対処したいが、バックエンド要件にあった層で注入します。
  • 不要なドメインロジックは書きません。サーバーサイド担当者を説得します。
    • フロントエンドの寿命は短い
  • Store でなくても構いませんが、代替が今のところありません。
  • atoms 以下の要素に対する CSS をどう管理するか
    • 基本的には各コンポーネントに閉じて「管理しない」という戦略を取ることが多い
    • 外部CSSにまとめることもありますが、せいぜいクラス2〜3個までにまとめます。(tailwind より更にミニマムなものが欲しい)
  • 似たドメイン問題

終わりに

現時点では上記のような戦略で、できるだけコンポーネント間の依存関係を明確にするように書いています。ユースケース、コントローラーでの仕様変更に対応しやすく、ドメイン・値コンポーネントの追加・削除が安全に行える設計を目指しています。

そろそろ Vue 3 でメモアプリでも作って、現状の戦略をどう変えていくか検討していきたいと思います。

フロントエンド戦略とUIフレームワーク

Web 系で UIフレームワークというと、よく善か悪かで語られる印象がありますが、私はプロダクト立ち上げ時における技術選択の一つでしか無いと考えています。

機能要求、非機能要求に基づいて、使用するならどのような特徴を持ったUIフレームワークを選択しカスタマイズするのか、使用しないならどのようにコンポーネント郡を構築、管理していくのか。プロダクトのリリース、そしてグロースまで見据えたフロントエンド戦略の一環として取組みます。

以下の図は、ここ数年で私が触れたUIフレームワークを主観でプロットした図になります。Vue 系がメインになりますので、あしからず。 また、私は主に右下を主戦場にしているので、多少のバイアスも含まれていると思います。

UIフレームワークの有効範囲
UIフレームワークの有効範囲

Utility Types チートシート

Utility Types · TypeScript から逆引きコピペ用チートシート(抜粋)です。

readonly へ変換する

Readonly<T>

optional(?) を取り除く

Required<T>

optional(?) へ変換する

Partial<T>

T から K を抽出する

Pick<T, K>

T から K を取り除く

Omit<T, K>

T から null と undefined を取り除く

NonNullable<T>

関数Tの返り値の型を抽出する

ReturnType<T>

Tクラスのインスタンス型を返す

InstanceType<typeof T>

T と U の共通部分を取り除く

Exclude<T, U>

T と U の共通部分のみ抽出する

Extract<T, U>

K に対して T 型を割り当てる

K に union types を使う場合に強力

Record<K,T>

2019年と2020年

今年、2個めの記事です。 1年の振り返り記事しか無いブログになってます。。。

目次

  • 2019年の振返り
    • 受託案件
    • 自社システム開発
    • Go の学習
    • 新しい挑戦
    • 個人開発(趣味)
    • 家族・子育て
  • 2020年について
    • 仕事
    • 個人開発(趣味)
    • 子育て
  • 最後に

2019年の振返り

受託案件

とあるスタートアップにて、週3で主にフロントエンドを中心にお手伝いをしています。昨年に引き続きフルリモートで参加させて頂いています。地方に居て、この条件で仕事ができているのはありがたく、クライアントには感謝しかありません。最近、チーム移動がありましたが、前チームでは途中参加にも関わらず、フロントエンドのリポジトリでコミット数 1位(2019/12/28 時点)を記録しました!週3フルリモートでも結果は残せていると思います。

自社システム開発

自社と言っても父が営んでいる管工事業の会社ですが、経理向けの工事台帳システムを作っています。前システムの老朽化に困っていた両親に相談され、2018年4月から一人で開発しています。週1〜2日未満でマイペースに開発していました。今秋に稼働し始めています。(お盆、正月、GW前後など全く進捗0の期間もありつつ)

工事台帳管理システム
工事台帳管理システム

単純な CRUD システムです。バックエンドは Go / PostgreSQL、フロントエンドは TypeScript / Vue で、無駄にマルチテナント対応しています!

工期が掛かってしまいましたが、なんとか稼働するところまでたどり着きました。今後も経理部長(母)と二人三脚で改善、機能追加していく予定です。(あわよくば SaaS 展開も!?)

Go の学習

自社システム開発では gin と gorm を使用してるくらいで、正直 Go できますって感じではないです。そこで作りながら、スターティングGo言語改訂2版 みんなのGo言語 を読みました。作りながら復習していくスタイルで、学習体験としては久々に楽しくできました。自身のこれまでの言語遍歴と Go がマッチしたところが良かったのだと思います。 折角なので、受託案件でも Go を触れる機会があれば良いなと思います。

新しい挑戦

去年の年末には Flutter、Python とか触りたいなーっと思っていましたが、作りたいものが特に無く、触る機会がありませんでした。その代わり少しだけ Ruby を触りました。

個人開発(趣味)

5月に中国の技術系の掲示板?からまとまったアクセスがあり、それ以降ぼちぼちスターが増え続けています。

2017年に Vue の勉強ついでに作ったWebアプリなので、今見るといまいちな部分が多いですね。自分が実務で使うためのツールなので、細々とメンテしています。

また、最近 public なリポジトリに Go や TypeScript が無いことに気づき、営業のためと思って幾つか作りました。

github.com

github.com

自身の「はてなブックマーク」データを Algolia にバックアップしているのですが、 どちらともそれを検索する簡易的なツールとなっています。

TypeScript は 1.x 系から使っていますが、近年さらに進化している型をキャッチアップしていなかったので、実践TypeScript を読みました。これが今年読んだ書籍で一番よかった気がします。他には vue-composition-api なんかも試しています。

家族・子育て

子供たちも少しづつ手が掛からなくなり、単純作業、肉体労働の子育てから次の段階に移りつつあります。今後は考え方だったり、伝え方に神経を使うことになるのかなと。世の中のルールだったり、習慣だったり、善悪なども子供が理解・納得できるように伝えなければなりません。子育てにコミニュケーション能力が必要だなんて。。。

あとは夢中になれる趣味を早く見つけてあげたい。経済的な制約もあるので、そんなに多くの機会は作ってあげられないかもしれないけど。なにか一つでも刺さればなと思っています。願望としてはもう少しピアノに興味持って欲しい!それともうそろそろ、プログラミング楽しいよ?も勧めてみようかなと思案中です。

2020年について

まだ全体的に目標とか何をしたいかなど、ふわっとしているので、この年末年始休みの間に改めて考えたいと思っています。

仕事

フリーランスも3年目を迎えました。受託も継続しながら、父の会社のIT相談・改善も進めていきたいと思っています。特に母の負担を減らしてあげたい。もういい歳なので。あと、もう少し活動の幅を広げていきたいと考えています。(漠然!?)

個人開発(趣味)

PlantUML Editor の脱 Bootstrap や TypeScript 化なんかしたいですね。(本当にやるかな?)他には今年こそ Flutter 入門したいと考えています。(本当にやるかな?)

子育て

とにかく一緒に遊ぶ!やはり親が「楽しい」というところを見せてあげないといけないと感じました。ピアノも一緒にやってみたり、プログラミング教材なんかも調べているので、一緒になにか作ってみたいと思います。旅行にも行きたい!

最後に

2019年も振り返ってみると色々とありました。仕事、子育て、家事とバランス良くやれたと思っています。(妻の評価が怖い。。。)2020年はもう少し自分に負荷をかけつつ、新しい挑戦をしていきたいです!

Cloud Run で PlantUML Server を利用する

自前の PlantUML Server が欲しくなったら Cloud Run がお手軽です!(2019/04/16 時点)

SDK をインストール

cloud.google.com

認証

cloud.google.com

image build

github.com

をクローンして

docker image build -t gcr.io/<プロジェクトID>/plantuml-server .

image push

docker push gcr.io/<プロジェクトID>/plantuml-server

サービス作成

CREATE SERVICE ボタンをクリックして push した image を選ぶだけ。

オプションでメモリを 512 以上に設定する。

以上!!

これだけで、XXXX.run.app に PlantUML Server が立ち上がります!

手軽すぎて怖いですね。。。

参考

medium.com

qiita.com

cloud.google.com

2018年と2019年

ユニコーンの「雪が降る町 」を聴きながら書いています。

熊本でも雪が降りました。

2018年

今は運が良いことにフルリモートの案件に参加しています。生活は祖父母、両親と同居し、とても賑やかな環境で子育てが出来ています。クライアントや家族には感謝しかありません。特に80を超えた祖母には子育てで随分と助けられています。そして何よりも新しい環境にあっという間に慣れた子供たちへ感謝です。(保育園にも感謝。)

また受託の傍ら、両親が営む会社のバックオフィス業務システムをフルリニューアル中です。あわよくば SaaS 展開したいと思案しています。ただ、週1〜2日未満の稼働にもかかわらず、フルスクラッチ&使ったことのない言語・環境で始めたのでものすごく時間が掛かっています (汗)

結果として受託、自社システム、個人開発、子育て、読書 etc とバランスが取れたのは良かったです。周りの人々に支えられた1年だったと改めて感じています。ありがとうございました。

地方ITエンジニア(フリーランス)について

都会と比較はできませんが、生活できるかどうかは「運」しだいです。

私程度のWebエンジニアであれば、収入を優先させるなら福岡・東京で勤めるべきでしょう。私にとってはそれ以上に大切なものがあり、結果、熊本の更に谷郷のような場所で生きています。先の話ですが、子供たちが大学に進学する際には、福岡・東京などを勧めたいと考えています。

2019年

  • 受託継続
    • 安定した収入を確保する
  • 自社システム開発 アルファリリース
    • 営業
  • golang レベルアップ
  • Flutter (未経験)
  • Python (未経験)
  • 長男の趣味を作る

来年も、この地で子供たちを育てていくための基盤づくりを進めていきたい。

まずは2018年に始めたことを継続できるように気を引き締め、新しいことにもチャレンジしていきたい。

また、「少年」になりつつある長男に趣味を作ってあげたい。音楽やスポーツ、科学、読書 etc 何でも良いので、少しでも彼の人生が豊かになるように努めたい。機会を増やし、なにか 1つでも好きになってもらえたら◎。

フリーランスになって2年目に突入し、まだまだこれから。

2019年はもう少し将来の見通しを良くしたい。そして1歩でも先に進んで行く。

お父さん、がんばります!!!

Docker コマンド備忘録

Docker + Go + Gin の開発環境を準備する
を書いた時に学んだことを残しておきます。

参考サイトから必要最小限だけ抽出しただけなので、
Qiita ではなく自ブログに記載してます(汗)

イメージビルド

# --no-cache 構築時にイメージのキャッシュを使わない
# --pull 常に新しいバージョンのイメージ取得を試みる
# --force-rm 常に中間コンテナを削除
docker-compose build

イメージ一覧

docker images

イメージ削除

docker rmi <イメージ名>

# 全削除
docker images | awk 'NR>1 {print $3}' | xargs docker rmi

# タグなしのイメージをすべて削除する
docker images | grep '<none>' | awk '{print$3}' | xargs docker rmi

コンテナ作成・起動

# -d バックグラウンド実行
docker-compose up -d

コンテナ一覧

# -a 全コンテナ表示(デフォルトは起動しているコンテナのみ)
docker ps -a

コンテナ起動

# 再起動も出来る
docker-compose start
# docker-compose restart

コンテナ停止

# 削除しません
docker-compose stop

コンテナ削除

# -v ボリューム削除
docker-compose down

# 全削除
docker ps -a | awk 'NR>1 {print $1}' | xargs docker rm

コンテナログ確認

# -f 表示しつづける
# -t タイムスタンプの表示
docker-compose logs

コンテナ接続

# コンテナ名、コマンドは docker ps -a で確認出来る
docker exec -it <コンテナ名> <コマンド>
# 例 docker exec -it -e COLUMNS=200 -e LINES=50 ubuntu_bash bash

ボリューム確認

docker volume ls

ボリューム削除

docker volume rm <ボリューム名>

# リンク切れ削除
docker volume ls -qf dangling=true | xargs docker volume rm