2017/10/18

vue2.5でTypeScript統合が改善されthisが推論されるようになったので試してみた

2017年10月13日に、ついにvue 2.5(コードネーム: Level E)がリリースされた。
今回のリリースの目玉はなんといってもTypeScript統合の改善! TypeScriptのアップデートにともない、vueの憎きオブジェクトリテラルの中で、なんと「thisが推論される」ようになったのだ!

vue 2.4以前は、vue-class-componentのデコレータを使いクラスベースで実装しなければならなかったのが、vue 2.5からはvue.jsのAPIのままTypeScriptで開発できるようになった。

vue 2.4以前のTypeScriptでの開発については、以下の記事を参照してほしい。

ということで、今回はvue 2.5を使ってTypeScriptで実装する方法をまとめる。
ついでにvue 2.4から2.5へのアップデート方法もまとめる。

実装するにあたりハマった点があるので、参考になればと思う。

vue 2.4以前のプロジェクトをアップデートした場合


vue 2.4からvue 2.5+TypeScriptへの移行方法は、以下の4つのライブラリをアップデートする必要がある。
# vue@2.5、vue-router@3.0
$ npm i -S vue vue-router

# vue-loader@13.3、vue-template-compiler@2.5
$ npm i -D vue-loader vue-template-compiler

あと、tsconfig.jsonも書き換えないといけない。(これでかなりハマった)
{
  // 略
  noImplicitThis: true
  // 略
}

noImplicitThisを有効にしないと、thisがanyのままで推論されないので注意!
あとはデコレータを取っ払って、クラスベースからvue標準のオブジェクトリテラルによる実装に変更すればOK!



vue 2.5でTypeScriptを使う方法

プロジェクトディレクトリを作成する

今回はvue-cliを使うが、各自の環境にあわせて行ってください。
$ vue init webpack my-project
$ cd my-project

$ npm install

TypeScriptで書けるようにwebpackの設定を変更

$ npm i -D typescript ts-loader

// tsconfig.json
{
  "compilerOptions": {
    "module": "es2015",
    "target": "es5",
    "sourceMap": true,
    // import Vue from 'vue'をするため
    "allowSyntheticDefaultImports": true,
    // モジュールの解決方法を変更するため
    "moduleResolution": "node",
    // Thisを推論させるため
    "noImplicitThis": true
  },
  "include": [
    "./src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

// ./build/webpack.base.conf.js
module.exports = {
  entry: {
    // 拡張子を.tsに変更
    app: './src/main.ts'
  },
  // 略
  resolve: {
    // .tsを追加
    extensions: ['.js', '.ts', '.vue', '.json']
    // 略
  },
  module: {
    rules: [
      // 略
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
    // ts-loaderを追加
      {
        test: /\.ts$/,
        loader: 'ts-loader',
        options: {
          appendTsSuffixTo: [/\.vue$/]
        }
      },
      // 略
    ]
  }
}
tsconfig.jsonでnoImplicitThisを有効にすることを忘れないでください。
でないと、私のようにハマってしまう。
※ ちなみに別ファイル(.js)にしたときに、computedがないとthisが推論されない件は未だ未解決

拡張子やlangをtsに変える

TypeScriptで実装するため、tsファイルを作ったり、scriptタグにlang="ts"を付与する。
<!-- .vueファイルの場合 -->

<template>
<!-- 略 -->
</template>

<script lang="ts">
// 略
</script>

// main.js → main.ts など

vueファイルにscriptもまとめたい場合は、VSCode+Veturがオススメ。
ただし、vueファイルだとtslintがうまく実行されなかったり、VSCodeの一部標準機能が使えなかったりするので、TypeScriptで開発する場合はファイルを分けたほうが良いかもしれない。

vueファイルをimportするために、型定義を作成する

// sfc.d.ts
declare module "*.vue" {
  import Vue from 'vue'
  export default Vue
}

ちなみにsfcは、Single File Component(s)の略。決してスーファミなどではない。


別にしたtsファイル内をVue.extendで書き換える

import Vue from 'vue';

export default Vue.extend({
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Hello'
    }
  },
  methods: {
    say () {
      window.alert(this.msg);
    }
  }
});

ちなみにvue単一ファイルで実装する場合は、Vue.extendがなくてもthisが推論される。
それはVeturが内部でオブジェクトリテラルをnew Vueでラップしてくれるためだ。


これでthisが推論され、vue開発の効率が格段にあがった!



サンプルリポジトリ

vue-class-componentブランチがvue2.4以前の実装方法。vue-2.5ブランチが新しい実装方法なので、参考にしてほしい。


VSCodeでtypescript2.5.3以上が入っていれば、tsでもjsでも強力に補完される。
ただ、tsはVuex周りがしんどいので、いま現在ではjsのままでも良い気がする。
(Vuexもstore内ならTypeScript万歳感があるのだが、ViewModelと連携しようとするとちょっとツライ)


以上

written by @bc_rikko

0 件のコメント :

コメントを投稿