Zenn
Closed6

在庫管理台帳を開発してみる

Nakajima.jsNakajima.js

商品情報

項目名 説明
商品ID 各商品に割り当てられる一意の識別子。
商品名 商品の名称。
カテゴリー 商品が属するカテゴリー。
焙煎度 コーヒー豆の焙煎の度合い(例: 浅煎り、中煎り、深煎り)。
内容量 商品の内容量(例: 250g, 500g)。
特徴 商品の特長やセールスポイント。
単価 商品の単価。
登録日 商品が登録された日付。

商品IDの構造案

  1. 商品名の略称: 商品名を短縮した2〜3文字の略称。
  2. 形状: 豆か粉かを示す1文字(例: 豆 = "B"、粉 = "P")。
  3. 焙煎度: 焙煎度を示す1文字(例: 浅煎り = "L"、中煎り = "M"、深煎り = "D")。
  4. シリアル番号: 一意の識別子としての3桁の番号。

  • 商品名が「コロンビア」、豆、中煎り、250gの場合:

    • 商品ID: COL-BM-250-001
  • 商品名が「エチオピア」、粉、深煎り、500gの場合:

    • 商品ID: ETH-PD-500-002
  • 商品名が「キリマンジャロ」、豆、浅煎り、250gの場合:

    • 商品ID: KIL-BL-250-003
  • 商品名が「ブルーマウンテン」、粉、中煎り、500gの場合:

    • 商品ID: BLM-PM-500-004
  • 商品名が「モカ」、豆、深煎り、250gの場合:

    • 商品ID: MOC-BD-250-005
  • 商品名が「ブラジル」、粉、浅煎り、500gの場合:

    • 商品ID: BRA-PL-500-006
  • 商品名が「グアテマラ」、豆、中煎り、250gの場合:

    • 商品ID: GUA-BM-250-007
  • 商品名が「コナ」、粉、深煎り、500gの場合:

    • 商品ID: KON-PD-500-008
  • 商品名が「マンデリン」、豆、浅煎り、250gの場合:

    • 商品ID: MAN-BL-250-009

このようにすることで、商品IDから商品名、形状、焙煎度、内容量を直感的に把握できるようになります。

Nakajima.jsNakajima.js

焙煎度

項目名 説明
焙煎度 コーヒー豆の焙煎の度合いを示す。
階段 焙煎度のステージを示す。
特徴 焙煎度に応じた味わいや香りの特徴。
詳細 焙煎度に関する詳細な説明。
Nakajima.jsNakajima.js

GitHub設定あれこれ

Gitフローをシステムで制限したりする
コミュニティ活性化を目的にしているので今後自分1人だけで開発とは限らないため初期のタイミングで法整備を行っておく

mainリポジトリに直接pushすることを禁止する

CodeRabbitを導入するのでmainに直接pushしてしまっては意味がなくなってしまうため

https://zenn.dev/json_hardcoder/articles/f9b534377103a4

ターゲットはmainに設定

設定項目はこんな感じ

Require a pull request before mergingに追加の設定をする項目があるがいじらずにしておく

ブランチの命名規則

GitHubのissueからブランチを作成
issueを立ち上げてから作業を基本行なっていく
ブランチ名は日本語になっていても問題ないとする
作業ブランチの切り替えのコマンドも生成してくれるので楽

issueのテンプレート

  1. バグ報告 (Bug Report):
    • ソフトウェアの不具合や予期しない動作を報告するためのテンプレートです。再現手順、期待される結果、実際の結果、環境情報などを含めると良いでしょう
bug_report
---
name: バグ報告
about: バグを報告してプロジェクトの改善に貢献する
title: "[BUG] バグの簡単な説明"
labels: bug
assignees: ''

---

**バグの説明**
バグが何であるかを明確かつ簡潔に説明してください。

**再現手順**
バグを再現するための手順を記載してください:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**期待される動作**
期待される動作を明確かつ簡潔に説明してください。

**スクリーンショット**
可能であれば、問題を説明するのに役立つスクリーンショットを追加してください。

**デスクトップ (以下の情報を記入してください):**
 - OS: [e.g. Windows, macOS]
 - ブラウザ [e.g. Chrome, Safari]
 - バージョン [e.g. 22]

**スマートフォン (以下の情報を記入してください):**
 - デバイス: [e.g. iPhone6]
 - OS: [e.g. iOS8.1]
 - ブラウザ [e.g. stock browser, safari]
 - バージョン [e.g. 22]

**追加のコンテキスト**
ここに問題に関する他のコンテキストを追加してください。
  1. 機能リクエスト (Feature Request):
    • 新しい機能や改善を提案するためのテンプレートです。提案の詳細、利点、関連するスクリーンショットやモックアップを含めることができます
feature_request
---
name: 機能リクエスト
about: 新しい機能の提案
title: "[FEATURE] 機能の簡単な説明"
labels: enhancement
assignees: ''

---

**機能の説明**
提案する機能が何であるかを明確かつ簡潔に説明してください。

**動機**
この機能がなぜ必要か、どのように役立つかを説明してください。

**提案する解決策**
機能の実装方法についてのアイデアがあれば記載してください。

**代替案**
考えられる代替案や機能について記載してください。

**追加のコンテキスト**
ここに機能に関する他のコンテキストやスクリーンショットを追加してください。

  1. 質問 (Question):
    • プロジェクトに関する質問やサポートを求めるためのテンプレートです。具体的な質問内容や関連する背景情報を記載します
question
---
name: 質問
about: プロジェクトに関する質問
title: "[QUESTION] 質問の簡単な説明"
labels: question
assignees: ''

---

**質問の内容**
質問を明確かつ簡潔に説明してください。

**関連する背景情報**
質問に関連する背景情報や試したことを記載してください。

**追加のコンテキスト**
ここに質問に関する他のコンテキストを追加してください。

  1. ドキュメント改善 (Documentation Improvement):
    • ドキュメントの誤りや改善点を報告するためのテンプレートです。具体的な改善提案や誤りの詳細を含めます
documentation_improvement
---
name: ドキュメント改善
about: ドキュメントの誤りや改善点を報告する
title: "[DOCS] ドキュメントの簡単な説明"
labels: documentation
assignees: ''

---

**改善の説明**
改善が必要なドキュメントの部分を明確かつ簡潔に説明してください。

**提案する変更**
提案する具体的な変更内容を記載してください。

**関連するドキュメント**
関連するドキュメントやページへのリンクを記載してください。

**追加のコンテキスト**
ここに改善に関する他のコンテキストを追加してください。

  1. タスク (Task):
    • プロジェクト内の特定のタスクや作業項目を追跡するためのテンプレートです。タスクの詳細、目的、期限などを記載します。
task
---
name: タスク
about: プロジェクト内の特定のタスクや作業項目を追跡する
title: "[TASK] タスクの簡単な説明"
labels: task
assignees: ''

---

**タスクの説明**
タスクが何であるかを明確かつ簡潔に説明してください。

**目的**
このタスクの目的や達成したい結果を記載してください。

**作業項目**
- [ ] 作業項目1
- [ ] 作業項目2
- [ ] 作業項目3

**期限**
このタスクの完了期限を記載してください。

**追加のコンテキスト**
ここにタスクに関する他のコンテキストや関連情報を追加してください。

Nakajima.jsNakajima.js

コーディング規約を設定

コードの品質を担保するためにESLintの導入

https://qiita.com/fmai/items/2d27d394d31e994d3878

インストール

@nuxt/eslintモジュールを追加

npx nuxi module add eslint

ESLint StylisticをNuxtに設定する

nuxt.config.ts
  export default defineNuxtConfig({
    modules: [
      '@nuxt/eslint'
    ],
+   eslint: {
+     config: {
+       stylistic: true
+     }
+   }
  })

設定ファイル

// @ts-check
import withNuxt from './.nuxt/eslint.config.mjs'

export default withNuxt([
  {
    rules: {
      'no-console': 'warn', // console.logの使用を警告
      'no-unused-vars': 'error', // 未使用の変数をエラーとして報告
      'eqeqeq': 'error', // 厳密等価演算子(===)の使用を強制
      'curly': 'error', // すべての制御文に波括弧を強制
      'stylistic/semi': 'off', // stylistic/semiルールを無効化
      'quotes': ['error', 'single'], // シングルクォートの使用を強制
      'no-trailing-spaces': 'error', // 行末の空白を禁止
      'indent': ['error', 2], // インデント2スペース
      'comma-dangle': ['error', 'always-multiline'], // 複数行の場合は末尾カンマを強制
      'no-var': 'error', // varの使用を禁止
      'prefer-const': 'error', // 再代入がない場合はconstを強制
    },
    languageOptions: {
      globals: {
        browser: true,
        node: true,
        es6: true,
      },
      ecmaVersion: 2020,
      sourceType: 'module',
    },
  },
  {
    files: ['**/*.vue'],
    rules: {
      'vue/require-v-for-key': 'error', // v-forディレクティブでkeyの指定を強制
      'vue/no-use-v-if-with-v-for': 'error', // v-ifとv-forの同時使用を禁止
      'vue/html-indent': ['error', 2], // テンプレートのインデントを2スペースに
      'vue/html-closing-bracket-newline': ['error', {
        singleline: 'never', // 単一行の場合は改行なし
        multiline: 'always', // 複数行の場合は改行を強制
      }],
    },
  },
  {
    files: ['**/*.vue', '**/*.ts'],
    rules: {
      'no-console': ['error', { allow: ['error'] }], // 本番環境ではconsole.logを禁止
      '@typescript-eslint/no-explicit-any': 'error', // any型の使用を禁止
      '@typescript-eslint/explicit-function-return-type': 'error', // 関数の戻り値の型を明示的に指定
      '@typescript-eslint/no-unused-vars': 'error', // 未使用の変数をエラーとして報告
      '@typescript-eslint/consistent-type-definitions': ['error', 'interface'], // 型定義に一貫性を強制
    },
  },
  {
    files: ['**/components/**/index.vue'],
    rules: {
      'vue/multi-word-component-names': 'error', // コンポーネント名は複数単語を強制
    },
  },
])

ファイルパターン ルール名 設定内容
全体 no-console 'warn'(console.logの使用を警告)
全体 no-unused-vars 'error'(未使用の変数をエラーとして報告)
全体 eqeqeq 'error'(厳密等価演算子(===)の使用を強制)
全体 curly 'error'(すべての制御文に波括弧を強制)
全体 stylistic/semi 'off'(stylistic/semiルールを無効化)
全体 quotes ['error', 'single'](シングルクォートの使用を強制)
全体 no-trailing-spaces 'error'(行末の空白を禁止)
全体 indent ['error', 2](インデント2スペース)
全体 comma-dangle ['error', 'always-multiline'](複数行の場合は末尾カンマを強制)
全体 no-var 'error'(varの使用を禁止)
全体 prefer-const 'error'(再代入がない場合はconstを強制)
**/*.vue vue/require-v-for-key 'error'(v-forディレクティブでkeyの指定を強制)
**/*.vue vue/no-use-v-if-with-v-for 'error'(v-ifとv-forの同時使用を禁止)
**/*.vue vue/html-indent ['error', 2](テンプレートのインデントを2スペースに)
**/*.vue vue/html-closing-bracket-newline {'singleline': 'never', 'multiline': 'always'}(改行設定)
**/.vue, **/.ts no-console ['error', { allow: ['error'] }](本番環境ではconsole.logを禁止)
**/.vue, **/.ts @typescript-eslint/no-explicit-any 'error'(any型の使用を禁止)
**/.vue, **/.ts @typescript-eslint/explicit-function-return-type 'error'(関数の戻り値の型を明示的に指定)
**/.vue, **/.ts @typescript-eslint/no-unused-vars 'error'(未使用の変数をエラーとして報告)
**/.vue, **/.ts @typescript-eslint/consistent-type-definitions ['error', 'interface'](型定義に一貫性を強制)
/components//index.vue vue/multi-word-component-names 'error'(コンポーネント名は複数単語を強制)
Nakajima.jsNakajima.js

Vuetifyの導入

https://vuetifyjs.com/en/getting-started/installation/#get-started-with-vuetify-3

必要なライブラリのインストール

  • vuetifyvite-plugin-vuetify: VuetifyとそのViteプラグインを開発依存としてインストールしました。
  • @mdi/font: Material Design Iconsのフォントパッケージをインストールしました。
  • sass: Sass(CSSプリプロセッサ)をインストールしました。

vuetify

https://vuetifyjs.com/en/getting-started/installation/#installation

vite-plugin-vuetify

https://www.npmjs.com/package/vite-plugin-vuetify

sass

https://sass-lang.com/install/

導入コマンド

npm i -D vuetify vite-plugin-vuetify
npm i @mdi/font
npm i sass

設定ファイル

設定ファイル全体
nuxt.config.ts
import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  compatibilityDate: '2024-11-01',
  devtools: { enabled: true },
  build: {
    transpile: ['vuetify'],
  },
  modules: [
    (_options, nuxt) => {
      nuxt.hooks.hook('vite:extendConfig', (config) => {
        // @ts-expect-error
        config.plugins.push(vuetify({ autoImport: true }))
      })
    },
  ],
  vite: {
    plugins: [vuetify({ autoImport: true })],
    vue: {
      template: {
        transformAssetUrls,
      },
    },
  },
  plugins: [
    '~/plugins/vuetify.ts',
  ],
});

Nuxt.jsプロジェクトのビルド設定

vuetifyをトランスパイルするように指定しています。これは、vuetifyを使用する際に必要な設定です。

build: {
  transpile: ['vuetify'],
},

vuetify.tsプラグインを使用するための設定

plugins配列にプラグインのパスを追加することで、プロジェクト全体でそのプラグインを利用可能にします。

  plugins: [
    '~/plugins/vuetify.ts',
  ],

Viteの設定を拡張するためのフックを追加

vite:extendConfigフックを利用して、Viteの設定にvuetifyプラグインを自動インポートオプション付きで追加しています。
コメントでTypeScriptのエラーを無視する指示も含まれています。

  modules: ['@nuxt/eslint',
    (_options, nuxt): void => {
      nuxt.hooks.hook('vite:extendConfig', (config) => {
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-expect-error
        config.plugins.push(vuetify({ autoImport: true }));
      });
    },
  ],

Nuxt.jsプロジェクトでViteを使用する際の設定

特に、Vue.jsのテンプレートにおけるアセットURLの変換を行うための設定を行っています。transformAssetUrlsは、テンプレート内のアセットURLを適切に変換するためのオプションです。

  vite: {
    vue: {
      template: {
        transformAssetUrls,
      },
    },
  },

Nuxt.jsプロジェクトで使用するCSSファイルを指定

@mdi/font/css/materialdesignicons.cssはMaterial Design Iconsのフォントスタイルをプロジェクトに追加しています。
これにより、プロジェクト全体でこれらのスタイルを利用できます。

css: [
    '@mdi/font/css/materialdesignicons.css',
  ],

Vuetifyの設定をutilsディレクトリに追加

StoryBook導入時にプラグインの読み込み処理と一緒にすると不都合が起きるので今後の展開も考えて分けておく

細かい設定などは今後行なっていく

utils/vuetify.ts
import '@mdi/font/css/materialdesignicons.css';
import 'vuetify/styles';
import { createVuetify } from 'vuetify';
import * as components from 'vuetify/components';
import * as directives from 'vuetify/directives';

export default createVuetify({
  components,
  directives,
  theme: {
    defaultTheme: 'light',
  },
});

Vuetifyを呼び出すPluginsの設定

先ほどのutilsを読み込む処理を作成

plugin/vuetify.ts
import vuetify from '../utils/vuetify';

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(vuetify);
});
このスクラップは2ヶ月前にクローズされました
ログインするとコメントできます