概要
export default class Hoge extends Vue {}
のクラス定義をミスった際に不思議な挙動をしたので、覚書。
教訓
Vueファイルをコピーしたらクラス名を変更し忘れないようにしよう。
GitHubに利用したプロジェクトをUPしています。実際に試してみたい方どうぞ^^
https://github.com/kai-kou/vue-js-typescript-component-class-name
準備
ここではDockerを利用して環境構築していますが、ローカルで構築してもらってもOKです。
> mkdir 任意のディレクトリ > cd 任意のディレクトリ > vi Dockerfile > vi docker-compose.yml
Dockerfile
FROM node:10.8.0-stretch RUN npm install --global @vue/cli WORKDIR /projects
docker-compose.yml
version: '3' services: app: build: . ports: - "8080:8080" volumes: - ".:/projects" tty: true
> docker-compose up -d > docker-compose exec app bash
コンテナ内
> vue create app Vue CLI v3.0.1 ? Please pick a preset: Manually select features ? Check the features needed for your project: Babel, TS, Linter, Unit ? Use class-style component syntax? Yes ? Use Babel alongside TypeScript for auto-detected polyfills? Yes ? Pick a linter / formatter config: TSLint ? Pick additional lint features: Lint on save ? Pick a unit testing solution: Mocha ? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files ? Save this as a preset for future projects? No ? Pick the package manager to use when installing dependencies: (Use arrow keys) ❯ Use Yarn Use NPM
コンテナ内
> cd app
これで環境が整いました。
検証
新しくコンポーネントを追加します。
> touch src/components/Hoge.vue
src/components/Hoge.vue
<template> <div>hoge</div> </template> <script lang="ts"> import { Component, Vue } from 'vue-property-decorator'; @Component export default class Hoge extends Vue {} </script>
追加したコンポーネントをコピーしてもうひとつ追加します。
> cp src/components/Hoge.vue src/components/Hoge2.vue
あえて、export default class Hoge extends Vue {}
のHoge
をそのままにしておきます。
src/components/Hoge2.vue
<template> <div>hoge2</div> </template> <script lang="ts"> import { Component, Vue } from 'vue-property-decorator'; @Component export default class Hoge extends Vue {} </script>
もとからあるApp.vueで追加したコンポーネントを利用します。
src/App.vue
<template> <div id="app"> <hoge/> <hoge2/> <img alt="Vue logo" src="./assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/> </div> </template> <script lang="ts"> import { Component, Vue } from 'vue-property-decorator'; import HelloWorld from './components/HelloWorld.vue'; import Hoge from './components/Hoge.vue'; import Hoge2 from './components/Hoge2.vue'; @Component({ components: { HelloWorld, Hoge, Hoge2, }, }) export default class App extends Vue {} </script> (略)
ブラウザで確認してみます。
> yarn serve yarn run v1.9.2 $ vue-cli-service serve INFO Starting development server... Starting type checking and linting service... Using 1 worker with 2048MB memory limit 98% after emitting CopyPlugin DONE Compiled successfully in 67085ms 7:53:09 AM No type errors found No lint errors found Version: typescript 3.0.3, tslint 5.11.0 Time: 28863ms App running at: - Local: http://localhost:8080/ It seems you are running Vue CLI inside a container. Access the dev server via http://localhost:<your container's external mapped port>/ Note that the development build is not optimized.
はい。
追加コンポーネントが表示されました。
追加した2つのコンポーネントのClass名はHoge
で同じなのですが、特にエラー出力はありません。
単体テストを追加してみます。
> touch tests/unit/App.spec.ts
tests/unit/App.spec.ts
import { expect } from 'chai'; import { shallowMount } from '@vue/test-utils'; import App from '@/App.vue'; import HelloWorld from '@/components/HelloWorld.vue'; import Hoge from '@/components/Hoge.vue'; import Hoge2 from '@/components/Hoge2.vue'; describe('App.vue', () => { it('Hogeコンポーネントが表示されるか', () => { const wrapper = shallowMount(App, {}); wrapper.is(App); expect(wrapper.findAll(HelloWorld)).to.length(1); expect(wrapper.findAll(Hoge)).to.length(1); expect(wrapper.findAll(Hoge2)).to.length(1); }); });
テスト実行してみます。
> yarn test:unit WEBPACK Compiled successfully in 1101ms MOCHA Testing... App.vue 1) Hogeコンポーネントが表示されるか 0 passing (1s) 1 failing 1) App.vue Hogeコンポーネントが表示されるか: AssertionError: expected { Object () } to have a length of 1 but got 2 + expected - actual -2 +1 at Context.<anonymous> (dist/webpack:/tests/unit/Hoge.spec.ts:15:1) MOCHA Tests completed with 1 failure(s)
oh。
Hogeコンポーネントが2つとみなされました。
そりゃあ、そうクラス定義しているので、そうですね。
けど、単体テストを書かないと気が付かずにそのまま。。。になりかねないので、 皆さま、うっかりミスには気をつけましょう^^
参考
Vue.js+TypeScriptで開発するときの参考記事まとめ
https://cloudpack.media/43084