wordpressのテーマ開発にVue.jsを使う

vue.js wordpress
vue.js

この記事は後編です。
前編ではsassを導入しました。
前編をご覧になってから読み進めることをおすすめします。

Vue.jsはjQueryよりも優秀だと思う

フロントエンドのJavaScriptフレームワーク(ライブラリ)で代表的なものはAngularReact.js、そしてVue.jsでしょう。
それぞれに特徴があります。
Vue.jsは、とても軽量であり、既存のプロジェクトにも導入することが容易で、非常に使いやすいフレームワークです。
jQueryはDOMをばんばん書き換えますが、Domを直接いじることは現代において、アンチパターンとなりつつあります。
Domの操作はフレームワークに任せて、本来のコーディングに専念できる、その1つがVue.jsです。
WordpressにはjQueryが標準で組み込まれているので、これを使うのが一番手っ取り早いのですが、

おいおい冗談だろ。今どきjQueryなんて誰も使ってないよ。君はまずReactを学ぶべきだし、今は2016年だぜ。

という声が聞こえてきそうだし、やはりVue.jsのほうが慣れているのでこっちでやりたいという恣意的な理由です。

jQueryももちろん現役です

誤解ないように言っておくと、jQueryは未だに現役です。ちょっとした痒いところに手が届くし、手軽に使うには便利です。ただ、やっぱりVue.jsとかに慣れちゃうと戻れなくなっちゃうんですよねぇ。

Vue.jsをWordpressで使おう

最も手っ取り早いのはCDNですね。

<script src="https://unpkg.com/vue"></script>

と書くだけでVue.jsが利用できるようになります。
この程度であれば敢えて備忘録として残す必要もないのですが、今回はnpmを使ってVue.jsの環境を整えたいと思っています。

requireとか便利すぎて、普通のJavaScriptには戻れない

require 便利です。これなしに開発とか考えられない体になってしまいました。
簡単に説明すると、requireという魔法の言葉を使えば、世界中の人が作成した公開されているプログラムを簡単に自分のプログラムに組み込むことができます。
Wordpressでいう「プラグイン」みたいなものですね。

しかしこのrequire、npmで使えますが普通のブラウザでは使えない機能です。
時間の処理とかしたければmoment.jsが秀逸ですし、通信に関してはaxiosとか使いたいんです。

npm install vueではい!解決

前置きが長くなりましたが、そういったわけでVue.jsを導入していきます。
使用するプロジェクトは前回使用したmythemeです。
sassを導入する際に使用したサンプルをそのまま使っていきます。
またはこちらからダウンロードできます
mytheme

※テーマをダウンロードしたあとは、wordpressのテーマフォルダ(wp-content/theme/)において下さい。
そしてターミナルで回答したテーマディレクトリまで移動し、

npm install

と入力して下さい。これでgulpなどの必要なモジュールをダウンロードできます。

では、mythemeディレクトリで、以下のコマンドを入力します

npm install vue --save

これでvue.jsがnpmモジュールとして使えるようになりました

WebpackでJavaScriptを1個にまとめる

webpackというものが私にとってはちょっと分かりにくいのですが、要は複数のJavascriptファイルを連結して、1個のjavascriptファイル(bundle.jsという名前がよく使われます)にするというソフトです。
npm install 〜〜〜 でたくさんのライブラリを取り込んでも、最終的に出力されるのはbundle.jsという1個のファイルに纏めてくれるので、HTML側ではたった1行書くだけでJavaScriptのプログラムを読み込むことができるという仕組みのようです。

ベースとなるindex.phpを用意

では最初にHTMLの方を準備しましょう。
wordpressで必須なのはindex.phpというファイルです。まだ作成していないのでこれをmytheme直下にindex.phpファイルを作りましょう。
そして以下のコードをコピペします

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta charset="utf-8">
  <!-- style.scssが変換されてstyle.cssになったファイルを読み込みます -->
  <link rel="stylesheet" href="<?php echo get_stylesheet_uri(); ?>" media="screen">
  <?php wp_head(); ?>
</head>

<body <?php body_class(); ?>>
  <h1>my theme test</h1>
  <!-- webpackで出力されたJavascriptファイル(bundle.js)を読み込みます。Webpackの設定はこれからやります -->
  <script type="text/javascript" src="<?php echo get_template_directory_uri();?>/bundle.js"></script>
  <?php wp_footer();?>
</body>
</html>

これでWordpressに必要な素材が揃ったので、wordpressの設定からmythemeが選択できるようになるはずです。

Webpackの設定ファイルを用意

gulpではgulp.jsを作ったように、webpackでも同様にwebpack用の設定ファイルを用意します。mytheme直下にwebpack.config.jsというファイルを作成して、以下のコードを貼り付けて下さい

module.exports = {
  entry: './src/js/app.js',
  output: {
    path: __dirname,
    filename: './bundle.js'
  },
  module: {
    loaders: [
    ]
  },
  resolve: {
    alias: {
      vue: 'vue/dist/vue.js'
    }
  }
};

gulpと連動させる

webpack自体がタスクランナーの機能も持っているらしいのですが、今回はSassの変換にGulp、Javascriptの連結にWebpackを使用します。

このあたりは色々有りすぎて混乱します・・・。gruntとか、bowerとか、browseryとか・・・

gulpでwebpackを利用するために、npmモジュールを追加します

npm install webpack-stream --save-dev

webpack-streamを入れれば、自動でwebpackも入ってくるのでこれだけでOKです。

次にgulpfile.jsを開いて以下のように書き換えます

var gulp = require('gulp');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var plumber = require('gulp-plumber');

const webpackStream = require("webpack-stream");
const webpack = require("webpack");
const webpackConfig = require("./webpack.config");


gulp.task('convertToCss', function() {
  gulp.src('./src/scss/style.scss')
      .pipe(plumber())
      .pipe(sass())
      .pipe(autoprefixer())
      .pipe(gulp.dest('./'));
});
gulp.task('webpack',function(){
    return gulp.src('./src/js/*.js')
    .pipe(plumber())
    .pipe(webpackStream(webpackConfig, webpack))
    .pipe(gulp.dest('./'));
})

gulp.task('default', function() {
    gulp.watch('./src/scss/**/*.scss',['convertToCss']);
    gulp.watch('./src/js/app.js',['webpack']);
});

src/ディレクトリの中にjsディレクトリを作ります。その中にapp.jsファイルを作って起きましょう。
ここまでのディレクトリ構造は下図の通りです

ディレクトリ構造

ここまでの作業で、ディレクトリはこのような構成になるはずです

さぁ、これでgulpが、srcディレクトリ以下のファイルを監視してくれます。 src/js/app.jsが変わったらwebpackが起動して、bundle.jsをプロジェクト直下に吐き出してくれますし、src/scss以下が変わったらgulpがscssをcssに変換してくれるようになります。

app.jsを書き換えて動作確認

なにはともあれここまでお疲れ様です。きちんと動くかどうかが重要です。試しにプログラムを書いて見ましょう

src/js/app.jsを開いて、以下の通りに入力して下さい

var Vue = require('vue');
alert("welcome")

上書き保存をすると自動で、bundle.jsが出力されます。されましたか?無事うまく動くことをお祈りします。

では、wordpressで作成中のテーマに切り替えて、実際に動かしてみましょう

bundle.js動作確認

bundle.jsが正常に読み込まれていれば、このようにalertが表示されることでしょう

さぁ、npmでモジュールを取り込んでバンバン動かしましょう

ここまでの面倒な環境構築も、全てはnpmモジュールを使いたいがため・・・。
ここでは試しにmoment.jsを使ってみましょう。
gulpが起動している場合はControl + Cで停止できます。

そして

npm install moment --save

と打つだけでmoment.jsがnpmモジュールに追加されます。
この楽を一度覚えると、いちいち

<script type="text/javascript" src="xxxx"></script>

と書く開発に戻れない体になります。

では動作確認も兼ねた簡単なサンプルです
src/js/app.js

var Vue = require('vue');
var moment = require("moment");
//alert("welcome")

var vm = new Vue({
  el: '#app',
  data: {
    "now": moment().format('MMMM Do YYYY, h:mm:ss a'),
  }
})

そして、index.php

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta charset="utf-8">
  <!-- style loading -->
  <link rel="stylesheet" href="<?php echo get_stylesheet_uri(); ?>" media="screen">
  <?php wp_head(); ?>
</head>

<body <?php body_class(); ?>>
  <h1>my theme test</h1>
  <div id="app">
    <p>{{now}}</p>
  </div>

  <script type="text/javascript" src="<?php echo get_template_directory_uri();?>/bundle.js"></script>
  <?php wp_footer();?>
</body>
</html>

gulpがちゃんと起動してることを忘れないで下さいね。npm installとか打つためにgulpを止めると、再度実行するのをよく忘れます。

そして結果は次の通り

vue.jsとmoment.jsの実行結果

vue.jsとmoment.jsを使った簡単なサンプルの実行結果

ちゃんとmoment.jsの処理で日付が出力されていますね。
めでたしめでたし


この解説をするために作成したソースコードを、Github上にアップロードしておきますので、ほしい方はご自由にお使い下さい。