尝试在Nuxt.js v2.11.X中支持TypeScript和Express.js

image.png

在Nuxt.js v2.11.0 中支持TypeScript和Express.js。

主要环境

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

首先安装以上支持包

nuxt.config.ts 配置

下面是部分配置

1
2
3
4
5
6
import { Configuration } from '@nuxt/types'

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

然后添加 TypeScript 配置,在 nuxt.config.ts 的任意位置

1
2
3
4
typescript: {
    typeCheck: true,
    ignoreNotFoundWarnings: true
},

配置 serverMiddleware

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

这样config的设定就完成了
最终的完整配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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 的配置

1
2
3
4
5
"types": [
    "@types/node",
    "@nuxt/types",
    "@nuxtjs/axios"
]

不想使用axios的可以关掉axios。
这样tsconfig.json的配置就完成了。

tsconfig.json 的整体配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
{
  "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 的配置

配置启动脚本

1
2
3
4
5
6
7
8
"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"
},

Express 端的配置

server/index.ts

1
2
3
4
5
6
7
8
9
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

Server 端的 api
server/api/index.ts

1
2
3
4
5
6
7
8
9
import { Router } from 'express'

import text from './text'

const router = Router()

router.use(text)

export default router

Vue文件的脚本
pages/index.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<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-property-decorator。

这样设定就完成了。

总结

Nuxt.js的TypeScript支持感觉还不稳定,随着版本升级也总会有一些细节变化。
给人的印象是事情多。

以下是工程模板
https://github.com/baisheng/nuxt-express-ts