(追記: 2019年3月27日)
v2.5.0が3月21日にリリースされました。
このバージョンではこの記事の内容はあわないところがでてきます。
私が使用しているGAE環境ではv2.5がいまのところ動かないので、その不具合が解消されたらv2.5についての記事を別に書こうと思っています。
(追記: 2019年4月5日)
v2.6.0がリリースされたので、予告通り別記事を投稿しました。
待望のNuxt v2.6リリース! 〜 nuxt-tsからの移行編〜
Nuxt.js v2.4.0のTypeScript対応
Nuxt v2.4.0 is finally here 🎉
— Nuxt.js (@nuxt_js) January 28, 2019
Official TypeScript support, smart prefetching and many more features & bug fixes.https://t.co/Ljf29xYvXi
つい先日Nuxt.js v2.4.0がリリースされました。
以下リリースブログからの抜粋。
TypeScript support has landed!
In order to run Nuxt with TypeScript, we created a new distribution, called nuxt-ts.
⚠️ Experimental: We are waiting for your feedback to keep improving it and breaking changes can occur without a semver major release. However, all changes will be documented properly
まだ実験段階ですがTypeScriptのサポートが強化されました。
TypeScriptサポートのNuxtを使うためにはnuxt-tsを使う必要があります。 nuxtでもts-loader
不要でTypeScript使えるようになりました。
nuxt
とnuxt-ts
との違い
-
nuxt
コマンドではなくnuxt-ts
コマンドを使う必要がある-
build
,start
など
-
- Run TimeがTypeScriptをサポート
-
nuxt.config.js
ではなくnuxt.config.ts
を書く必要がある -
module
,serverMiddleware
もTypeScriptで書ける
-
-
build.useForkTsChecker
がデフォルトでtrue
より詳しくはTypeScript Support - Nuxt.jsを参照してください。
tsconfig.json
tsconfig.json
がまだ存在しない場合は、nuxt-ts
コマンドの初回実行時に作成してくれます。
主力されるのは以下になります。
{
"extends": "@nuxt/typescript",
"compilerOptions": {
"baseUrl": ".",
"types": [
"@types/node",
"@nuxt/vue-app"
]
},
}
@nuxt/typescript
内のtsconfig.jsonを参照しているのと、types
に@nuxt/vue-app
が追加されています。
このため@types/xxx
の自動インクルードが無効化されてしまうので、@types
を追加した場合は自分で明示的にtsconfig.json
にも追記する必要がでてきます。1
types
ではなく、typeRoots
を以下のようにすることで明示的に追記する必要なくできます。
{
"extends": "@nuxt/typescript",
"compilerOptions": {
"baseUrl": ".",
"typeRoots": [
"./node_modules/@types",
"./node_modules/@nuxt/vue-app/types"
]
},
}
type safeにnuxt.config.ts
を書く
nuxt.config
内のbuild.extendを書くときの話です。
JSだと以下のように書きますね。
export default {
build: {
extend (config, { isClient }) {
// Extend only webpack config for client-bundle
if (isClient) {
config.devtool = '#source-map'
}
}
}
}
このときextend
の引数をtype safeにしたい場合、型定義をimport
する必要があります。
第一引数はWebpackのConfigurationなのであらかじめWebpackの型定義をinstallしておきます。
$ yarn add @types/webpack
tsconfig.json
にも追記します。
typeRoots
を使うことで追記は不要にできます。
"types": [
"@types/node",
+ "@types/webpack",
"@nuxt/vue-app"
]
そうするとnuxt.config.ts
はany
を使わず以下のように書けます
import {Configuration} from 'webpack'
import {Context} from '@nuxt/vue-app'
export default {
build: {
extend (config: Configuration, { isClient }: Context) {
// Extend only webpack config for client-bundle
if (isClient) {
config.devtool = '#source-map'
}
}
}
}
nuxt-ts
移行時にハマった3つのこと
以下、既存プロジェクトでnuxt-ts
化したときにハマったことを書いてみました。
躓いている方がいれば参考にしてください。
前提として既存プロジェクトでは、すでにTypeScriptを使っており、よくあるts-loader
の設定を自前で2書いていました。
Custom Server Middleware
前述したようにnuxt-ts
を使えばserverMiddleware
もTypeScriptで書けます。
既存プロジェクトでCookie処理をCustom Server Middlewareとして記述していたのですが、それをTypeScriptに移行するときにハマりました。
結論としてServer SideではCommonJSで書く必要があるということです。
nuxt-ts
コマンドは中で@nuxt/typescriptを使っています。実装をみるとcompilerOptions.module: "commonjs"
が指定されています。この変更はv2.4.2で入りました。3なので、module.exports
とrequire
を使う必要があります。
この辺りは正式にNuxt.jsのmasterとしてマージされたときに変更されるなり、ドキュメント化されるなりすると思いますがハマりました。
@types/xxx
はdevDependencies
ではなく、depencencies
に宣言する
package.json
の話です。
前述のようにServer SideでもTypeScriptを使う4ため、tsconfig.json
はnuxt-ts start
時でも必要になります。
ts-loader
だけで使っていたときはbuild
時にのみ必要だったのでdevDependencies
として宣言していました。
NODE_ENV=production
環境でエラーになると思っていたら、tsconfig.json
の処理で型定義が参照できないというエラーが起きていました。
Jest利用時
テスティングフレームワークはJest5を使っています。
JestでTypeScriptを使うためにts-jestを使っており、どうやらこれがtsconfig.json
のextends
でnode_modules
以下を使うとうまく参照してくれないようです。それでJest実行時だけ必要な設定が有効にならず、エラーとなっていました。
いまは冗長ですが、@nuxt/typescript
の設定を全展開しています。
Google App Engine Standard Environment Nodeで動かせない
SSRの実行環境としてGAE SE Nodeを使っています。
大したアプリでなかったので最弱のmachine_type
であるF1で動かしていたのですが、nuxt-ts
だとF2以上でないと動きませんでした。
ワークロードが重くなっているようなので、この辺り正式リリース時には改善されることを期待したいです。
さいごに
紆余曲折ありましたが、いまでは本番環境で問題なく動いています
最終的にプロジェクト以下のJSファイルは以下2つのみにできました
$ fd -e js
babel.config.js
jest.config.js
-
正直イケてないので理想的には
@types/nuxt
に移動してほしいところ。monorepoの観点からいまはこうしているようですが… ↩ -
fix(ts): fix typescript default module compilerOption by kevinmarrec · Pull Request #4886 · nuxt/nuxt.js ↩
-
まだv23.xを使っています。最新のv24だとTypeScript周りの使い方が変っており、まだうまく動かなかったため ↩