144
108

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-02-06

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

144
108
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
144
108

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?