1
/
5

VueとWebpackとJestの最初の一歩

VueとWebpackとJestの最初の一歩

Vue, node, webpackとJestで簡単なアプリを作ります。vue-cli
というツールを使ってテンプレートから始めるのが便利ですが、設定をはっきり理解して欲しいので、vue-cli
を使わずに少しずつスタックを作成します。Vue, node (express), webpack, jestを使います。ソースコード:https://github.com/lmiller1990/vue-webpack-jest-express

Node, babel, es6をインストール

まずは、babel
をインストールします。

yarn add --dev babel-preset-env babel-cli

babelは、ES6、ES7などの新しいJavaScriptの機能を一般的なブラウザがサポートしているES5にコンパイルするプログラムです。babelを使うため、.babelrc
というファイルを作成して、その中に以下の通り入力します。

{ 
  "presets": [
    "env"
  ]
}

package.json
を更新します。

"scripts": {
  "start": "babel-node src/index.js"
"

次が、srcというディレクトリを作成して、その中にserverというのを作ります。serverの中にindex.js, hello.jsというファイルを作成します。src/server/index.js

import hello from './hello'
console.log(hello())

src/server/hello.js

function hello() {
  return 'Hello from babel'
}
export default hello

yarn start
を実行します。Hello from babel
が表示されるはずです。表示されたら、babelを実行していることになります。

Jestをインストール

次は、Jestをインストールして、簡単なテストを書いてみましょう。

yarn add --dev jest

package.json
を更新します:

"scripts": {
  "start:" "babel-node src/server/index.js",
  "test": "jest"
}

src/server/hello.test.js
というファイルを作ります。.testがファイルネームに入ったら、Jestは自動に実行します。src/server/hello.test.js

import hello from './hello'
test('it says hello', () => {
  expect(hello()).toBe('Hello from babel')
})

yarn test
で実行します。

PASS  src/server/hello.test.js
  ✓ it says hello (5ms)

上記の内容が表示されるはずです。

Node (express)のサーバー

VueアプリをHTTPサーバーでサーブします。有名なExpress.jsを使います。

yarn add express

でインストールしてから、src/server/index.js
を更新します。

import express from 'express'
import renderApp from './renderApp'
const app = express()
app.get('/', (req, res) => {
  res.send(renderApp())
})
app.listen(3000, () => console.log('Listening on port 3000.'))

import hello from './hello'
はいりません。これは、Jestとbabelをちゃんと動かせるのを確認するためだけのものです。src/server/renderApp.js
を作ります。

const renderApp = () =>
`
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <h3>Hello from express</h3>
  <div id="app"></div>
</body>
</html>
`
export default renderApp

まだ作っていないけれど、<div id="app"></div>
をVueアプリを載せるタグです。yarn start
で実行します。ブラウザーでhttp://localhost:3000にアクセスすると、Welcome to expressが表示されるはずです。

Webpackでファイルをまとめる

Webpackでたくさんのファイルをまとめるモジュールバンドラーです。Webpackを使って、別のファイル(.vue, .jsなど)を全部一つのファイルにまとめて、クライアントに送ります。今まで、サーバーサイドコードだけを書きました。src/client
というディレクトリを作って、その中にindex.js
を作ります。index.js
が二つあります。一つ目は、サーバーの。もう一つは、クライアントのです。src/client/index.js
以下通り入力してください。

document.querySelector('#app').innerHTML = '<h3>Hello from webpack</h3>'

次は、ルートにwebpack.config.babel.js
を作ります。

import path from 'path'
import webpack from 'webpack'
export default {
entry: [
'./src/client/index.js'
],
output: {
filename: 'js/bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: `http://localhost:8000/dist/`,
},
module: {
rules: [
{
test: /\.vue$/, loader: 'vue-loader', options: {
loaders: {
js: 'babel-loader'
}
}
},
{
test: /\.js/, use: 'babel-loader', exclude: /node_modules/
}
]
},
devtool: 'source-map',
resolve: {
extensions: ['.js', '.vue']
},
devServer: {
port: 8000,
hot: true,
headers: {
'Access-Control-Allow-Origin': '*',
}
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
}

そして、webpackと必要なモジュールをインストールします。この設定は別の投稿で説明します 。devServer
というのは、まとめたbundle.jsをlocalhost:8000でアクセスできるサーバーでサーブします。これを使うと開発が早くなります。続きを見ればわかります。webpackとコンパイルに必要あモジュールをインストールします。nodemon
をインストールします。nodemon
を利用すれば、サーバーのファイルを手動で更新することなく、自動で再起動します。

yarn add --dev webpack webpack-dev-server babel-core babel-loader vue-loader css-loader


yarn global add nodemon

webpack
を実行してみます。dist/js/bundle.js
が作成されるはずです。最後の一行は、document.querySelector(‘#app’).innerHTML = ‘<h3>Hello from webpack</h3>’;
.そして、まとめたbundle.js
をアプリに表示しましょう。src/server/renderApp.js
を更新します。

<!-- ここまで同じ -->
<body>
<h3>Hello from express</h3>
<div id="app"></div>
<script src="http://localhost:8000/dist/js/bundle.js"></script>
</body>

package.json
にwebpackのタスクを追加します。start
も更新します。

"scripts": {
  "dev:wds": "webpack-dev-server --progress",
  "nodemon -e .vue,.js --ignore lib,files --exec babel-node src/server/index.js
}

一番目のターミナルでyarn start
を実行して、もう一つのターミナルでyarn dev:wds
を実行します。http://localhost:3000にアクセスと、Hello from expressHello from webpackが表示されるはずです。webpack-dev-serverから読み込んでいます。さらに、webpack-dev-server
を使っているので、src/client
のファイルを更新して、セーブすると自動にページがリフレッシュします。

Vueを統合します

Vueを統合しましょう。src/client/App.vue
を作ります。

<template>
  <div>
    <div class="greeting">    
      Hello Vue
    </div>
  </div>
</template>
<script>
  export default {
    name: 'App'
  }
</script>
<style scoped>
</style>

Vueで開発する際は、こういうテンプレートを作ることが多いです。私はこのモジュールを作って、vc App.vue
だけで以上のようなテンプレートが作成されます。src/client/index.js
を更新します。

import Vue from 'vue'
import App from './App'
new Vue({
  el: '#app',
  render: h => h(App),
  template: '<App />',
  components: { App  }
})

そして、Vueをインストールします。yarn add vueyarn dev:wds
をまた実行します。Hello Vueをブラウザに表示されるはずです。

JestでVueコンポーネントをテストする

Jestで、.vue
コンポーネントを簡単にテストできます。.vue
を読み込むために、jest-vue-preprocessor
を使います。yarn add --dev jest-vue-preprocessorそして、package.json
にjest
という新しい部分を追加します。

"jest": {
  "moduleFileExtensions": [
    "js",
    "vue"
  ],
  "transform": {
    "^.+\\.js$": "<rootDir>/node_modules/babel-jest",
    ".*\\.(vue)$": "<rootDir>/node_modules/jest-vue-preprocessor"
  }
}

src/client/App.test.js
を作ります。

import Vue from 'vue'
import App from './App.vue'
const doTest = (Component) => {
  const vm = new Vue({
    el: document.createElement('div'),
    render: h => h(Component)
})
expect(vm.$el.querySelector('.greeting')
  .textContent.trim()).toEqual('Hello Vue')
}
describe('App.vue', () => {
  it('should load a .vue file', () => {
    doTest(App)
  })
})

yarn test
で実行します。大丈夫なはずです。最後に、もう一つのテストを書いてみます。src/client/Clicker.vue
を作成します。src/client/Clicker.test.js
も。src/client/Clicker.vue

<template>
<div>
Count: {{ count }}
<button @click="clicked">Click me</button>
</div>
</template>
<script>
  export default {
    name: 'Tester',
    
    data() {
      return {
        count: 0
      } 
    },
  methods: {
      clicked() {
        this.count += 1
      }
    }
  }
</script>
<style scoped>
</style>

localhost:3000にアクセスして、ボタンを押してみましょう。count
が1ずつ増えます。テストをしましょう!

import Vue from 'vue'
import Tester from './Tester.vue'
const doTest = (Component) => {
  const vm = new Vue({
    el: document.createElement('div'),
    render: h => h(Component)
  })
vm.$el.querySelector('button').click()
 
   expect(vm.$children[0].count).toBe(1)
}
describe('Tester.vue', () => {
  it('should increment a counter when a button is clicked', () => {
    doTest(Tester)
  })
})

大丈夫なはずです。今度は、非同期に実行するコードなどをテストしたいです。ソースコード:https://github.com/lmiller1990/vue-webpack-jest-express