(追記: 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周りの使い方が変っており、まだうまく動かなかったため ↩