Help us understand the problem. What is going on with this article?

Nuxt.js v2.6でTypeScriptが書ける環境を構築する

More than 1 year has passed since last update.

先日、Nuxt.js v2.6がリリースされましたね!

本バージョンからnuxt-tsコマンドを使わずに、TypeScriptで記述できるようになったという特徴がありますが、create-nuxt-appを叩いてからTypeScriptの環境を整えるために案外手間取ったので、記事にしておきます。

手っ取り早く始めたい人

こちらに以下で行う作業を済ましたものを上げてありますので、cloneしてご自由にお使いください。
若干typesyncvue-property-decoratorなど、別記事で説明する(予定の)ライブラリも入っています。

まずは create-nuxt-app

とりあえずここでは、SPAとしてプロジェクト作成を進めていきます。また、LinterとPrettierは便利なので是非つけておきましょう。その他はお好みで。

typescript-testとしているところは、プロジェクト名なので適宜変更してください。

$ create-nuxt-app typescript-test
> Generating Nuxt.js project in /Users/hoge/Projects/typescript-test
? Project name typescript-test
? Project description My beautiful Nuxt.js project
? Use a custom server framework none
? Choose features to install Linter / Formatter, Prettier, Axios
? Use a custom UI framework none
? Use a custom test framework none
? Choose rendering mode Single Page App
? Author name dora1998
? Choose a package manager yarn

一旦ここで起動することを確認しておきましょう。

$ cd (project-name)
$ yarn run dev

TypeScript 仕様に変更する

Nuxt.js のバージョンを変える

デフォルトで入るパッケージのバージョンは古い(v2.4系)なので、まず最新のv2.6までバージョンアップします。
自分でpackage.jsonを書き換えてもいいのですが、ncuを使うのが楽です。ncuを実行して、最新バージョンを確認してみましょう。

$ ncu
Checking /Users/hoge/Projects/typescript-test/package.json
[====================] 22/22 100%

 ...(前略)
 nuxt                       ^2.4.0  →    ^2.6.1 
 ...(後略)

Run ncu -u to upgrade package.json

nuxtがv2.6以上になることを確認したら、これをpackage.jsonに反映しましょう。

$ ncu -u

node_modulesフォルダとyarn.lock(npmの場合はpackage-lock.json)を削除し、一旦今入れているパッケージを入れ直します。

$ rm -rf node_modules yarn.lock
$ yarn

パッケージの導入

まずは、TypeScript本体とNuxt.jsとの連携に必要なものから入れていきましょう。

$ yarn add typescript ts-node @nuxt/typescript

設定ファイルの作成・修正

tsconfig.json

次に、tsconfig.jsonをプロジェクト直下に作成します。

tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "types": [
      "@types/node",
      "@nuxt/vue-app"
    ],
    "paths": { "@/*": [ "./*" ], "~/*": [ "./*" ] },
    "target": "es5",
    "strict": true,
    "module": "es2015",
    "moduleResolution": "node"
  },
}

この中にあるpathsの設定がないと、

import Logo from '~/components/Logo.vue'

といったimport文が解決できないので注意しましょう。

nuxt.config.js → nuxt.config.ts

設定ファイルもTypeScriptで書くように変更します。拡張子をjstsに修正する他、下の部分を修正すると設定オブジェクト自体にも型がつきます。

nuxt.config.js
module.exports = {
 ...
}
nuxt.config.ts
import NuxtConfiguration from '@nuxt/config'

const nuxtConfig: NuxtConfiguration = {
 ...
}
export default nuxtConfig

また一点、undefined の可能性があるためにエラーを吐く箇所があるので、そちらも修正します。

nuxt.config.ts
  build: {
    extend(config, ctx) {
      if (ctx.isDev && ctx.isClient) {
        if (!config.module) return  // undefinedの場合、pushせずにreturnするように追加
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
    }
  }

コンポーネントをTypeScriptで書く

それでは、まず最初からあるindex.vueを TypeScript に変更してみましょう。まずは、下のように変更してみます。

index.vue
<script lang="ts">
import Vue from 'vue'
import Logo from '~/components/Logo.vue'

export default Vue.extend({
  components: {
    Logo
  }
})
</script>

なお、この書き方ではほぼjsと変わらないので、TypeScript の良さを活かせていると言えません。別記事で説明する(予定の)vue-property-decoratorを使うと、よりスマートに書くことができます。

ここで、このままだとビルドは通るのですが、VSCode の拡張機能である Vetur がエラーを吐いてしまいます。

nuxt_ts_1.png

.vueファイルをうまく認識してないのかなと定義ファイルを作ってみたりしたのですが、実はこれはLogo.vue<script></script>がないことが原因です。ですので、

Logo.vue
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({})
</script>

という風に追記してあげれば解決します。これで、エラーなく動くはずです。

ESLint で TypeScript を扱う設定

次に、TypeScript についても Lint が効くように設定します。TSLint を使う場合も多いかと思いますが、ここでは最近力を入れ始めた ESLint の方で TypeScript の Lint を行う方で設定したいと思います。

まずは、必要なパッケージをインストールしましょう。

$ yarn add -D @typescript-eslint/parser @typescript-eslint/eslint-plugin 

その後、.eslintrc.jsを次のように修正します。

.eslintrc.js
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true
  },
  parserOptions: {
    parser: '@typescript-eslint/parser',
    sourceType: 'module',
    project: './tsconfig.json',
    ecmaFeatures: { "legacyDecorators": true }
  },
  extends: [
    '@nuxtjs',
    'plugin:nuxt/recommended',
    'plugin:prettier/recommended',
    'prettier/vue',
    'prettier/@typescript-eslint'
  ],
  plugins: [
    'prettier',
    '@typescript-eslint'
  ],
  // add your custom rules here
  rules: {
    "no-unused-vars": "off",
    "@typescript-eslint/no-unused-vars": "error"
  }
}

ここで、一番下のrulesno-unused-vars@typescript-eslintのルールで上書きしていますが、これをしないとnuxt.config.ts

'NuxtConfiguration' is defined but never used.eslint(no-unused-vars)

というようなエラーが発生します。このように、ESLint 本家が持つルールの一部を TypeScript ファイルにそのまま適用してしまうと、不適切なエラーを吐くことがあります。このことについては、以下の記事が参考になります。

@typescript-eslint ことはじめ - teppeis blog

これでひとまず環境構築は終了です!

トラブルシューティング

index.vue で Lintエラー

ESLint(正確にはPrettier) がindex.vueについて、

/Users/hoge/Projects/typescript-test/pages/index.vue
  12:11  error  Replace `⏎··········href="https://nuxtjs.org/"⏎··········target="_blank"⏎·········` with `·href="https://nuxtjs.org/"·target="_blank"`  prettier/prettier
  16:9   error  Replace `>Documentation</a` with `··>Documentation</a⏎········`                                                                         prettier/prettier
  21:9   error  Replace `>GitHub</a` with `··>GitHub</a⏎········`                                                                                       prettier/prettier

といったようなエラーを吐くことがあります。整形スタイルが正しくないだけなら、普通は自動修正できるのですが、なぜかうまくいかないときがあります。
その場合は、ESLint と Prettier の設定を特にいじっていなければ、

index.vue
        <a
          href="https://nuxtjs.org/"
          target="_blank"
          class="button--green"
        >Documentation</a>
        <a
          href="https://github.com/nuxt/nuxt.js"
          target="_blank"
          class="button--grey"
        >GitHub</a>

と書いてある部分を

index.vue
        <a href="https://nuxtjs.org/" target="_blank" class="button--green">
          Documentation
        </a>
        <a
          href="https://github.com/nuxt/nuxt.js"
          target="_blank"
          class="button--grey"
        >
          GitHub
        </a>

と修正してあげれば、解消されるはずです。

環境は整えた…その次は?

これで、とりあえず Nuxt.js を TypeScript で書く最低限の環境が整いました!

しかし、せっかく TypeScript を導入したのですから、JS で書いていた時よりも簡潔に、また型安全に安全に書けたら嬉しいですよね。本記事もだいぶ長くなってきたので、開発を楽にする*vue-property-decorator*vuex-modules-decoratorの導入と使い方について書いていきたいと思います。

長文お読みいただきありがとうございました!もしなにか詰まった点やここが違うぞとかあれば、お気軽にコメントや編集リクエストしてください。

dora1998
Nuxt.js がマイブーム。Python / TypeScript あたりもよく書いています。
https://minoru.dev
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした