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

Nuxt.js v2.9にTypeScriptとExpress.jsを対応してみた

Nuxt.js v2.9にTypeScriptとExpress.jsを対応しました

第一弾 Nuxt.js+Express.jsにTypeScriptを導入してみた

第二弾 Nuxt.js+Express.jsにTypeScriptを導入してみた(backpack.js編)

v2.9で上記じゃ使えなくなったので対応してみました。

主な環境

  • Nuxt.js v2.9.1
  • @nuxt/typescript-runtime
  • ts-node
  • @nuxt/typescript-build
  • vue-property-decorator

v2.8からの移行

公式サイト

上記サイトを参考に下記を実行していく。

yarn remove @nuxt/typescript
yarn add --dev @nuxt/typescript-build
yarn add @nuxt/typescript-runtime

完了したらnuxt.config.tsを変更していく

nuxt.config.tsの設定

下記の部分を

nuxt.config.ts
// old
import NuxtConfiguration from '@nuxt/config'

const nuxtConfig: NuxtConfiguration = {
}
module.exports = nuxtConfig

// new こちらに変更
import { Configuration } from '@nuxt/types'

const nuxtConfig: Configuration = {
  buildModules: ['@nuxt/typescript-build']
}
module.exports = nuxtConfig

次にTypeScriptの設定を任意の場所に記述

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

今までbackpack経由で処理していたものを今回はserverMiddlewareで読み込む

serverMiddleware: [
    { path: '/api', handler: '~/server/index.ts' }
]

これでconfigの設定は完了
最終的な全貌

nuxt.config.ts
import { Configuration } from '@nuxt/types'

const nuxtConfig: Configuration = {
  mode: 'universal',
  buildModules: ['@nuxt/typescript-build'],
  /*
  ** Headers of the page
  */
  head: {
    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' }
    ]
  },
  /*
  ** Customize the progress-bar color
  */
  loading: { color: '#fff' },
  /*
  ** Global CSS
  */
  css: [
  ],
  /*
  ** Plugins to load before mounting the App
  */
  plugins: [
  ],
  typescript: {
    typeCheck: true,
    ignoreNotFoundWarnings: true
  },
  /*
  ** Nuxt.js modules
  */
  modules: [
    // Doc: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios',
    '@nuxtjs/pwa',
    '@nuxtjs/eslint-module',
  ],
  /*
  ** Axios module configuration
  ** See https://axios.nuxtjs.org/options
  */
  axios: {
  },
  /*
  ** Build configuration
  */
  build: {
    /*
    ** You can extend webpack config here
    */
    extend(config, ctx) {
    }
  },
  serverMiddleware: [
    { path: '/api', handler: '~/server/index.ts' }
  ]
}
module.exports = nuxtConfig

tsconfig.jsonの設定

typesを下記に書き換えます。

tsconfig.json
// old
"types": [
    "@types/node",
    "@nuxt/vue-app"
]
// new 変更
"types": [
    "@types/node",
    "@nuxt/types",
    "@nuxtjs/axios"
]

axios使いたくない人はaxiosを消して大丈夫です。

これでtsconfig.jsonの設定は完了です。

全体像

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

package.jsonを設定

起動スクリプトを下記に変更します。

package.json
"scripts": {
    "lint": "eslint --ext .ts,.js,.vue --ignore-path .gitignore .",
    "precommit": "yarn run lint",
    "dev": "nuxt-ts",
    "build": "nuxt-ts build",
    "start": "nuxt-ts start",
    "generate": "nuxt-ts generate"
},

これでnuxt-tsから読み込みができます。

Express側の設定

下記の設定が必要なくなったので、けします。

server/index.ts
import config from '../nuxt.config'
config.dev = !(process.env.NODE_ENV === 'production')

async function start() {
  // Init Nuxt.js
  const nuxt = new Nuxt(config)

  const { host, port } = nuxt.options.server

  // Build only in dev mode
  if (config.dev) {
    const builder = new Builder(nuxt)
    await builder.build()
  } else {
    await nuxt.ready()
  }

  // Give nuxt middleware to express
  app.use(nuxt.render)

  // Listen the server
  app.listen(port, host)
  consola.ready({
    message: `Server listening on http://${host}:${port}`,
    badge: true
  })
}
start()

そうするとスッキリします。

server/index.ts
import express from 'express'
import bodyParser from 'body-parser'
import routes from './api'
const app = express()

app.use(bodyParser.json())
app.use(routes)

module.exports = app

apiのルートを別に記述してルートで読み込んでます。

server/api/index.ts
import { Router } from 'express'

import text from './text'

const router = Router()

router.use(text)

export default router

中間にルート管理をしてます。

Vueファイルのスクリプト

pages/index.vue
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
@Component({
  components: {
    Logo: () => import('~/components/Logo.vue')
  },
  async asyncData({ $axios }) {
    const data: any = await $axios.$get('api/test')
    return { text: data }
  }
})
class TopPage extends Vue {
}
export default TopPage
</script>

上記ではvue-property-decoratorを使用してます。

これで設定が完了しました。

まとめ

Nuxt.jsのTypeScript対応はなかなか安定してないので、今後もバージョンアップに伴い対応する
ことが多そうなイメージですね。

下記にソースをアップしたので参考になる箇所があれば参考にしてください。

ソース

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
ユーザーは見つかりませんでした