フルスタックエンジニア目指して

エンジニアリングのことはもちろん、全然関係無い話もします。

Nuxt.jsのバージョンを1.3.0から2.0.0へ上げようとしたけど、tslintが導入できなかった話

結論から言うと、tslint関連の設定がうまくできなかったので、現在開発中のアプリのNuxt.jsのバージョンを2.0.0のアップデートは見送りました。
tslintを封印してまでNuxtのバージョンを2.0に上げる理由が見つからなかったというのも1つの理由です。

tslintがいらない方は問題なくアップデートできると思います(未確認)ので、早くNuxt 2.0を試したい方はtslintを導入しないことをオススメします。

作業手順

今回はNuxt.js + TypeScript(+ tslint)プロジェクトの作成手順で構築した環境を使用します。

なお、Nuxt.jsのリリースノートにざっくりと作業手順が載っているので、こちらを参考にしていきます。

まずはパッケージnuxt@^2.0.0をインストールします。

$ yarn add nuxt@^2.0.0

次に古いパッケージを確認します。

$ yarn outdated
yarn outdated v1.7.0
info Color legend : 
 "<red>"    : Major Update backward-incompatible updates 
 "<yellow>" : Minor Update backward-compatible features 
 "<green>"  : Patch Update backward-compatible bug fixes
Package       Current Wanted Latest  Package Type    URL                                                   
@nuxtjs/axios 5.3.1   5.3.2  5.3.2   dependencies    https://github.com/nuxt-community/axios-module#readme 
@types/node   9.6.31  9.6.31 10.10.1 devDependencies https://github.com/DefinitelyTyped/DefinitelyTyped.git
firebase      5.5.0   5.5.1  5.5.1   dependencies    https://firebase.google.com/                          
ts-loader     3.5.0   3.5.0  5.1.1   devDependencies https://github.com/TypeStrong/ts-loader               
typescript    2.9.2   2.9.2  3.0.3   devDependencies http://typescriptlang.org/  

nuxt 2.0ではWebpack4に対応しているので、Webpack3では3.x系までしか扱えなかったts-loaderも最新のバージョンが使用できます。
今回はすべてのパッケージをアップデートしておきます(個人プロジェクトなので気楽にね)

$ yarn upgrade --latest

nuxt 2.0ではcss-loaderが更新されているので、cssで画像等を指定している場合はパスの指定方法を以下のように修正する必要があります。

-    background-image: url(~/assets/images/hoge.png);
+    background-image: url(~assets/images/hoge.png);

うまく行かなかったことと試したこと

tslintがvueファイルでエラー

tslintが<template>...</template>の部分もチェックしてしまい、以下のような警告が出るようになってしまいました。

 warning  in ./pages/templates/new.vue?vue&type=script&lang=ts&

Module Warning (from ./node_modules/tslint-loader/index.js):
[7, 9]: statements are not aligned
[1, 1]: Type assertion using the '<>' syntax is forbidden. Use the 'as' syntax instead.
[21, 1]: Type assertion using the '<>' syntax is forbidden. Use the 'as' syntax instead.
[1, 1]: unused expression, expected an assignment or function call
[21, 1]: unused expression, expected an assignment or function call
[7, 2]: missing whitespace
[5, 2]: missing whitespace
[4, 4]: missing whitespace
[3, 13]: missing whitespace
[3, 14]: missing whitespace
[7, 13]: missing whitespace
[7, 14]: missing whitespace
[7, 18]: missing whitespace
[21, 2]: missing whitespace

https://github.com/wbuchwalter/tslint-loader/issues/105によるとtslint 3.6.0のエラーっぽい?ので、3.5.3にダウングレードしてみました。

$ yarn add tslint-loader@3.5.3
$ yarn run dev
 warning  in ./store/index.ts

Module build failed (from ./node_modules/tslint-loader/index.js):
TypeError: Cannot read property 'tslint' of undefined
    at resolveOptions (/path/to/project/node_modules/tslint-loader/index.js:24:47)
    at Object.module.exports (/path/to/project/node_modules/tslint-loader/index.js:139:17)

 @ ./store sync ^\.\/(?!-)[^.]+\.(mjs|js|ts|tsx)$
 @ ./.nuxt/store.js
 @ ./.nuxt/index.js
 @ ./.nuxt/client.js
 @ multi webpack-hot-middleware/client?name=client&reload=true&timeout=30000&path=/__webpack_hmr ./.nuxt/client.js

新たなエラーが。これは逆に3.6.0で修正されているようです。

https://github.com/wbuchwalter/tslint-loader/issues/99

念のため、さらにダウングレードしてみます。

$ yarn add tslint-loader@3.4.3
$ yarn run dev
Module build failed (from ./node_modules/tslint-loader/index.js):
Error: Tslint should be of version 4+
    at Object.module.exports (/path/to/project/node_modules/tslint-loader/index.js:121:11)

https://github.com/wbuchwalter/tslint-loader/issues/67によると、tslint-loader@3.4.3はtslintの5系以上に対応していないようです。

$ yarn add tslint@^4.0.0
$ yarn run dev
 warning  in ./store/index.ts

Module build failed (from ./node_modules/tslint-loader/index.js):
TypeError: Cannot read property 'tslint' of undefined
    at resolveOptions (/path/to/project/node_modules/tslint-loader/index.js:24:47)
    at Object.module.exports (/path/to/project/node_modules/tslint-loader/index.js:139:17)

 @ ./store sync ^\.\/(?!-)[^.]+\.(mjs|js|ts|tsx)$
 @ ./.nuxt/store.js
 @ ./.nuxt/index.js
 @ ./.nuxt/client.js
 @ multi webpack-hot-middleware/client?name=client&reload=true&timeout=30000&path=/__webpack_hmr ./.nuxt/client.js

3.4系でもうまくいかないですね・・・

その他トラブルシューティング

解決済のトラブルをいくつか紹介します。

TypeError: Cannot set property 'ts' of undefined

ts-loaderのバージョンが古い場合、または.tsxファイルをloaderの対象としていない場合に発生します。

tsxの設定に関してはhttps://github.com/nuxt-community/typescript-template/issues/48が参考になります。
私の場合は以下のような設定になっております。

this.nuxt.options.extensions.push("ts", "tsx")config.resolve.extensions.push('.tsx')を追加したり、test: /((client|server)\.js)|(\.tsx?)$/,のようにtsxもloaderの対象に入るように書き換えます。

You are using the runtime-only build of Vue...

You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

https://github.com/nuxt/nuxt.js/issues/1142を参考に以下の設定を追加することで、解決しました。

// nuxt.config.js
.
.
.
build: {
    extend(config) {
      config.resolve.alias['vue'] = 'vue/dist/vue.common'
    },
.
.
.

が、以降この設定を外しても再現しなくなりました。。。 謎です。

まとめ

なかなかNuxt 2.0の記事が見つからなかったので書いてみましたが、いかがでしたでしょうか。
結論うまくいきませんでしたが、こういう記事も需要あるかな・・・?

tslint-loaderがアップデートされてこの問題が対応されたらNuxt 2.0を試してみたいと思います。 アンテナを張っていきたいですね。

てか、フロント側の環境構築難しすぎー