こんにちは。GMOメイクショップで、主にフロントエンドの開発している原田です。今回は開発効率を高めるために、プロジェクトで活用しているツール群をご紹介します。参考になれば幸いです!この記事は GMOインターネットグループ Advent Calendar 2024 5日目の記事です。
はじめに
GMOメイクショップでは、ネットショップ構築SaaS「makeshop」を提供しています。私は、このサービスの管理画面をモダン化する「次世代ECプロジェクト」に携わっています。次世代ECでは フロントエンドにTypeScript / Vue3、バックエンドにGo / GraphQLを使い、GitHub上のモノリシックリポジトリにて開発しています。今回はそんな次世代ECの開発を支えるフロントエンド周辺ツールをご紹介します。
次世代EC開発を支えるツール群
VSCodeワークスペース
フロントエンドの開発環境は主にVSCode、もしくはGolandを利用しています。その中でも特にVSCodeの設定は、「ワークスペース」として共有することができます。そのため、推奨拡張機能、Linter設定、バックエンドを立ち上げるためのコマンドなどをワークスペースに記載して共有しています。ワークスペースを利用することで、環境構築の手間を削減しています。
タスク設定
手動での操作を減らすため、バックエンドのコンテナ起動などを VSCodeのタスク機能に登録。タスク一覧からワンクリックで実行できるようにすることで、開発効率を向上させています。
推奨拡張機能設定
特にフロント開発に必須となりそうな拡張機能を推奨機能として登録しています。これにより、開発開始時どんな拡張機能を入れる必要があるかが明示的になります。
カラー設定
モノレポ環境では複数のプロジェクトを扱うため混乱しやすいです。そのため、Peacockという拡張機能を利用し、フロントエンドはVueの緑色、バックエンドはGoの青色、GitHubActionsは黒色になるように設定しています。これにより混乱を防止しています。
ESLintとPrettier
コード規約などの問題点をチェックするLinterツールにESLint、コードの見た目を一定に整えるFormatterツールにPrettierを利用して開発しています。特にESLintでは、様々なコード規約を使い、常に一定の書き方で揃えて、後の開発者が読みやすいように整えています。
採用ESLintルール
下記のような各種推奨ルールを利用しています。利用しているライブラリに対応する公式ルールがあれば、可能な限り全てを採用し、一般的な作法に沿った書き方を目指しています。
export default [
// JavaScript標準 推奨ルール (jsファイルなどに適用)
// https://www.npmjs.com/package/eslint
eslint.configs.recommended,
// TypeScript標準 推奨ルール (tsファイルなどに適用)
// https://www.npmjs.com/package/typescript-eslint
…tseslint.configs.recommended,
// Vue公式 推奨ルール (vueコンポーネントに適用)
// https://www.npmjs.com/package/eslint-plugin-vue
…pluginVue.configs["flat/recommended"],
// Vueコミュニティ Scoped CSS用 推奨ルール (vue style scopedに適用)
// https://www.npmjs.com/package/eslint-plugin-vue-scoped-css
…eslintPluginVueScopedCSS.configs['flat/recommended'],
// Storybook公式 推奨ルール
// https://www.npmjs.com/package/eslint-plugin-storybook
…storybook.configs['flat/recommended'],
// その他カスタムルール
...extendedRules,
// Prettier 共存ルール (Prettierと競合するルールを無効化する) "必ず最後に書くこと"
// https://www.npmjs.com/package/eslint-config-prettier
eslintConfigPrettier,
]
拡張ESLintルール
推奨ルールに含まれていない細かなルール、逆に推奨ルールの一部に無効化が要るケースでは、下記のように別途ルール登録しています。内製したリリースフラグルールというESLintルールも存在し、リリース時の対応漏れを防止しています。
const extendedRules = [
eslintExtendRules,
...tsEslintExtendRulesArray,
vueCustomExtendRules,
...vueStyleScopedExtendRulesArray,
// 未使用のインポートと変数禁止 (自動削除)
noUnusedImportAndVarsRules,
// インポート順序の強制
importOrderStrictRules,
// 相対インポート禁止
...noRelativeImportRulesArray,
// export default禁止
...noExportDefaultRulesArray,
// リリースフラグルール (yaml記載のフラグがコード内に残っていればリリース日にエラーとなる)
releaseFlagLinterRules,
]
TypeScript
昨今の高機能で複雑なフロントエンドを実装するためには型付けのあるJavaScript、TypeScriptが不可欠です。TypeScriptが存在することで、コードを実行する前にエラーを検出することができます。TypeScriptでも特に便利な、頻出する書き方を3つご紹介します。
よく使う書き方
as const
通常、配列を定義すると {key: string, value: string}[] のような型になります。これは as const を使うとさらに厳密な型情報で表示することもできます。例えば ITEMS[0].key のように定数を参照する際、何が入っているかが厳密に表示され、読み出しデータの取り違え防止に役立ちます。
// これは {key: string, value: string}[] となる
const ITEMS = [
{ key: "key1", value: "value1" }, { key: "key2", value: "value2" },
]
// これは readonly [ { readonly key: "key1"; readonly value: "value1" }... ]
// のような厳密な型になる
const ITEMS = [
{ key: "key1", value: "value1" }, { key: "key2", value: "value2" },
] as const
satisfies
satisfies は 満たす必要がある前提となる型を指定できる構文です。定数を作る際に間違った記述をすることを防止したり、switch パターンの網羅チェックに役立ちます。
const ITEMS = [
{ key: "key1", value: "value1" },
// key と valueが無く 前提となる型を満たしていないのでエラーになる
{ k: "key2", v: "value2" },
] as const satisfies {key: string, value: string}[]
const input = "cat" as "cat" | "dog"
switch (input) {
case "cat":
return "猫"
default:
// 全パターンを網羅していればここに辿り着くことは起こり得ず never型になる
// このケースでは "dog"の条件を満たしていないのでnever型にならず、エラーとなる
console.error(`Invalid ${input satisfies never}`)
}
ジェネリクス
型定義自体をパラメータとして渡すことで、複数の異なるデータ型をサポートできる型をジェネリクスといいます。慣れるまでが大変ですが、非常に強力な機能です。例えばAPIのエラー処理など、複数箇所で使う型定義に利用しています。
// ジェネリクスTを受け取る レスポンス型定義
type ResponseOkOrError<T extends string | number | boolean | object>
= [T, undefined] | [undefined, Error]
const fetchHoge = async (): ResponseOkErrorError<string> => {
try {
const res = await fetch('https://example.com')
const body = await res.text()
return [body, undefined]
} except (e) {
return [undefined, e as Error]
}
}
const [res, err] = await fetchHoge()
if (res) {
// res型は string / err型はundefined
console.log(res, err)
} else {
// res型は undefined / err型は Error
console.log(res, err)
}
Vite-plugin-vue-devtools
Vue公式の開発支援ツールです。マウスカーソルでコンポーネントを選択し、瞬時に対応するコードを開く他、現在のコンポーネントに渡された情報を確認できます。これによりローカル環境での開発を大幅に効率化することができます。
Vitest
関数単位の処理をテストできる、ユニットテストツールです。見た目以外の複雑なロジックの動作検証に役立っています。
Storybook
主に見た目要素、共通のデザインカタログを確認できるビジュアルテストツールです。次世代ECでは特に、共通コンポーネントを登録していつでも確認できるようにしています。重複するコンポーネントの作成防止や、デザインのレビューに役立っています。
Autify
実際のユーザーのブラウザ操作を再現することで動作テストを行う、E2Eテストツールの一種です。有償ではあるものの、ブラウザに拡張機能を導入するだけで、ノーコードでテストを書けるのが魅力的なツールです。最近導入したところで、まだまだテスト数が少ないものの活用を進めています。
GitHub Issue forms・ GitHub Pull Request template
GitHubでのタスク管理には、共通の書き方でIssueを作成できるIssue Formsや、プルリクエストの内容記載にはPull Request Template 機能を利用しています。テンプレートを使うことで、常に過不足の無い情報記載をし、後から情報を探しやすい環境を目指しています。
Issueフォーム
PRテンプレート
GitHub Copilot
makeshopでは AI開発支援ツールである、GitHub Copilotを開発に活用しています。コードを書くスピードを高めたり、開発満足度の向上に役立っています。
チャットの活用例
もっと良い書き方はできないか? をラフに尋ねたり、SASSが具体的にどんな要素構造に対して機能するか具体例を出してもらう等で活用しています。
Autofixの活用例
型の不一致エラーなど、細かな問題にもGitHub Copilotが役立ちます。表示されているエラーメッセージを元にした解決策を提示してもらうと、ほとんどの場合、自動的に修正を行うことができます。
Github Actions
依存関係の更新など、自動化の余地があるものは可能な限りGitHubActionsを活用しています。また、GraphQLの型定義生成なども自動化し、手動での対応を減らしています。
採用しているアクションの例
・Renovateを用いたフロント依存関係更新・Graphql-Code-Generatorを使った GraphQL型定義生成・SpectaQLを使った GraphQLドキュメント生成・タイトル/本文/ブランチ名/改修ファイル等を元にした IssueやPRへの自動label付与・CodeRabbit (OSS版)と GPT4o-miniを使った AIコードレビュー (置き換え検討中)・マージ後のデプロイ処理
次世代EC開発に利用していないツール
今回紹介した中には、代替ツールがあるものもあります。あえて利用しなかったツールも一部ご紹介します。
VSCode DevContainer
仮想コンテナ基盤であるDockerを利用し、エディタ全体を仮想環境で立ち上げる機能です。設定を厳密に共有可能な点がメリットですが、動作が重く開発端末が不安定になることから、利用しなくなりました。スペック的に余裕がある環境下ではおすすめしたいです。
Biome
BiomeはRust製のLinter/Formatterツールです。昨今パフォーマンスの良さから話題です。しかし、ESLintで通常の推奨ルールだけでなく、さまざまな強化ルールを採用している環境のため、Lintルール全てを移植することが難しく一旦ESLintのまま据え置きしています。
Histoire
Storybookの代替候補として、特にVueを想定したHistoireというツールが存在します。Vue3環境で動作検証し、動作に特段な問題はなかったものの、あまりメジャーでなく資料が少ない点、関連するプラグインやエコシステムが整っていない点から本導入は見送ることになりました。
Playwright
E2Eテストツールとして、初期はCypress、その後しばらくはPlaywrightを利用していました。しかし、テストコードを専任できるリソースがなく、なかなかテストコードを増やせない点、テストランナーを自前で運用するのが難しい点が課題になっていました。そこで、Webブラウザだけで簡単にテストを作成でき、テストランナーが外部で保守される、Autifyに徐々に載せ替えています。
まとめ
次世代ECでは下記のようなツールを活用してフロントエンドを開発しています。今後自動テストツールの活用に注力し、バグの防止を推し進めていきたいです。エディタ: VSCode または GoLandLinter/Formatter: ESlint / Prettier開発言語: TypeScriptテストツール: Vitest / Storybook / Autify開発支援ツール: VitePluginVueDevToolsコード管理と自動化: GitHub / Github Copilot / GitHub Actions
さいごに
以上、次世代ECの開発を支えるツール群をご紹介しました。これらのツールは、日々の開発効率化や品質向上に役立っています。気になるものがあれば、ぜひ試してみてください!GMOメイクショップの社内テックブログもよろしくお願いしますhttps://tech.makeshop.co.jp