CakePHP4にWebpack + Vue.jsを導入する

新規プロジェクトでバックエンドにCakePHP、フロントにはVue.jsを採用しようという話になりました。

CakePHPとwebpack+Vue.jsの導入する記事があまり少なかったので、導入する手順を私なりに記載しておきます。

※既にCakePHPはインストールされているものとします。

作成済みのプロジェクトに移動します。

package.jsonの作成

package.jsonの作成をしていきます。

$ npm init

いくつか質問されますが、基本的にはEnterを押して次に進めて問題ありません。

質問をすべて回答するとpackage.jsonが作成されます。

webpackのインストール

webpackをインストールしていきます。

$ npm install –save-dev webpack webpack-cli

vueのインストール

vueをインストールしていきます。

$ npm install –save-dev vue
$ npm install –save-dev vue-template-compiler
$ npm install –save-dev vue-loader

※後ほどbuildを行いますが、そのときに vue-loader”: “^17.~” だと、Cannot find module ‘vue/compiler-sfc’という

エラーが出ました。なので、私は、vue-loader”: “^15.9.8″に下げてインストールしています。

●package.json

“devDependencies”: {
    “vue”: “^2.6.12”,
    “vue-loader”: “^15.9.8”,
    “vue-template-compiler”: “^2.6.12”,
    “webpack”: “^5.68.0”,
    “webpack-cli”: “^4.9.2”
}

axiosを使用するため、axiosもインストールしておきます。package.jsonにaxiosを追加で入れます。

●package.json

“devDependencies”: {
    “vue”: “^2.6.12”,
    “vue-loader”: “^15.9.8”,
    “vue-template-compiler”: “^2.6.12”,
    “webpack”: “^5.68.0”,
    “webpack-cli”: “^4.9.2”,
    “axios”: “^0.21.4”
}

インストールを実行します。

$ npm install

webpackを実行するためのscriptを記述

buildするために以下を記述します。

※webpackのみのbuildだと、–modeをつけてくれと怒られます。

なので、–mode development,–mode productionを付けておきます。

package.json

  “scripts”: {
    “build”: “webpack –mode development”,
    “build:watch”: “webpack -w –mode development”,
    “build:prod”: “webpack –mode production”
  },

Vueのコンポーネントの作成

基本的にはプロジェクト内であればどこでもよいですが、今回はプロジェクト直下にresourcesを作成し、以下のようにしました。componentsの下に.vueを作成していくようにします。

●resources

resources
    -js
        -app.js
        -components
            -Hoge.vue

●resources/js/app.js

import Vue from ‘vue’
window.axios = require(‘axios’);
 
Vue.component(‘hoge-component’, require(‘./components/Hoge.vue’).default);
 
const app = new Vue({
     el: ‘#app’,
});

●resoures/js/components/Hoge.vue

<template>
    <div class=”message”>
        {{ message }}
    </div>
</template>
 
<script>
export default {
    data () {
        return {
            message: ‘HogeHoge’
        };
    }
};
</script>

その他にtemplate、webrootに必要な記述をしていきます。

●webroot/js/app.js

webroot/jsにapp.jsを作成しておきます。特に記述はいりません。

※npm run buildしたときにoutputされるファイルになります。

●template/Hoge/index.php

<hoge-component></hoge-component>

Contollerも併せて作成しておいてください。

●templates/layout/default.php

<div id=”app”> idにappを付与していきます 。

また、/webroot/js/app.jsは<body></body>の最後に読み込ませるようにしておきます。

<body>
    <div id=”app”>
        <main class=”contents”>
            <?php echo $this->Flash->render(); ?>
            <?php echo $this->fetch(‘content’); ?>
     </main>
    </div>
    <?php echo noh( $this->Html->script([ ‘app’]) ); ?>
</body>

webpack.config.jsの作成

プロジェクト直下にwebpack.config.jsを作成して、以下を記述します。

エントリーポイントは作成した/resources/js/app.jsになります。

build時の出力ファイルが/webroot/js/app.jsになります。

●webpack.config.js

const webpack = require(‘webpack’);
 
module.exports = {
  entry: ‘./resources/js/app.js’,
  output: {
    path: __dirname + ‘/webroot’,
    publicPath: ‘/’,
    filename: ‘js/app.js’
  },
  module: {
    rules: [
        {
            test: /\.vue$/,
            loader: ‘vue-loader’
        },
    ]
  },
  resolve: {
    alias: {
        ‘vue$’: ‘vue/dist/vue.esm.js’,
    }
  }
};

npm run build とコマンドを打ちます。すると、

Module Error (from ./node_modules/vue-loader/lib/index.js):vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.

とエラーになりました。Pluginが必要みたいなので以下を記述しておきます。

●webpack.config.js

const webpack = require(‘webpack’);
const VueLoaderPlugin = require(‘vue-loader/lib/plugin’); // 追加
 
module.exports = {
  entry: ‘./resources/js/app.js’,
  output: {
    path: __dirname + ‘/webroot’,
    publicPath: ‘/’,
    filename: ‘js/app.js’
  },
  module: {
    rules: [
        {
            test: /\.vue$/,
            loader: ‘vue-loader’
        },
    ]
  },
  plugins: [
    new VueLoaderPlugin() // 追加
  ],
  resolve: {
    alias: {
        ‘vue$’: ‘vue/dist/vue.esm.js’,
    }
  }
};

Babelの導入

.babelrcの作成

プロジェクト直下に.babelrcを作成し、以下を記述します。

.babelrc

{
    “presets”: [
         “@babel/preset-env”
    ]
}

Babelのインストール

$ npm install –save-dev babel-loader @babel/core
$ npm install @babel/preset-env –save-dev

●webpack.config.js

webpack.config.jsにbabelの設定を追加します。

const webpack = require(‘webpack’);
const VueLoaderPlugin = require(‘vue-loader/lib/plugin’);
 
 
module.exports = {
  entry: ‘./resources/js/app.js’,
  output: {
    path: __dirname + ‘/webroot’,
    publicPath: ‘/’,
    filename: ‘js/app.js’
  },
  module: {
    rules: [
        {
            test: /\.vue$/,
            loader: ‘vue-loader’
        },
        {
            test: /\.js$/,
            exclude: /node_modules/,
            use: {
                loader: ‘babel-loader’,
                options: {
                    presets: [‘@babel/preset-env’],
                },
            },
        },
    ]
  },
  plugins: [
    new VueLoaderPlugin()
  ],
  resolve: {
    alias: {
        ‘vue$’: ‘vue/dist/vue.esm.js’,
    }
  }
};

npm run buildができれば完了です!!!

※2022/5/26追記

vue3に変えたことやライブラリのバージョンを変えたことで、いくつか変更がありました。

●resources/js/app.js
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
import Vue from ‘vue’
window.axios = require(‘axios’);

Vue.component(‘hoge-component’, require(‘./components/Hoge.vue’).default);

const app = new Vue({
el: ‘#app’,
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
import { createApp } from ‘vue’
window.axios = require(‘axios’);

// コンポーネントのimport
import SampleComponent from ‘./components/Sample.vue’;

const app = createApp({
components: {
‘sample-component’: SampleComponent
}
}).mount(‘#app’);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
コンポーネントの呼び出し方が変更
(※axiosについては試していないので実際に使うときに動かなければ修正します)

●webpack.config.js
const VueLoaderPlugin = require(‘vue-loader/lib/plugin’);

const { VueLoaderPlugin } = require(‘vue-loader’);

new VueLoaderPlugin()

new VueLoaderPlugin(),
new webpack.DefinePlugin({
VUE_OPTIONS_API: true,
VUE_PROD_DEVTOOLS: true,
}),

‘vue$’: ‘vue/dist/vue.esm.js’,

‘vue’: ‘@vue/runtime-dom’,
‘vue’: ‘vue/dist/vue.esm-bundler.js’,

この投稿へのコメント

コメントはありません。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

この投稿へのトラックバック

トラックバックはありません。

トラックバック URL