今回初めてJavaScript(Babel)からTypeScriptへ移行したのですが、解決に悩んだ点をいくつかピックアップしてメモしておきます
(現在も移行中なので今後もあれば追記していきます)
対象はこちらの環境になります
VSCode
webpack v3.8
Vue.js v2.5
TypeScript v2.6
■ awesome-typescript-loader
を使った方が速いみたいだが、.vue
だと使えない
□ 対応
https://github.com/s-panferov/awesome-typescript-loader/issues/356
このissue見るとたぶん作業中
今は諦めてts-loader
にしてる
■ VSCodeの"prettier.trailingComma": "none"
にしてるのに.ts
の時だけカンマを付けてくる
□ 対応
tslint.json
のprettierの設定を見ていい感じにフォーマットしてくれるようにしたかったが、できなかったので
.eslintrc
のprettierを見てフォーマットするようにした
yarn add --dev prettier-eslint
"prettier.eslintIntegration": true
■ tslint-config-airbnb
を使ってるとWarningを出す
Warning: The 'no-boolean-literal-compare' rule requires type information.
Warning: The 'strict-boolean-expressions' rule requires type information.
□ 対応
type-checkが機能していない
tslint-loader
のオプションで以下を指定する
{
test: /\.ts$/,
use: [
{
loader: 'tslint-loader',
options: {
typeCheck: true // これ
}
}
],
exclude: /node_modules/
}
以下issueで言われているように、私もビルドスピードがだいぶ落ちたので今後使うか検討した方がいいかもしれません
https://github.com/wbuchwalter/tslint-loader/issues/76
■ webpackで設定したaliasをVSCodeが認識しない
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
}
パスは合ってるのに、VSCode上で以下エラーとなる
□ 対応
tsconfig.jsonに以下を追加する
webpackのaliasの設定と同じようにTypeScriptにも@/*
がsrc/*
であることを定義してあげるとVSCodeもちゃんと認識する
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
]
}
さらに.vue
であれば以下のようにVueの型定義も必要
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
上記の型定義でVueファイルというのを認識させるため、import時に.vue
を省略せずに書く
import Sample from '@/components/Sample.vue'
■ babel-plugin-istanbul
を使ってコードのカバレッジを出していたので、TypeScriptだと使えなくなった
□ 対応
awesome-typescript-loader
のオプションでuseBabel: true
をすればTypeScriptを変換する時にBabelをはさめるので、babel-plugin-istanbul
でも出せるのではないかと思ってる
でも今回はVueなので、上に述べたようにawesome-typescript-loader
が使えない
この後少し調べて、Reactですが公式の例で普通にts-loader
とbabel-loader
を使えてました
https://github.com/Microsoft/TypeScriptSamples/blob/master/react-flux-babel-karma/webpack.config.js
{
test: /\.ts$/,
use: [
{
loader: 'babel-loader'
},
{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/]
}
}
],
exclude: /node_modules/
}
"target": "es2015"
上記設定でちゃんとbabel-plugin-istanbul
を使ってカバレッジ出せました
■ TSLintのエラーにルール名が無いので、オフる時困る
□ 対応
コマンドだとformatでverboseを指定すれば出せる
tslint ./src/index.ts -t verbose
これをtslint-loader
でもできてほしいけど、オプション見ても出来なそうだった
今回はVSCodeを使っていたので、vscode-tslint-vue
というプラグインを入れて解決した
https://marketplace.visualstudio.com/items?itemName=prograhammer.tslint-vue
■ vueファイルのTSLintがバグる
以下のようにしてvueファイルでもTSLintを使えるようにしている
{
test: /\.vue$/,
use: [
{
loader: 'vue-loader',
options: {
loaders: {
ts: 'ts-loader!tslint-loader'
}
}
}
]
}
しかし、Lintエラーになっていないはずなのに、こんな警告が出る
□ 対応
最初文字化けして、Lintバグってんなって思ったけど、調べてみるとVueファイル内のTSコード以外の箇所が空行と認識されていた
以下の例だとscriptタグ内以外の部分が全て空行とみなされる
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<style>
</style>
<script lang="ts">
export default {
name: 'App'
}
</script>
↓つまり、tslint-loader
的には以下のようにみえている
export default {
name: 'App'
}
なので、連続した空白行があるよって警告が出る
結論、Vueのサポートが不十分ということだと思うので、以下のようにして回避した
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<style>
</style>
<script lang="ts">
/* tslint:disable:prettier */
/* tslint:enable:prettier */
export default {
name: 'App'
}
</script>
prettierを使ってない場合は、以下のルールになると思います、たぶん
/* tslint:disable:no-consecutive-blank-lines */
/* tslint:enable:no-consecutive-blank-lines */
tslint.jsonにno-consecutive-blank-lines: false
を書いてしまうと、全体的にこのルールをオフにしてしまうので、
上記のように特定箇所のみオフした方が良いでしょう
また、TSLintを使わず、typescript-eslint-parser
を使って、TypeScriptをESTree互換の形式にパースして、ESLintを使うのも良いかもしれません
■ VueファイルのtypeCheckをtrueにするとエラーになる
{
test: /\.vue$/,
use: [
{
loader: 'vue-loader',
options: {
loaders: {
ts: 'ts-loader!tslint-loader?typeCheck'
}
}
}
]
}
上記の設定でビルドすると、以下のエラーが出る
Ensure that the files supplied to lint have a .ts, .tsx, .d.ts, .js or .jsx extension.
□ 対応
tslint-loader
のtypeCheckがvue-loader
上でも動作するようになるのを待つか
以下プルリクであるように、linterOptions.typeCheckという機能がprivateだが用意されているので、これが公開されるのを待つか
https://github.com/palantir/tslint/pull/1403
その他の方法を考えるか
まだ解決策を考えれてないので、解決したら追記します