先日、Nuxt.js v2.6がリリースされましたね!
本バージョンからnuxt-ts
コマンドを使わずに、TypeScriptで記述できるようになったという特徴がありますが、create-nuxt-app
を叩いてからTypeScriptの環境を整えるために案外手間取ったので、記事にしておきます。
手っ取り早く始めたい人
こちらに以下で行う作業を済ましたものを上げてありますので、cloneしてご自由にお使いください。
若干typesync
やvue-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
をプロジェクト直下に作成します。
{
"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で書くように変更します。拡張子をjs
→ts
に修正する他、下の部分を修正すると設定オブジェクト自体にも型がつきます。
module.exports = {
...
}
import NuxtConfiguration from '@nuxt/config'
const nuxtConfig: NuxtConfiguration = {
...
}
export default nuxtConfig
また一点、undefined の可能性があるためにエラーを吐く箇所があるので、そちらも修正します。
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 に変更してみましょう。まずは、下のように変更してみます。
<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 がエラーを吐いてしまいます。
.vueファイルをうまく認識してないのかなと定義ファイルを作ってみたりしたのですが、実はこれはLogo.vue
に<script></script>
がないことが原因です。ですので、
<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
を次のように修正します。
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"
}
}
ここで、一番下のrules
でno-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 の設定を特にいじっていなければ、
<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>
と書いてある部分を
<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
の導入と使い方について書いていきたいと思います。
長文お読みいただきありがとうございました!もしなにか詰まった点やここが違うぞとかあれば、お気軽にコメントや編集リクエストしてください。