1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CakePHP4 で Vue.js ( Laravel-Mix ) を使えるようにして docker-compose で動くようにする

Last updated at Posted at 2020-03-14

CakePHP4 を docker-compose で動くようにする

の続きです。

CakePHP4 のプロジェクトから Vue.js を使えるようにします。
Vue.js は Laravel-Mix を使って導入します。

この記事でわかること

事前準備

僕の Mac の各種バージョンは以下です。

バージョン
docker Docker version 19.03.5, build 633a0ea
docker-compose docker-compose version 1.25.4, build 8d51620a
CakePHP4 4.0.4
Vue.js 2.6.11
laravel-mix 5.0.1

手順の流れの説明

Laravel の仮プロジェクト作り、そこから必要なファイルをコピーします。
その後、CakePHP4 のディレクトリ構成に合わせた変更や docker-compose の変更を行います。

Laravel 仮プロジェクトの作成

CakePHP プロジェクトと同列(同じディレクトリ)に Laravel の仮プロジェクトを作成します。
ここでは CakePHPプロジェクト「cakephp-vue-study」のディレクトリにいるところ始めるので、まずは1つ上のディレクトリへ移動します。

ローカル環境に依存したくないで一時的なコンテナを立ち上げて入ります。
一時的なコンテナが独自なのは、最低限必要なライブラリを入れているためです。
( https://github.com/katsuhiko/docker-php-fpm-base/blob/master/Dockerfile )

cd ..
docker run --rm -it -v "$(pwd):/home/app" -w /home/app katsuhikonagashima/php-fpm-base:7.4-buster /bin/bash

ここからはコンテナ内での作業になります。
composer を取得して、Laravelプロジェクトを作ります。
その後、ui として Vue.js を導入します。

curl -sS https://getcomposer.org/installer | php

php composer.phar create-project --prefer-dist laravel/laravel laravel-template

cd laravel-template
php ../composer.phar require laravel/ui
php artisan ui vue
exit

コンテナ内での作業はここまでです。

必要なファイルをコピー

CakePHP4プロジェクトへ必要なファイルをコピーします。
Vue.js の各種ファイルは ./assets/ 配下に格納して開発していきます。
Laravel に合わせて ./resources/ 配下でも良いと思いますが、自分は locale 系のファイルと一緒にあることに違和感を感じるので ./assets/ 配下にしています。

cd ./cakephp-vue-study/

cp ../laravel-template/package.json ./
cp ../laravel-template/webpack.mix.js ./

mkdir -p ./assets
cp -r ../laravel-template/resources/js ./assets/js
cp -r ../laravel-template/resources/sass ./assets/sass

ライブラリのインストール

npm install も一時的なコンテナを立ち上げて実施します。
一応、現時点で LTS となっている node 12系を使っています。

docker run --rm -it -v "$(pwd):/home/app" -w /home/app node:12 npm install

必要になると思うので、このタイミングで vue-router を入れても良いと思います。

docker run --rm -it -v "$(pwd):/home/app" -w /home/app node:12 npm install --save-dev vue-router

webpack.mix.js の変更

./webpack.mix.js をCakePHP4 のディレクトリ構成にあった設定へ変更します。
./assets/./webroot/assets/ 配下へビルドした結果が格納されるようにします。

webpack.mix.js
mix.setPublicPath('webroot')
    .js('assets/js/app.js', 'assets/js')
    .sass('assets/sass/app.scss', 'assets/css')
    .sourceMaps().webpackConfig({devtool: 'source-map'});

javascript, css ファイルにタイムスタンプをつける

javascript, css ファイルのキャッシュが表示されてしまう問題に対応するために CakePHP の Asset.timestamp 機能を使います。
./config/app.php を変更します。

本番でも有効にしたいので、Asset.timestamp へ force を指定します。

config/app.php
    'Asset' => [
        'timestamp' => 'force',
        // 'cacheTime' => '+1 year'
    ],

docker-compose.yml への記述追加

./docker-compose.yml で Vue.js に関するファイルが変更された場合、ビルドを実施するコンテナ watch を追加します。

docker-compose.yml
services:
  # ... 以下が追加の記述です。
  watch:
    image: node:12
    container_name: watch
    working_dir: /home/app
    command: "npm run watch"
    volumes:
      - ./:/home/app
    networks:
      - frontend

コンテナを立ち上げ直します。

docker-compose down
docker-compose up -d

./webroot/assets/js , ./webroot/assets/css 配下に js ファイルや map ファイルができていたら適切にビルドできています。

※ Windowsの場合、変更ファイルの検知ができない可能性があるため command: "npm run watch"command: "npm run watch-poll" にする必要があると思います。

.gitignore への記述追加

ライブラリとビルドで作られるファイルを ./.gitignore へ追加しソース管理の対象から外します。

.gitignore
# Laravel Mix specific files #
##############################
/node_modules
/webroot/assets
/webroot/mix-manifest.json

動作確認のための変更

簡易的な対応を実施して、Vue.js が動作していることを確認します。

routes.php の変更

./config/routes.php で、どんなアクセスがあっても同じ PagesController#index() が呼び出されるようにします。

config/routes.php
$routes->scope('/', function (RouteBuilder $builder) {
    $builder->registerMiddleware('csrf', new CsrfProtectionMiddleware([
        'httpOnly' => true,
    ]));
    $builder->applyMiddleware('csrf');

    //$builder->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
    $builder->connect('/pages/*', ['controller' => 'Pages', 'action' => 'display']);

    // Vue.js のルートページ表示用です。
    $builder->connect('/*', ['controller' => 'Pages', 'action' => 'index']);

    $builder->fallbacks();
});

PagesController の変更

./src/Controller/PagesController.php へ index メソッドを追加します。

src/Controller/PagesController.php
class PagesController extends AppController
{
    // この index メソッドを追加します。
    public function index(): ?Response
    {
        return $this->render();
    }
    // ...
}

Pages/index.php の追加

./templates/Pages/index.php ファイルを追加します。
CakePHP4 から ctp ファイルではなく、php ファイルになったようです。
確認のため、example-component タグを記述しています。

templates/Pages/index.php
<div id="app">
    <example-component></example-component>
</div>
<?= $this->Html->script('/assets/js/app.js')?>

動作確認

http://localhost し以下の文言が表示されていることを確認してください。

Example Component
I'm an example component.

補足) テストの追加と実行方法

./tests/TestCase/Controller/PagesControllerTest.php へ PagesController で追加したメソッドのテストを追加します。

tests/TestCase/Controller/PagesControllerTest.php
class PagesControllerTest extends TestCase
{
    // ... 以下の2つのテストを追加します。
    /**
     * @return void
     */
    public function testVueルートページを表示(): void
    {
        $this->get('/');
        $this->assertResponseOk();
        $this->assertResponseContains('<div id="app">');
    }

    /**
     * @return void
     */
    public function test_どんなアクセスでもVueルートページを表示(): void
    {
        $this->get('/hoge/bar');
        $this->assertResponseOk();
        $this->assertResponseContains('<div id="app">');
    }
    // ...
}

コンテナを使って、テストを実行します。

docker exec -it app php composer.phar test

コミット前に composer check を行うと test と codesniffer による check を行えます。

docker exec -it app php composer.phar check

この composer で実行するコマンドは、 composer.json の scripts に記載があります。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?