Edited at

TypeScript版Nuxtであるnuxt-tsに移行してJSファイルを駆逐した

(追記: 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.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使えるようになりました。


nuxtnuxt-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コマンドの初回実行時に作成してくれます。

主力されるのは以下になります。


tsconfig.json

{

"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だと以下のように書きますね。


nuxt.config.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を使うことで追記は不要にできます。


tsconfig.json

    "types": [

"@types/node",
+ "@types/webpack",
"@nuxt/vue-app"
]

そうするとnuxt.config.tsanyを使わず以下のように書けます:white_flower:


nuxt.config.ts

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.exportsrequireを使う必要があります。

この辺りは正式にNuxt.jsのmasterとしてマージされたときに変更されるなり、ドキュメント化されるなりすると思いますがハマりました。


@types/xxxdevDependenciesではなく、depencenciesに宣言する

package.jsonの話です。

前述のようにServer SideでもTypeScriptを使う4ため、tsconfig.jsonnuxt-ts start時でも必要になります。

ts-loaderだけで使っていたときはbuild時にのみ必要だったのでdevDependenciesとして宣言していました。

NODE_ENV=production環境でエラーになると思っていたら、tsconfig.jsonの処理で型定義が参照できないというエラーが起きていました。


Jest利用時

テスティングフレームワークはJest5を使っています。

JestでTypeScriptを使うためにts-jestを使っており、どうやらこれがtsconfig.jsonextendsnode_modules以下を使うとうまく参照してくれないようです。それでJest実行時だけ必要な設定が有効にならず、エラーとなっていました。

いまは冗長ですが、@nuxt/typescriptの設定を全展開しています。


Google App Engine Standard Environment Nodeで動かせない

SSRの実行環境としてGAE SE Nodeを使っています。

大したアプリでなかったので最弱のmachine_typeであるF1で動かしていたのですが、nuxt-tsだとF2以上でないと動きませんでした。

ワークロードが重くなっているようなので、この辺り正式リリース時には改善されることを期待したいです。


さいごに

紆余曲折ありましたが、いまでは本番環境で問題なく動いています:tada:

最終的にプロジェクト以下のJSファイルは以下2つのみにできました:exclamation:

$ fd -e js

babel.config.js
jest.config.js





  1. 正直イケてないので理想的には@types/nuxtに移動してほしいところ。monorepoの観点からいまはこうしているようですが… 



  2. TypeScriptでNuxtアプリケーションを作成する際の覚書 | Studio Andyなど 



  3. fix(ts): fix typescript default module compilerOption by kevinmarrec · Pull Request #4886 · nuxt/nuxt.js 



  4. ts-nodeを使って実現しています 



  5. まだv23.xを使っています。最新のv24だとTypeScript周りの使い方が変っており、まだうまく動かなかったため