静的解析ツールのESlintを導入します。Prettierは今の所、なくても良いかな!?
Nuxt2でも導入していたのをVue3にも対応させるイメージです。
前回:Nuxt BridgeをNuxt3に移行。上に戻るボタンに対応

ESlintを導入

複数のサイトを参考にさせて頂きましたが、これだけで十分そう。

% yarn add -D eslint @nuxtjs/eslint-config-typescript \
  typescript eslint-plugin-nuxt@latest

package.json

-    "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .",
-    "lint": "yarn lint:js",
+    "lint": "eslint --ext \".js,.ts,.vue\" --ignore-path .gitignore .",
+    "lint:fix": "yarn lint --fix",
+    "eslint": "eslint",
+    "eslint:fix": "eslint --fix"

  "devDependencies": {
    "@nuxtjs/eslint-config-typescript": "^12.1.0",
    "eslint": "^8.54.0",
    "eslint-plugin-nuxt": "^4.0.0",
    "typescript": "^5.3.2",

tsが対象になっていなかったので追加と、yarn lintだとファイル指定ができない(パスが必須で”.”を入れている)ので、別途、yarn eslintを作りました。

.eslintrc.js

ちなみに.eslintrc.tsだと、設定ファイルがないと言われる。

ESLint couldn't find a configuration file. To set up a configuration file
 for this project, please run:
    npm init @eslint/config
module.exports = {
  root: true,
  env: {
    browser: true,
+    es2021: true,
    node: true
  },
  extends: [
    '@nuxtjs/eslint-config-typescript',
    'plugin:nuxt/recommended',
+    'plugin:vue/vue3-recommended'
  ],
  plugins: [
  ],
  // add your custom rules here
  rules: {
+    'prefer-promise-reject-errors': 'off',
    'vue/max-attributes-per-line': 'off',
    'vue/singleline-html-element-content-newline': 'off',
-    'prefer-promise-reject-errors': 'off',
+    'vue/multi-word-component-names': 'off',
+    'vue/no-reserved-component-names': 'off',
+    'vue/no-multiple-template-root': 'off',
+    '@typescript-eslint/no-var-requires': 'off'
  }
}

Vue3からtemplate直下に複数ルート入れられるようになったので、vue/no-multiple-template-rootを追加しました。

pages/index.vue
  1:1  error  Component name "index" should always be multi-word  vue/multi-word-component-names

-> これは変えられないので、offに変更しました。

pages/users/sign_in.vue
  82:5  error  Name "Form" is reserved in HTML  vue/no-reserved-component-names

-> vee-validateの <Form はそのまま使いたいので、offに変更しました。

nuxt.config.ts
  5:16  error  Require statement not part of import statement  @typescript-eslint/no-var-requires

-> 動的にファイルを切り替えているので、offに変更しました。

const environment = process.env.NODE_ENV || 'development'
const config = require(`./config/${environment}.ts`)

.eslintrc.js is treated as an ES … package.json contains “type”: “module” …

package.jsonに「”type”: “module”」を追加したら動かなくなりました。
拡張子を.cjsにするか、typeをcommonjsに変更すれば良いと。後者で対応します。

% yarn lint
Error [ERR_REQUIRE_ESM]: require() of ES Module /xxxx/.eslintrc.js
 from /xxxx/node_modules/@eslint/eslintrc/dist/eslintrc.cjs not supported.
.eslintrc.js is treated as an ES module file as it is a .js file
 whose nearest parent package.json contains "type": "module"
 which declares all .js files in that package scope as ES modules.
Instead either rename .eslintrc.js to end in .cjs, change the requiring code
 to use dynamic import() which is available in all CommonJS modules,
 or change "type": "module" to "type": "commonjs" in /xxxx/package.json
 to treat all .js files as CommonJS (using .mjs for all ES modules instead).

package.json

-  "type": "module",
+  "type": "commonjs",
% yarn lint
=============
WARNING: You are currently running a version of TypeScript
 which is not officially supported by @typescript-eslint/typescript-estree.

You may find that it works just fine, or you may not.

SUPPORTED TYPESCRIPT VERSIONS: >=4.3.5 <5.3.0

YOUR TYPESCRIPT VERSION: 5.3.2

Please only submit bug reports when using the officially supported version.
=============

eslintがサポートしているTypeScriptのバージョンを超えているとの事なので、
5.3.0未満に落とします。

package.json

-    "typescript": "^5.3.2",
+    "typescript": "<5.3.0",
% yarn install
% yarn lint   
✨  Done in 3.52s.

コードを修正(lint修正)

自動修正

% yarn lint --fix

手動修正

The "xxx" event has been triggered but not declared on `emits` option

emitが不要になったケース

components/Message.vue
  3:66  warning  The "update:alert" event has been triggered but not declared on `emits` option   vue/require-explicit-emits
  4:66  warning  The "update:notice" event has been triggered but not declared on `emits` option  vue/require-explicit-emits

-> v-alertの閉じるボタンの仕様が変わっているので修正しました。
 closable追加して、emitで値を消さなくても良くなった。

※閉じると再emitしても再表示されなくなってしまったので修正しました。

呼び出し元

-      <Message :alert.sync="alert" :notice.sync="notice" />
+      <AppMessage v-model:alert="alert" v-model:notice="notice" />

- import Message from '~/components/Message.vue'
+ import AppMessage from '~/components/app/Message.vue'

  components: {
-    Message,
+    AppMessage,

components/Message.vue -> components/app/Message.vue
※共通のはappとかに入れると解りやすくなりそうなので変更します。
 同様に共通のDestroyInfo.vue/Loading.vue/Processing.vue等のパスも変更。

-  <div v-if="alert || notice">
     <v-alert
-      v-if="alert" 
+      v-if="alert != null"
       type="error"
+      icon="mdi-alert"
-      dismissible
+      closable
+      class="mb-4"
-      @input="$emit('update:alert', null)"
+      @update:model-value="$emit('update:alert', null)"
     >
      {{ alert }}
     </v-alert>
     <v-alert
-      v-if="notice"
+      v-if="notice != null"
       type="info"
-      dismissible
+      closable
+      class="mb-4"
-      $emit('update:notice', null)
+      @update:model-value="$emit('update:notice', null)"
     >
       {{ notice }}
     </v-alert>
-  <div>

引き続きemitが必要なケース

components/ListSetting.vue
  123:18  warning  The "update:hiddenItems" event has been triggered but not declared on `emits` option  vue/require-explicit-emits

emitsオプションで宣言すればOK!

+  emits: ['update:hiddenItems'],

      this.$emit('update:hiddenItems', hiddenItems)

`<template v-for>` key should be placed on the `<template>` tag

components/ListDownload.vue
  122:27  error  `<template v-for>` key should be placed on the `<template>` tag  vue/no-v-for-template-key-on-child

keyをemplateの中に移動すればOK!

-                      <template v-for="(item, index) in items">
+                      <template v-for="(item, index) in items" :key="item.value">
                        <v-switch
                          :id="`download_output_item_${item.value.replace('.', '_')}`"
-                          :key="item.value"

コードを修正(template直下に複数ルート)

アラートは出ませんが、2行減らせて、インデントも1つ減らせるので、全体的に修正しておきます。
但し、divがなくなると、デザインが崩れる事があるのでご注意を。

※VSCodeにVeturを入れている場合、修正するとvue/no-multiple-template-rootのアラートが表示されます。
.eslintrc.jsの設定が効かない。Veturを無効にして、Volarを入れればOK!

例: pages/infomations/index.vue

<template>
-  <div>

-  </div>
</template>

例: components/app/Message.vue

<template>
-   <div v-if="alert != null || notice != null">

-  </div>
</template>

無駄にdivが出ないようにしていただけなので、削除しました。

例: components/infomations/Lists.vue

<template>
+  <template v-if="infomations != null && infomations.length > 0">

-  </div>
+  </template>
</template>

最初のtemplateにもv-if入れられるようです。
無視されるだけなので、divをtemplateに変える事にしました。

不要ファイルを削除

不要なファイルが見えてきたので、削除しておきます。

削除対象

assets/README.md
assets/variables.scss
components/README.md
layouts/README.md
middleware/README.md
pages/README.md
plugins/README.md
store/index.js
store/README.md
store/
.babelrc
.editorconfig
.babel.config.js
jest.config.js
jest.setup.js
jsconfig.json

空ファイルを追加

assets/.keep
middleware/.keep

ヘッダのタイトルが表示されないのと、エラーページがデフォルトのままになってしまったので、そちらの修正を行います。
Nuxt BridgeをNuxt3に移行。ヘッダタイトルとエラーページを修正

今回のコミット内容

origin#507 ESlintを導入、lint修正
origin#507 不要ファイルを削除
origin#507 ESlintのvue/no-multiple-template-rootをoffに変更+対象コード修正
origin#507 Messageが再表示されない。useApiRequest拡張。リファクタ。デザイン調整

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です