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 express
Hello 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 vue
yarn 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