コンテンツにスキップ

静的コード分析とフォーマット⚓︎

静的コード分析とフォーマットには .editorconfig 、 ESLint 、 Stylelint 、および Prettier を使用します。 これらの設定はアプリケーション間で共通することが多いため、ルートプロジェクトに配置して共通化します。 下記の手順を実行後の設定ファイルの配置例を示します。

<root-project-name> ------ ルートプロジェクト
├ .editorconfig
├ eslint.config.ts
├ .stylelintrc.js
├ .prettierrc.json
├ tsconfig.json
└ <workspace-name> ------- ワークスペース/プロジェクト
  └ .stylelintrc.js

.editorconfigの追加⚓︎

.editorconfig を用いることで、 IDE 上で追加されるファイルにフォーマットルールを課すことが可能になります。 ブランクプロジェクトの作成 時に、各ワークスペースの直下に .editorconfig が自動的に作成されているので、ルートプロジェクトに移動してください。

Visual Studio Code の推奨プラグインである EditorConfig for Visual Studio Code を使用すると、以下のような設定が可能です。

  • エンコード
  • 改行コード
  • 文末に空白行を追加
  • インデントのサイズ
  • インデントの形式
  • 行末の空白を削除

開発時に統一する必要がある項目を .editorconfig に定義します。特に開発者によって差が出やすいエンコード、改行コードやインデントのサイズなどを定めておくと良いでしょう。

.editorconfig の設定には、自動的に適用されるものと、違反すると IDE のエディター上に警告として表示されるものがあります。詳細は 公式ドキュメント を参照してください。

.editorconfig の設定例

デフォルトでは上位のフォルダ階層に対して可能なかぎり .editorconfig ファイルを探索し、複数見つかった場合は上位の階層の設定を引き継ぎつつ、 キーが重複したプロパティについては下位の階層の設定でオーバーライドします。 しかし、 root = true が設定された .editorconfig が見つかった時点で探索を停止します。 そのため、意図せず同じリポジトリ内の別の .editorconfig を参照することがないように、ルートプロジェクトの .editorconfig には root = true を設定しておくとよいでしょう。

サンプルアプリケーションの .editorconfig
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
root = true

[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue,css,scss,sass,less,styl}]
charset = utf-8
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

end_of_line = lf
max_line_length = 100

Prettier⚓︎

Prettier は ブランクプロジェクトの作成 時にオプションとしてインストールしているため、追加でインストールする必要はありません。 ただし、設定ファイルがワークスペースの直下に作成されているため、ルートプロジェクトの直下に移動します。

Prettier の設定⚓︎

設定ファイル prettierrc.json で行います。

.prettierrc.json の設定例
1
2
3
4
5
6
{
  "$schema": "https://json.schemastore.org/prettierrc",
  "semi": false,
  "singleQuote": true,
  "printWidth": 100
}

既定の設定を上書きする場合は、設定値を記述します。 全ての設定可能な値は Options - Prettier を参照してください。また、設定方法は Configuration File - Prettier を参照してください。

一部の設定値は、既定で .editorconfig に記述している値が適用されます。したがって、.prettierrc.json では、 .editorconfig では設定できないもののみ設定すると良いでしょう。

ワークスペースの直下にいることを確認し、下記のコマンドを実行します。

npm run format

Prettier がルートプロジェクトの設定ファイルを自動的に認識し、正常に実行できることを確認してください。

ESLint⚓︎

ESLint および ESLint の実行に必要なパッケージは、 ブランクプロジェクトの作成 時にオプションとしてインストールしているため、追加でインストールする必要はありません。

ESLint の設定⚓︎

設定前の動作確認⚓︎

ESLint の設定は、設定ファイル eslint.config.ts で行います。 このファイルはインストール時にワークスペースの直下に自動的に追加されています。 ワークスペースの直下にいることを確認し、下記のコマンドを実行します。

npm run lint

設定の変更前に、 ESLint が正常に実行できることを確認してください。

設定例の確認⚓︎

コーディング規約 に沿うように設定を追加・変更します。 初期設定からの変更点をハイライトで示します。

サンプルアプリケーションの eslint.config.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { globalIgnores } from 'eslint/config'
import tseslint from 'typescript-eslint'
import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'
import pluginVue from 'eslint-plugin-vue'
import pluginVitest from '@vitest/eslint-plugin'
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import pluginCypress from 'eslint-plugin-cypress/flat'
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'

// To allow more languages other than `ts` in `.vue` files, uncomment the following lines:
// import { configureVueProject } from '@vue/eslint-config-typescript'
// configureVueProject({ scriptLangs: ['ts', 'tsx'] })
// More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup

export default defineConfigWithVueTs(
  // Lint 対象外とするファイルパスを列挙します。
  globalIgnores([
    '**/dist/**',
    '**/dist-ssr/**',
    '**/coverage/**',
    '**/src/generated/**',
    '**/mockServiceWorker.js',
  ]),

  // Vue.js 向けの推奨ルールを適用します。
  // .vue ファイルを Lint の対象とします。
  pluginVue.configs['flat/recommended'],

  // TypeScript + Vue.js 向けの型情報を使用した推奨ルールを適用します。
  // .vue .ts .mts .ts .vue ファイルを Lint の対象とします。
  vueTsConfigs.recommendedTypeChecked,

  // 型情報を使用した Lint を実行するために、 tsconfig ファイルを探すための設定をします。
  {
    languageOptions: {
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },

  // JavaScript ファイルに対しては、 型情報を使用した Lint は無効化します。
  {
    files: ['**/*.js'],
    extends: [tseslint.configs.disableTypeChecked],
  },

  // プロジェクトやワークスペースに固有のルールを適用します。
  // 必要に応じて対象のファイルやルールを設定します。
  {
    name: 'dressca-frontend/additional-rules',
    files: ['**/*.{ts,mts,tsx,vue}'],
    rules: {
      'no-console': 'warn',
      'no-alert': 'warn',
      '@typescript-eslint/no-floating-promises': [
        'error',
        {
          // 戻り値の Promise を await 不要とみなすメソッドを例外登録します。
          allowForKnownSafeCalls: [
            { from: 'package', name: ['push', 'replace'], package: 'vue-router' },
          ],
        },
      ],
    },
  },

  // Vitest 用のテストスイートに対して、 Vitest 推奨の Lint ルールを適用します。
  {
    ...pluginVitest.configs.recommended,
    files: ['**/src/**/__tests__/**/*'],
  },

  // Cypress 用のテストスイートに対して、Cypress 推奨の Lint ルールを適用します。
  {
    ...pluginCypress.configs.recommended,
    files: [
      '**/cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}',
      '**/cypress/support/**/*.{js,ts,jsx,tsx}',
    ],
  },
  // コードのフォーマットは Prettier で実行するので、 ESLint のフォーマットルールは無効化します。
  skipFormatting,
)

mono-repo 用の設定⚓︎

mono-repo 用に、設定ファイルの配置と設定を変更します。 eslint.config.ts を、ルートプロジェクトの直下に移動してください。 設定後のファイルの配置は下記の通りです。

<root-project-name> ------ ルートプロジェクト
├ eslint.config.ts
├ tsconfig.json
├ <workspace-name> ------- ワークスペース/プロジェクト

eslint.config.ts に、下記の設定を追加してください。

1
2
3
4
5
6
7
8
{
  languageOptions: {
    parserOptions: {
      projectService: true,
      tsconfigRootDir: import.meta.dirname
    },
  },
},

src フォルダーが eslint.config.ts の直下ではなくなるので、ワークスペース配下を検索するようにパスを修正します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
  ...pluginVitest.configs.recommended,
  files: ['**/src/**/__tests__/**/*'],
},
{
  ...pluginCypress.configs.recommended,
  files: [
    '**/cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}',
    '**/cypress/support/**/*.{js,ts,jsx,tsx}',
  ],
},

ルートプロジェクトの直下に、 eslint.config.ts 用の tsconfig.json ファイルを作成します。

eslint.config.ts 用の tsconfig.json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
  "extends": "@tsconfig/node22/tsconfig.json",
  "include": ["eslint.config.ts"],
  "compilerOptions": {
    "noEmit": true,
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "types": ["node"]
  }
}

ワークスペースの直下にいることを確認し、再度下記のコマンドを実行します。

npm run lint

ESLint がルートプロジェクトの設定ファイルを自動的に認識し、正常に実行できることを確認してください。

ESLint の実行時にエラーが発生する場合の対処

create-vue で作成されるデフォルトのアプリケーションには、 icons フォルダの配下の .vue ファイルのように、 <script> ブロックを持たない .vue ファイルが含まれます。 しかし、 <script> ブロックを持たない .vue ファイルに対して型情報を使用した Lint ルールの適用を試みると下記のようなエラーが発生します。 その場合は、該当する .vue ファイルに空の <script> ブロックを追加してください。

[eslint   ] Error: Error while loading rule '@typescript-eslint/await-thenable': You have used a rule which requires type information, but don't have parserOptions set to generate type information for this file. See https://typescript-eslint.io/getting-started/typed-linting for enabling linting with type information.
[eslint   ] Parser: vue-eslint-parser
[eslint   ] Note: detected a parser other than @typescript-eslint/parser. Make sure the parser is configured to forward "parserOptions.project" to @typescript-eslint/parser.
[eslint   ] Occurred while linting ...workspace-name\src\components\icons\IconCommunity.vue
1
<script setup lang="ts"></script>

適用ルールの変更⚓︎

Vue ファイルに適用するルールを、 flat/essential から flat/recommended に変更します。

1
pluginVue.configs['flat/recommended'],

TypeScript の型情報を使用するルールを使用するため、 vueTsConfigs.recommendedvueTsConfigs.recommendedTypeChecked に変更します。

1
vueTsConfigs.recommendedTypeChecked,

TypeScript 以外のファイルに対して、型情報を利用したルールの Lint を試みるとエラーが発生します。 そのため、 JavaScript ファイルに対して型情報を使用した Lint ルールを無効化するように、下記の設定を追加します。

1
2
3
4
5
6
import tseslint from 'typescript-eslint'

{
  files: ['**/*.js'],
  extends: [tseslint.configs.disableTypeChecked],
},

プロジェクト固有のルールを追加します。 ESLint は eslint.config.ts の先頭から設定の内容をマージするので、重複する設定は後から配置されたもので上書きされます。 そのため、プロジェクト固有のルールは、推奨ルールの設定よりも後に配置するように気を付けてください。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
  name: 'app/additional-rules',
  files: ['**/*.{ts,mts,tsx,vue}'],
  rules: {
    'no-console': 'warn',
    'no-alert': 'warn',
    '@typescript-eslint/no-floating-promises': [
      'error',
      {
        // 戻り値の Promise を await 不要とみなすメソッドを例外登録します。
        allowForKnownSafeCalls: [
          { from: 'package', name: ['push', 'replace'], package: 'vue-router' },
        ],
      },
    ],
  },
},

ESLint の対象外とするファイルを追加します。 サンプルアプリケーションでは、OpenAPI 仕様書からのクライアントコード生成 で自動生成するファイルと、 モックモードの設定 で追加するパッケージに由来するファイルは Lint 処理によって変更したくないので、 対象外にします。

1
2
3
4
5
6
7
globalIgnores([
  '**/dist/**',
  '**/dist-ssr/**',
  '**/coverage/**',
  '**/src/generated/**',
  '**/mockServiceWorker.js',
]),

その他の設定については 公式ドキュメント を参照してください。

ESLint Config Inspector で設定を可視化する

ESLint Config Inspector を使用することで、 ESLint の設定をブラウザー上で可視化できます。 ルールを変更・追加する際には、想定通りの変更が行われているか確認してください。 設定ファイルが存在するフォルダーの直下で下記のコマンドを実行することで、 ESLint Config Inspector を起動できます。

npx @eslint/config-inspector@latest

ESLint の実行⚓︎

ワークスペースの直下にいることを確認し、再度下記のコマンドを実行します。 ESLint が更新後の設定で正常に実行できることを確認してください。

npm run lint

Stylelint⚓︎

CSS ファイルおよび、 Vue ファイルの<template>ブロック、<style>ブロックに記述する CSS に対して静的解析をするため、 StyleLint を導入します。 ブランクプロジェクトの作成 時には追加されないため、手動でインストールする必要があります。

Stylelint のインストール⚓︎

ワークスペースの直下で下記のコマンドを実行してください。

npm install -D stylelint \
  stylelint-config-standard \
  stylelint-config-recommended-vue

Stylelint および、標準の設定や vue ファイルで使用する設定等をインストールします。 サンプルアプリケーションでは以下をインストールしています。

パッケージ名 使用目的
stylelint cssファイルの構文検証
stylelint-config-standard Stylelint の標準設定
stylelint-config-recommended-vue Stylelint の .vue ファイル向け推奨設定

Stylelint の設定⚓︎

ルートプロジェクトの直下に設定ファイル .stylelintrc.js を作成し、設定を記述します。

.stylelintrc.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
export default {
  extends: ['stylelint-config-standard', 'stylelint-config-recommended-vue'],
  rules: {
    'at-rule-no-unknown': [true, { ignoreAtRules: ['tailwind', 'define-mixin'] }],
  },
  ignoreFiles: ['dist/**/*'],
  overrides: [
    {
      files: ['**/*.vue'],
      customSyntax: 'postcss-html',
    },
  ],
}

各ワークスペースでは、ルートプロジェクトの設定ファイルを継承し、必要に応じて設定を追加します。

.stylelintrc.js
1
2
3
4
5
import stylelintConfigBase from '../.stylelintrc.js'

export default {
  extends: stylelintConfigBase
}
extends

既存の構成を拡張します。

rules

使用するルールを宣言します。

ignoreFiles

分析の対象外とするファイルまたはフォルダーを設定します。

overrides

特定のファイルにのみ別のルールを設定したい場合に使用します。

具体的な設定方法や設定値については 公式ドキュメント を参照してください。

デフォルトのアプリケーションに対する Stylelint の警告

create-vue で作成されるデフォルトのアプリケーションに対して Stylelint を実行すると、下記の警告が出力されて、動作確認が進められない場合があります。

src/assets/base.css
  25:1  ✖  Unexpected duplicate selector ":root", first used at line 2  no-duplicate-selectors

その場合は、 VS Code の拡張機能のサジェストに従って /* stylelint-disable-next-line no-duplicate-selectors */ を追加し、 対象箇所のルール違反を無視するようにして動作確認を続行してください。 ただし、実際のプロジェクトで使用するコードに対しては、ルール違反を無視する設定の利用はできるだけ避けて、警告に従ってコードを修正するようにしてください。

静的コード分析とフォーマットの実行⚓︎

各ワークスペースの package.json には ESLint および Prettier を実行するための scripts がデフォルトで定義されています。 CI での実行と個別の実行を可能にするため、下記のように変更します。

ESLint および Stylelint のオプション引数に --fix を、 Prettier のオプション引数に --write を設定しているため、自動で修正可能なものについては修正が実行されます。 自動で修正できないルール違反については、ターミナル上に結果が表示されます。 一方で、 :ci を付与したタスクではこれらのオプションを使用していないため、自動的に修正可能なルール違反であっても修正は実行されません。

サンプルアプリケーションの package.json
1
2
3
4
5
6
7
8
    "lint": "run-s eslint stylelint format --print-label",
    "lint:ci": "run-p eslint:ci format:ci stylelint:ci --print-label",
    "eslint": "eslint . --fix",
    "eslint:ci": "eslint .",
    "stylelint": "stylelint **/*.{vue,css} --fix",
    "stylelint:ci": "stylelint **/*.{vue,css}",
    "format": "prettier --write .",
    "format:ci": "prettier --check .",

ルートワークスペースの直下にいることを確認し、ワークスペースの設定 - スクリプトの定義 で定義した lint:ci を実行します。

npm run lint:ci:workspace-name

ESLint 、 Stylelint 、 Prettier が実行されることを確認してください。