Nuxt.jsにTypeScriptを導入する手順まとめ


Nuxt.jsのプロジェクトにTypeScriptを導入するには、基本的に公式ドキュメント通りで問題ないのですが、ちょっとハマった箇所もあったので備忘録としてまとめておきます。

Nuxt.jsのバージョンは 2.11.0 、typescriptのバージョンは 3.7.4 です。

まずはNuxt.jsプロジェクトを作成

設定は適宜変更してください。

# プロジェクト作成
npx create-nuxt-app nuxt-ts-sample

> Generating Nuxt.js project in nuxt-ts-sample
? Project name nuxt-ts-sample
? Project description My astounding Nuxt.js project
? Author name itouuuuuuuuu
? Choose the package manager Npm
? Choose UI framework Element
? Choose custom server framework None (Recommended)
? Choose Nuxt.js modules Axios
? Choose linting tools ESLint
? Choose test framework None
? Choose rendering mode Universal (SSR)
? Choose development tools jsconfig.json (Recommended for VS Code)

typescript-buildをインストール

まずはtypescript-buildをインストールします。

npm install --save-dev @nuxt/typescript-build

次に nuxt.config.jsbuildModules の箇所に設定を追加します。

nuxt.config.js
export default {
  buildModules: ['@nuxt/typescript-build']
}

typescript-runtimeをインストール

npm install --save-dev @nuxt/typescript-runtime

インストール完了後、package.json のscriptsを、 nuxt から nuxt-ts に書き換えます。

package.json
"scripts": {
  "dev": "nuxt-ts",
  "build": "nuxt-ts build",
  "generate": "nuxt-ts generate",
  "start": "nuxt-ts start"
}

nuxt.config.ts の設定

nuxt.config.js のファイル名を nuxt.config.ts に変更します。
また、 extend(config, ctx) {} で型を指定しなければエラーになるため、指定してあげます。

nuxt.config.ts.diff
  build: {
-    extend(config, ctx) {}
+    extend(config: any, ctx: any) {}
  }

nuxt.config.ts に下記を追加します。

nuxt.config.ts
typescript: {
  typeCheck: true,
  ignoreNotFoundWarnings: true
}

eslint-config-typescriptをインストール

npm install --save-dev @nuxtjs/eslint-config-typescript

続いて、 package.jsonscriptlint を修正します。

package.json.diff
  "scripts": {
-    "lint": "eslint --ext .js,.vue --ignore-path .gitignore ."
+    "lint": "eslint --ext .ts,.js,.vue --ignore-path .gitignore ."
  }

eslintrc.jsextends に下記を追加します。
@nuxtjs がある場合は削除します。

eslintrc.js.diff
  extends: [
-   '@nuxtjs',
+   '@nuxtjs/eslint-config-typescript',
  ],

必要なファイルの追加

tsconfig.json ファイルをルート直下に作成します。

tsconfig.json
{
  "compilerOptions": {
    "target": "es2018",
    "module": "esnext",
    "moduleResolution": "node",
    "lib": [
      "esnext",
      "esnext.asynciterable",
      "dom"
    ],
    "esModuleInterop": true,
    "allowJs": true,
    "sourceMap": true,
    "strict": true,
    "noEmit": true,
    "baseUrl": ".",
    "paths": {
      "~/*": [
        "./*"
      ],
      "@/*": [
        "./*"
      ]
    },
    "types": [
      "@types/node",
      "@nuxt/types"
    ]
  },
  "exclude": [
    "node_modules"
  ]
}

Elementの問題を解決

UIフレームワークに Element を使用していない場合は、この項目は飛ばしても構いません。
Element を選んでいる場合、 npm run dev を行うと下記のようなエラーが出ます。

92:18 Interface 'NuxtApp' incorrectly extends interface 'Vue'.
  Types of property '$loading' are incompatible.
    Type 'NuxtLoading' is not assignable to type '(options: LoadingServiceOptions) => ElLoadingComponent'.
      Type 'NuxtLoading' provides no match for the signature '(options: LoadingServiceOptions): ElLoadingComponent'.
    90 | }
    91 | 
  > 92 | export interface NuxtApp extends Vue {
       |                  ^
    93 |   $options: NuxtAppOptions
    94 |   $loading: NuxtLoading
    95 |   context: Context

ℹ Version: typescript 3.7.4
ℹ Time: 16566ms

これを解決するため、tsconfig.jsoncompilerOptions"skipLibCheck": true を追加します。

tsconfig.json
"compilerOptions": {
  "skipLibCheck": true,
}

nuxt-property-decoratorをインストール

クラスを使用するために、nuxt-property-decoratorをインストールします。

npm install --save-dev nuxt-property-decorator

nuxt-property-decoratorを有効にするために、 tsconfig.jsoncompilerOptions"experimentalDecorators": true を追加します。

tsconfig.json
"compilerOptions": {
  "experimentalDecorators": true,
}

TypeScriptを使ってみる

pages/index.vuescript の箇所をTypeScriptで書いてみます。
~/components/Logo.vue をimportしている箇所に、.vue をつけることに注意してください。

pages/index.vue
<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'
import Logo from '~/components/Logo.vue'  // .vueを忘れずにつける
@Component({
  components: {
    Logo
  }
})
export default class extends Vue { }
</script>

ESLintの問題を解決

ESLint を使用している場合、 npm run dev を行うと下記のようなエラーが出ます。

  40:0  error  Parsing error: Using the export keyword between a decorator and a class is not allowed. Please use `export @dec class` instead.

   8 |   },
   9 | })
> 10 | export default class extends Vue { }
     | ^
  11 | 

✖ 1 problem (1 error, 0 warnings)

これを解決するために、 .eslintrc.jsbabel-eslint を削除します。

eslintrc.js
parserOptions: {
  parser: 'babel-eslint' // この行を削除
}

確認

http://localhost:3000/にアクセスして、下記の様な画面が確認できれば完了です!
お疲れ様でした!