Tech note

備忘録

NuxtのTypeScript化 〜nuxt-property-decorator導入編〜

概要

nuxt-property-decoratorを使用して、NuxtをTypeScript化する。

環境

名称 Version
Node 14.10.1
Nuxt 2.14.5
Vue 2.6.12
TypeScript 3.9.7
Vuetify 2.3.10
nuxt-property-decorator 2.8.8

TypeScript化

パッケージをインストールする

npm i nuxt-property-decorator

vueファイルをTypeScript化する

TypeScript化前

<script>
export default {
  layout: "test",
  filters: {
    toUpperCase(val) {
      return val.toUpperCase();
    }
  },
  data() {
    return {
      testData: ""
    }
  },
  methods: {
    testMethod() {
      this.data = "test";
    }
  }
}
</script>

TypeScript化後

<script lang="ts">
import { Component, Vue } from "nuxt-property-decorator";

@Component({
  layout: "test",
  filters: {
    toUpperCase(val: string): string {
      return val.toUpperCase();
    }
  }
})
export default class extends Vue {
  private testData: string = "";

  private testMethod(): void {
    this.testData = "test";
  }
}
</script>

※Componentを何も使わない場合は、@Component({})と空で設定する。

nuxt.config.jsのTypeScript化

nuxt.config.jsをnuxt.config.tsにファイル名を変更する。
tsconfig.jsonにvuetifyの設定を追加する。
{
  "compilerOptions": {
    "target": "ES2018",
    "module": "ESNext",
    "moduleResolution": "Node",
    "lib": [
      "ESNext",
      "ESNext.AsyncIterable",
      "DOM"
    ],
    "esModuleInterop": true,
    "allowJs": true,
    "sourceMap": true,
    "strict": true,
    "noEmit": true,
    "experimentalDecorators": true,
    "baseUrl": ".",
    "paths": {
      "~/*": [
        "./*"
      ],
      "@/*": [
        "./*"
      ]
    },
    "types": [
      "@types/node",
      "@nuxt/types",
      "vuetify" ←この行を追加
    ]
  },
  "exclude": [
    "node_modules",
    ".nuxt",
    "dist"
  ]
}
buildプロパティのextendを使用している場合は、import文を追加してextendに型の設定をする。
import colors from 'vuetify/es5/util/colors'
import { Configuration } from 'webpack' ←この行を追加
import { Context } from '@nuxt/types' ←この行を追加

export default {
  /*
  ** Nuxt rendering mode
  ** See https://nuxtjs.org/api/configuration-mode
  */
  mode: 'universal',
  /*
  ** Nuxt target
  ** See https://nuxtjs.org/api/configuration-target
  */
  target: 'server',
  /*
  ** Headers of the page
  ** See https://nuxtjs.org/api/configuration-head
  */
  head: {
    titleTemplate: '%s - ' + process.env.npm_package_name,
    title: process.env.npm_package_name || '',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  /*
  ** Global CSS
  */
  css: [
  ],
  /*
  ** Plugins to load before mounting the App
  ** https://nuxtjs.org/guide/plugins
  */
  plugins: [
  ],
  /*
  ** Auto import components
  ** See https://nuxtjs.org/api/configuration-components
  */
  components: true,
  /*
  ** Nuxt.js dev-modules
  */
  buildModules: [
    '@nuxt/typescript-build',
    '@nuxtjs/vuetify',
  ],
  /*
  ** Nuxt.js modules
  */
  modules: [
    // Doc: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios',
  ],
  /*
  ** Axios module configuration
  ** See https://axios.nuxtjs.org/options
  */
  axios: {},
  /*
  ** vuetify module configuration
  ** https://github.com/nuxt-community/vuetify-module
  */
  vuetify: {
    customVariables: ['~/assets/variables.scss'],
    theme: {
      dark: false,
      themes: {
        dark: {
          primary: colors.blue.darken2,
          accent: colors.grey.darken3,
          secondary: colors.amber.darken3,
          info: colors.teal.lighten1,
          warning: colors.amber.base,
          error: colors.deepOrange.accent4,
          success: colors.green.accent3
        }
      }
    }
  },
  /*
  ** Build configuration
  ** See https://nuxtjs.org/api/configuration-build/
  */
  build: {
    extend(config: Configuration, ctx: Context) { ←型の設定を追加
    }
  }
}