今このブログのSPA化を進めていますが、 結局jsのフレームワークはvue.jsを使うことにしました。

Vue.js

個人的な感想ですが、 ReactやAngularは覚えなきゃいけないことが多くて学習コストが高い。 riot.jsやvue.jsは直感的に書けることが多く、サクッと書ける。

と言いますか、vue.jsに惚れました。これはなかなか良い。 ということで、npmを使って開発する方法をまとめました。

ディレクトリ構成

./project
  ├──src/
  │    ├── index.html
  │    └── js/
  │        └── bundle.js
  └──js-dev/
       ├── node_modules/
       ├── package.json
       ├── src
       │   └── app.js
       └── webpack.config.js

js-devディレクトリ配下で開発をして、 webpackでコンパイルされたものがsrc/js/bundle.jsに入ります。 index.htmlでbundle.jsを読み込むことで、ブラウザで表示されます。

js-dev/package.json

{
  "name": "wordpress-vuejs-spa",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack --watch"
  },
  "author": "m.hirasaki",
  "license": "ISC",
  "devDependencies": {
    "css-loader": "^0.28.7",
    "html-loader": "^0.5.1",
    "style-loader": "^0.19.0",
    "vue-loader": "^13.5.0",
    "vue-template-compiler": "^2.5.9",
    "webpack": "^3.10.0"
  },
  "dependencies": {
    "vue": "^2.5.9"
  }
}

js-dev/webpack.config.js

// output.pathに絶対パスを指定する必要があるため、pathモジュールを読み込んでおく
const path = require('path');

module.exports = {
  // エントリーポイントの設定
  entry: './src/app.js',
  // 出力の設定
  output: {
    // 出力するファイル名
    filename: 'bundle.js',
    // 出力先のパス
    path: path.join(__dirname, '../src/js/')
  },
  module: {
    loaders: [
      { test: /\.vue$/, loader: 'vue' },
    ]
  },
  // パッケージ
  resolve: {
    //extensions: ['*node_modules/vue/dist/vue.js', '.js', '.jsx']
    alias: {
       'vue': 'vue/dist/vue.js'
    }
  }
};

js-dev/src/app.js

var Vue = require('vue')

window.onload = function () {
  var app3 = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue!'
    }
  })
};

src/index.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta charset="utf-8">
<meta name="description" content="">
<meta name="author" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/style.css">
<!--[if lt IE 9]>
<script src="//cdn.jsdelivr.net/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<link rel="shortcut icon" href="">

<script type="text/javascript" src="js/bundle.js" charset="utf-8"></script>
</head>
<body>
  <div id="app">
    {{ message }}
  </div>
</body>
</html>

インストール

$ npm install

あとはindex.htmlにブラウザでアクセスすれば、 「Hello Vue!」と表示されるかと思います。

やっている最中、いくつかエラーが出たのですが、 以下のように解決しました。

また、このコマンドで開発時の自動コンパイルができます。

$ npm run dev

エラー① TypeError: Vue is not a constructor

TypeError: Vue is not a constructor #5470

webpackのresolveに以下のように追記して解決した。

resolve: {
  //extensions: ['*node_modules/vue/dist/vue.js', '.js', '.jsx']
  alias: {
     'vue': 'vue/dist/vue.js'
  }
}

エラー② bundle.js:713 [Vue warn]: Cannot find element: #app

[Vue warn]: Cannot find element

単純に、DOMがロードされるまでにjsが動作していたので見つからなかった。

app.jsに、windows.onloadを追加して解決した。

var Vue = require('vue')

window.onload = function () {
  var app3 = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue!'
    }
  })
};

よくわからなかったやつ

Module build failed: TypeError: this._init is not a function

ERROR in ./src/js/app.vue
Module build failed: TypeError: this._init is not a function
    at Object.Vue$3 (./blog/js-dev/node_modules/vue/dist/vue.runtime.common.js:4616:8)
 @ ./src/app.js 3:17-40
ERROR in ./src/app.js
Module not found: Error: Can't resolve '@/components/MyComponent' in './js-dev/src'
 @ ./src/app.js 2:17-72
[Vue warn]: Vue is a constructor and should be called with the `new` keyword
ERROR in ./src/app.js
Module not found: Error: Can't resolve './src/app.vue' in './js-dev/src'
 @ ./src/app.js 2:17-41

vueファイルを作成して、それをloaderと通してコンパイルに混ぜ込もうとした時に出るっぽい。 色々試しましたが、結局解決ができませんでした。 誰かわかる人がいたら教えてください。

追記

テンプレートがありました。 vuejs-templates

参考

以下のサイトを参考にさせていただきました、ありがとうございます!