クロコめも2。

ただのめもー

Vue2 + TypeScript2 を使ったサンプル

やりたいこと

vue.js2ではTypeScriptに対応したらしいのでどんなもんなのかを試したい。

試すものたち

  • vue.js 2.0.3
  • vuex
  • typescript 2.0.3
  • vue-ts-loader
  • av-ts
  • kilimanjaro

参考サイト

http://herringtondarkholme.github.io/2016/10/03/vue2-ts2/

作ってく

プロジェクトの作成

mkdir vue-ts-test
cd vue-ts-test
npm init -y
npm i -S vue typescript

ここまででpackage.jsonとnode_modulesが出来ている

STEP1:テンプレートのindex.htmlとちっちゃいVue

index.html

<div id="app"></div>
<script src="node_modules/vue/dist/vue.js"></script>
<script src="app.js"></script>

app.ts

declare var Vue: any
new Vue({
    el: '#app',
    render(h) {
        return h('h1', 'hello world')
    }
})

app.tsをコンパイルする

./node_modules/.bin/tsc app.ts

ブラウザでindex.htmlを開き"hello world"が表示されることを確認する

STEP2: webpack使って.vueファイルでコンポーネントを作る

npm i -D webpack vue-loader css-loader
npm i -D vue-ts-loader

webpack.config.js

module.exports = {
    entry: { app: './app.ts', },
    output: { filename: 'app.js' },

    // resolve TypeScript and Vue file
    resolve: {
        extensions: ['', '.ts', '.vue', '.js']
    },

    module: {
        loaders: [
            { test: /\.vue$/, loader: 'vue' },
            { test: /\.ts$/, loader: 'vue-ts' }
        ],
    },
    vue: {
        // instruct vue-loader to load TypeScript
        loaders: { js: 'vue-ts-loader', },
        // make TS' generated code cooperate with vue-loader
        esModule: true
    },
}

app.vue

<template>
<h1 @click="hello">hello world</h1>
</template>

<script>
export default {
    methods: {
        // type annotation!
        hello(): void {
            alert('hello world')
        }
    }
}
</script>

app.ts

declare var require: any

import Vue = require('vue')
var App = require('./app.vue').default

new Vue({
    el: '#app',
    components: { App },
    render: h => h('app')
})

ここでwebpackコマンドでコンパイルしてindex.htmlを表示したときにhello worldをクリックしてアラートが出ればOK

STEP3:もっと型を

npm i -S av-ts

app.vueを改造

<template>
<h1 @click="hello">hello {{name}}</h1>
</template>

<script>
// av-tsからVue関連のインポート
import {Vue, Component} from 'av-ts'

@Component
export default class App extends Vue {
name = 'kuroko'
// type annotation!
hello(): void {
    alert('hello ' + this.name)
}
}
</script>

ここでwebpackコマンドを叩いて動作確認

STEP4:Vuex導入

npm i -S kilimanjaro

store.tsの追加

import { create } from 'kilimanjaro'

var store = 
create({count: 0})
.getter('count', s => s.count)
.mutation('increment', s => () => s.count++)
.mutation('decrement', s => () => s.count--)
.done()

export default store

app.vue修正

<template>
<h1 @click="hello">hello {{name}} now count is {{count}}
<button @click.stop="add">+</button>
<button @click.stop="sub">-</button>
</h1>
</template>

<script>
// av-tsからVue関連のインポート
import {Vue, Component} from 'av-ts'
import {Vuex, getHelper} from 'kilimanjaro'
import store from './store'

const { getters, commit } = getHelper(store)

@Component
export default class App extends Vue {
@Vuex count: number = getters('count')
@Vuex add:Function = commit('increment')
@Vuex sub:Function = commit('decrement')
name = 'kuroko'
// type annotation!
hello(): void {
    alert('hello ' + this.name)
}
}
</script>

webpackコマンドを叩いて動作を確認する。

webpackコマンドを叩くとerror TS2304: Cannot find name 'Promise'.というエラーがいくつがでる。

単純にこのエラーを消したい場合はtsconfig.jsonのcompilerOptions.targetをes6に変えればエラーは出なくなる。

しかし、それが根本的な解決なのかはわからない。

次に確認したいこと

vue-cliのwebpack相当の構成でnpm run devデバッグしながらリアルタイムにプレビューできるようにするにはどうすればよいのかを調べたい。

が・・・ちょっとvue-cliで生成したプロジェクトを使って改造していくのは僕には歩幅が大きすぎて挫折したので小さくすすめる。

  • フォルダ構成を./srcとか./src/componentsとか./src/storeとかにわけれるようにしたい
  • sass使えるようにしたい
  • TypeScript -> ES5じゃなくてTypeScript -> ES6 (babelで) -> ES5にしたい。TypeScriptでES6チックにかければ不要か?
  • propなど今回使用していないvueの機能はどうやって書くのかを調べたい

今回のサンプルを作ってみてまだわからないこと

  • webpack.config.jsにあるvue:の指定は一体なんなのか?
  • vuexのgitterとかあんまり馴染みがない(ただの勉強不足)
  • tsconfig.jsonの中身全般。そもそもTypeScriptに関する知識が殆ど無い。