はじめに
Windowsでもできます。
これから何回かに分けてnpm initするところから、以下のようなことをできる環境を構築していきます。
- webpack4 + babel7 を使ってビルド
- vue-test-utils + jest を使ってテスト実行
- eslintを使って .vue と .js の構文チェック
今日の環境
- Windows10 Home
- node v8.11.1
- npm 5.8.0
プロジェクトディレクトリを作成
mkdir webpack_4_vue_introduction
移動してnpm init する
cd webpack_4_vue_introduction npm init -y
グローバルにインストール
npm install -g webpack webpack-cli babel
プロジェクトにインストール
npm install --save-dev webpack webpack-cli vue-loader vue-template-compiler babel-loader @babel/core @babel/cli @babel/preset-env
npm install --save vue vuex
今回webpack_4_vue_introductionディレクトリ内に作成するディレクトリ構造とファイル
./ ├── package-lock.json ├── package.json ├── src │ └── javascripts │ ├── entry_points │ │ └── first_page.js │ └── vue_applications │ ├── common │ │ ├── components │ │ │ ├── TextField.vue │ │ │ └── TextFieldUnit.vue │ │ └── modules │ │ ├── textField.js │ │ └── textFieldUnit.js │ └── pages │ └── first_page │ ├── App.vue │ └── store.js ├── webpack.config.js └── webroot └── first_page.html
ディレクトリと空のファイルを作成する
windowsの場合
windowsの場合は以下のコマンドでできると思います。
mkdir src\javascripts\entry_points mkdir src\javascripts\vue_applications\pages\first_page mkdir src\javascripts\vue_applications\common\components mkdir src\javascripts\vue_applications\common\modules mkdir webroot copy nul .babelrc copy nul webpack.config.js copy nul src\javascripts\entry_points\first_page.js copy nul src\javascripts\vue_applications\pages\first_page\App.vue copy nul src\javascripts\vue_applications\pages\first_page\store.js copy nul src\javascripts\vue_applications\common\components\TextFieldUnit.vue copy nul src\javascripts\vue_applications\common\components\TextField.vue copy nul src\javascripts\vue_applications\common\modules\textFieldUnit.js copy nul src\javascripts\vue_applications\common\modules\textField.js copy nul webroot\first_page.html
macの場合
mkdir -p src/javascripts/entry_points mkdir -p src/javascripts/vue_applications/pages/first_page mkdir -p src/javascripts/vue_applications/common/components mkdir -p src/javascripts/vue_applications/common/modules mkdir webroot touch .babelrc touch webpack.config.js touch src/javascripts/entry_points/first_page.js touch src/javascripts/vue_applications/pages/first_page/App.vue touch src/javascripts/vue_applications/pages/first_page/store.js touch src/javascripts/vue_applications/common/components/TextFieldUnit.vue touch src/javascripts/vue_applications/common/components/TextField.vue touch src/javascripts/vue_applications/common/modules/textFieldUnit.js touch src/javascripts/vue_applications/common/modules/textField.js touch webroot/first_page.html
.babelrcの編集
以下の通り記述します。
{ "presets": [ [ "@babel/preset-env", { "targets": [ "last 2 versions", "ie >= 11" ], "useBuiltIns": "usage", "corejs": 3 } ] ] }
webpack.config.jsの編集
以下の通り記述します。
const path = require('path'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); module.exports = { // entry point entry: { 'javascripts/first_page': './src/javascripts/entry_points/first_page.js', }, // 出力するパスは絶対パスで書きます output: { path: `${__dirname}/webroot/packed`, filename: (arg) => { return '[name].bundle.js' }, }, // webpack4はlordersではなくなりました module: { rules: [ // 拡張子.vueのファイルに対する設定 { test: /\.vue$/, use: [ { loader: "vue-loader", options: { loaders: { js: 'babel-loader', }, }, }, ] }, // 拡張子.jsのファイルに対する設定 { test: /\.js$/, exclude: /node_modules/, use: [ { loader: 'babel-loader', }, ] }, ] }, // デフォルトの設定値だけでは足りないことについて解決します resolve: { // モジュールを読み込むときに検索するディレクトリの設定 modules: [path.join(__dirname, 'src'), 'node_modules'], // importするときに省略できる拡張子の設定 extensions: ['.js', '.vue'], alias: { // importのファイルパスを相対パスで書かないようにsrcのrootを設定 '@': path.join(__dirname, 'src'), // 例えばmain.js内で `import Vue from 'vue';` と記述したときの`vue`が表すファイルパスを指定 'vue$': 'vue/dist/vue.esm.js' }, }, // プラグインを列挙 plugins: [ new VueLoaderPlugin() ], }
first_page.jsの編集
src/javascripts/entry_points/first_page.js
に以下の通り記述します。
import Vue from 'vue'; import Vuex from 'vuex' import store from '@/javascripts/vue_applications/pages/first_page/store' Vue.use(Vuex) import App from '@/javascripts/vue_applications/pages/first_page/App'; Vue.config.productionTip = false; new Vue({ el: '#app', store, template: '<App/>', components: { App }, });
App.vueの編集
src/javascripts/vue_applications/pages/first_page/App.vue
に以下の通り記述します。
<template> <div id="app"> <TextFieldUnit/> </div> </template> <script> import TextFieldUnit from '@/javascripts/vue_applications/common/components/TextFieldUnit' export default { name: 'app', components: { TextFieldUnit, }, } </script>
store.jsの編集
src/javascripts/vue_applications/pages/first_page/store.js
に以下の通り記述します。
import Vue from 'vue' import Vuex from 'vuex' import textFieldUnit from '@/javascripts/vue_applications/common/modules/textFieldUnit' Vue.use(Vuex) const state = () => { } const getters = { } const mutations = { } const actions = { } export default new Vuex.Store({ state, getters, mutations, actions, modules: { textFieldUnit, }, })
TextFieldUnit.vueの編集
src/javascripts/vue_applications/common/components/TextFieldUnit.vue
に以下の通り記述します。
<template> <section> <h1>TextFieldUnit</h1> <button @click="increment">count: {{ count }}</button> <TextField /> </section> </template> <script> import { mapState, mapMutations } from 'vuex'; import TextField from '@/javascripts/vue_applications/common/components/TextField'; export default { name: 'TextFieldUnit', components: { TextField, }, computed: { ...mapState('textFieldUnit', [ 'count', ]), }, methods: { ...mapMutations('textFieldUnit', [ 'setState' ]), increment() { this.setState({ key: 'count', value: this.count + 1, }); }, } } </script>
TextField.vueの編集
src/javascripts/vue_applications/common/components/TextField.vue
に以下の通り記述します。
<template> <section> <label>TextField: </label> <input :value="value" type="text" @input="onInput" > <div class="test-synced-text"> value: {{ value }} </div> </section> </template> <script> import { mapState, mapMutations } from 'vuex'; export default { name: 'TextField', computed: { ...mapState('textFieldUnit/textField', [ 'value', ]), }, methods: { ...mapMutations('textFieldUnit/textField', [ 'setState', ]), onInput(e) { this.setState({ key: 'value', value: e.target.value, }); }, }, } </script>
textFieldUnit.jsの編集
src/javascripts/vue_applications/common/modules/textFieldUnit.js
に以下の通り記述します。
import textField from '@/javascripts/vue_applications/common/modules/textField' const state = () => { return { count: 0, } } const getters = { } const actions = { } const mutations = { setState(state, payload) { state[payload.key] = payload.value; }, } export default { // strictとnamespacedをそれぞれtrueにしておきます。 strict: true, namespaced: true, state, getters, actions, mutations, modules: { textField, }, }
textField.jsの編集
src/javascripts/vue_applications/common/modules/textField.js
に以下の通り記述します。
const state = () => { return { value: 'defaultValue', }; } const getters = { } const actions = { } const mutations = { setState(state, payload) { state[payload.key] = payload.value; }, } export default { // strictとnamespacedをそれぞれtrueにしておきます。 strict: true, namespaced: true, state, getters, actions, mutations, }
first_page.htmlの編集
webroot/first_page.html
に以下の通り記述します。
<!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta charset="utf-8"> <title>vue-tutorial</title> </head> <body> <div id="app"> </div> <script type="text/javascript" src="packed/javascripts/first_page.bundle.js"></script> </body> </html>
package.jsonのscriptsに追記する
以下のような感じになるようにwatchを追記しました。
"scripts": { "watch": "webpack -d --watch", "test": "echo \"Error: no test specified\" && exit 1" },
watchしてトランスパイルしてみる
npm run watch
2020年3月14日追記
2020年3月14日にここまでの手順をやり直してみたところ、以下のようなエラーが出ました。
Can't resolve 'core-js/modules/es6.array.iterator'
core.jsのバージョンに関するエラーのようです。
以下のコマンドでインストールします。
npm install --save-dev core-js@3
もう一度トランスパイルしてみたらエラーは解消されていました。
npm run watch
ここまでやった段階のpackage.jsonの内容
{ "name": "vuex_design", "version": "1.0.0", "description": "vuexを使用する際のディレクトリ構造やコンポーネント設計のベースを作成します。", "main": "index.js", "scripts": { "watch": "webpack -d --watch", "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", "url": "git+https://github.com/motomichi-works/vuex_design.git" }, "keywords": [], "author": "", "license": "ISC", "bugs": { "url": "https://github.com/motomichi-works/vuex_design/issues" }, "homepage": "https://github.com/motomichi-works/vuex_design#readme", "devDependencies": { "@babel/cli": "^7.8.4", "@babel/core": "^7.8.7", "@babel/preset-env": "^7.8.7", "babel-loader": "^8.0.6", "core-js": "^3.6.4", "vue-loader": "^15.9.0", "vue-template-compiler": "^2.6.11", "webpack": "^4.42.0", "webpack-cli": "^3.3.11" }, "dependencies": { "vue": "^2.6.11", "vuex": "^3.1.3" } }
ページを見てみる
webroot/first_page.html
をブラウザで開いて確認します。
- JSエラーが出ないこと
- ボタンをクリックするとカウントアップすること
- テキストフィールドを編集するとその下のテキストも一緒に変化すること
今日はここまで。
次回はVuexで作っているアプリケーションをvue-test-utils + jestでテストできるようにしていきます。