- 投稿日:2022-02-01T23:20:48+09:00
【Nuxt】vue-chartjsの読み込みに失敗する!
TypeError: chart_js_WEBPACK_IMPORTED_MODULE_0_.default is not a constructor こんなメッセージが出てくる。なんでやねん!グラフ出したいだけなんですけど?! https://reffect.co.jp/vue/nuxt-js-vue-chartjs-easy-to-use こことかを参考にやってんだけどなぁ・・・ なんでこう記事では簡単に導入できてんのに、自分のときはエラーが出るんだ~!!って毎回思うw 解決の際に参考したサイト https://zenn.dev/kigi/scraps/f8c72302c0f84e https://stackoverflow.com/questions/66940954/why-does-nuxt-give-me-this-error-with-vue-chartjs 解決策 package.jsonのchart.jsのバージョンを2.9.4に書き換える package.json "dependencies" : { "chart.js": "^2.9.4", //このバージョンに書き換える ... "vue-chartjs": "^3.4.0", ... } .nuxtとnode_modulesとpackage-lock.jsonを削除 一旦上記のフォルダを削除 node install を実行 $ node install 実行後にnode_modulesとpackege-lock.jsonが作成される yarn devを実行 $ yarn dev このタイミングで.nuxtが作成される。 上記の手順で何故かうまくいきました。 どこが要だったのかよくわかりませんが、chart.jsのバージョンの変更は間違いなく必須だと思います。
- 投稿日:2022-02-01T23:05:11+09:00
Vue CLI で作成した Vuetify アプリを Vite / Vitest に移行する
Vuetify 2 と @vue/composition-api を使用した TODO アプリを題材に Vue CLI から Vite / Vitest への移行を試して、とりあえず動くようになったので手順と設定を共有したいと思います。 ビルド速度やサイズの変化についてはこの記事の後ろにまとめてあります。 使用したコードは次のリポジトリにあります。 なお、この記事に記載している情報は 2022 年 1 月 30 日時点のものです。 記事の内容はあくまで一例であり、手順や設定が正しいものであるという保証はありませんのでご注意ください。 移行を試した背景 2022 年 1 月 18 日に Vue CLI がメンテナンスモードに入ったことが宣言されました。 1 Vue CLI 自体は引き続き利用可能で v5 安定版リリースに向けて作業が続けられています。 2 とはいえ今後の主流は Vite になると思われますので Vue CLI で作成したアプリを移行できるか試してみました。 テストフレームワークに Vitest を選んだのは趣味です。 Vitest は鋭意開発中であり本番利用は推奨されていません。 しかし Vite と組み合わせて Vue (SFC) を使う前提だとあまり選択肢はないような気もします。 初期バージョン Vue CLI によるプロジェクト作成時の設定は次のような感じです。 $ vue create vuetify-todo-example Vue CLI v4.5.15 ? Please pick a preset: Manually select features ? Check the features needed for your project: Choose Vue version, Babel, TS, Router, Linter ? Choose a version of Vue.js that you want to start the project with 2.x ? Use class-style component syntax? No ? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes ? Use history mode for router? (Requires proper server setup for index fallback in production) Yes ? Pick a linter / formatter config: Prettier ? Pick additional lint features: Lint on save ? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files ? Save this as a preset for future projects? No これに Vuetify と @vue/composition-api を追加して TODO アプリの体裁を整えた v0.1.0 が初期バージョンです。 vue-router も導入していますがルートは 1 個だけなので導入しているだけで意味はありません。 アプリの設計が微妙とかは見逃してください。 事前準備 事前準備として依存パッケージをできる限り更新しておきました。 最終的に Vuetify 3 と Vue CLI 4 の依存関係で更新できないパッケージがいくつかありました。 vuetify sass vue-cli webpack sass-loader eslint eslint-plugin-prettier @vue/eslint-config-prettier ESLint 本体は更新できませんでしたがプラグインやルールが更新された結果、新しくエラーが出るようになったので修正しています。 @typescript-eslint/no-loss-of-precision だけは ESLint v7.1.0 以上を必要とするため無効にしています。 このタイミングでテストを書いていないことに気が付いて Jest でテストを書きました。 テストの書き方が微妙とかは見逃してください。 ついでに GitHub Actions で GitHub Pages にデプロイするようにしたり不具合を修正したりした v0.2.2 が移行前のバージョンになります。 Vue CLI から Vite / Vitest に移行する いよいよ Vite / Vitest への移行です。 不要になるパッケージの削除 移行する前に dependencies と devDependencies から不要になるパッケージを削除します。 vite / vitest への置き換え対象となる vue-cli / babel / webpack / jest の関連のパッケージが主な削除対象です。 npm uninstall core-js @types/jest @vue/cli-plugin-babel @vue/cli-plugin-eslint @vue/cli-plugin-router @vue/cli-plugin-typescript @vue/cli-plugin-unit-jest @vue/cli-service sass-loader vue-cli-plugin-vuetify vuetify-loader core-js @types/jest @vue/cli-plugin-babel @vue/cli-plugin-eslint @vue/cli-plugin-router @vue/cli-plugin-typescript @vue/cli-plugin-unit-jest @vue/cli-service sass-loader vue-cli-plugin-vuetify vuetify-loader 続いて不要になる設定ファイルも削除します。 トランスパイルは esbuild に頼る形になる 5 ため Browserslist の設定も削除しています。 .browserslistrc babel.config.js jest.config.js vue.config.js ただ、記事を書いている途中で気が付いたのですが後の手順で入れる Vite プラグインの依存関係で babel や Browserslist が再導入されているようでした。 Vite / Vitest のインストール 続いて Vite / Vitest をインストールします。 Vue 2 + Vuetify を動かすために追加のプラグインもインストールしています。 npm install --save-dev vite vue-tsc vite-plugin-vue2 unplugin-vue-components vitest jsdom vue-tsc はプラグインではないのですが vite で Vue の型チェックをするために必要なツールです。 vite-plugin-vue2 は vite で Vue 2 をサポートするプラグインです。 非公式プラグインですが 公式ドキュメントで紹介されています。 unplugin-vue-components は SFC でのコンポーネント import を自動的に行ってくれるプラグインです。 非公式プラグインですが Vue 周りで多くの貢献をしている方が開発しています。 vuetify-loader (Vuetify 2.x 用) は Vite に対応していない 6 ため代わりに使用しています。 jsdom はテスト用に DOM をエミュレートしてくれるパッケージです。 Vue CLI で Jest を設定した場合は導入済みかもしれません。 Vitest では happy-dom という実装が推奨っぽい感じなのですが実際にテストを動かしたところエラー 7 が出たため jsdom を使用しています。 設定と修正 Vite / Vitest で動かすために修正と追加が必要です。 プロジェクトルートに vite.config.ts を用意します。 設定の説明は日本語のコメントで記載しておきました。 // vite.config.ts /// <reference types="vitest" /> import { defineConfig } from "vite"; import { createVuePlugin } from "vite-plugin-vue2"; import Components from "unplugin-vue-components/vite"; import { VuetifyResolver } from "unplugin-vue-components/resolvers"; import path from "path"; // https://vitejs.dev/config/ export default defineConfig({ // デプロイ時と serve で動かした際のパスを変更しています。 base: process.env.NODE_ENV === "production" ? "/vuetify-todo-example/" : "/", resolve: { // Vite 単体だと無くても問題ないのですが Vitest を動かした際に動かないため追加します。 // https://vitejs.dev/config/#resolve-alias alias: [ { find: "@/", replacement: `${path.resolve(__dirname, "./src")}/`, }, ], }, // 大量の警告が出力されるため一部のルールを無効化しています。 // https://github.com/vitejs/vite/issues/6333#issuecomment-1003318603 css: { postcss: { plugins: [ { postcssPlugin: "internal:charset-removal", AtRule: { charset: (atRule) => { if (atRule.name === "charset") { atRule.remove(); } }, }, }, ], }, }, plugins: [ // Vite で Vue 2 を動かすために必要なプラグインです。 // https://github.com/underfin/vite-plugin-vue2 createVuePlugin(), // SFC でのコンポーネント import を自動的に行ってくれるプラグインです。 // https://github.com/antfu/unplugin-vue-components Components({ // Vuetify コンポーネントを import するための設定です。 resolvers: [VuetifyResolver()], // プロジェクトルートに型定義ファイルを出力してくれるのですが // 型チェックのエラーを解消できなかったため無効化しています。 dts: false, }), ], test: { // describe や it などを import なしで使えるようにします。 globals: true, // happy-dom だとエラーが出るため jsdom を指定します。 environment: "jsdom", // テストの初期化コードです。 // Jest 向けに作成したものと同じです。 setupFiles: ["tests/setup.ts"], // devtools 周りのコンソールメッセージが多数出力されるため抑制しています。 silent: true, // Vuetify は Node で ESM として読み込めないため変換が必要な依存関係として指定します。 deps: { inline: ["vuetify"], }, }, }); そして public/index.html をプロジェクトルートに移動します。 Vite では public ディレクトリがそのままデプロイされるため外に出す必要があります。 mv public/index.html ./index.html プロジェクトルートに移動した index.html を書き換えます。 具体的には webpack で置換していた部分と body 内部です。 書き換えたらいよいよ起動です。 npx vite おそらくブラウザには真っ白な画面が出ているはずです。 開発者コンソールを確認すると例外が出ており、クリックすると vue-router の初期化処理で process.env.BASE_URL の参照に失敗していることがわかります。 Uncaught ReferenceError: process is not defined at index.ts:17:9 Vite では環境変数の公開方法が変更されているため ドキュメント に記載されている env.d.ts を追加したのち、ソースコード内の process.env に対する参照を修正します。 (vite.config.ts 内で行っている参照はそのままで問題ありません) 最後に package.json の scripts を Vue CLI を使わない形に修正します。 新しく追加した行もありますが Vue CLI が裏で色々やってくれていたことがよく分かります。 "scripts": { "serve": "vite", "build": "vue-tsc --noEmit && vite build", "preview": "vite preview", "typecheck": "vue-tsc --noEmit", "test:unit": "vitest run", "lint": "eslint \"./src/**/*.{ts,tsx,vue}\" \"./tests/**/*.ts\" && prettier --check \"./src/**/*.{ts,tsx,vue}\" \"./tests/**/*.ts\"", "lint:fix": "eslint \"./src/**/*.{ts,tsx,vue}\" \"./tests/**/*.ts\" --fix && prettier --write \"./src/**/*.{ts,tsx,vue}\" \"./tests/**/*.ts\"" }, ここまでの変更は 1 コミット で行いました。 依存パッケージの更新 (2 回目) 最後に依存パッケージを更新します。 ESLint を更新するとルール名が変更されていたり、ルールが追加されていることがあるので対応します。 自動修正可能なものについては npm run lint:fix で対応可能ですが、ルール名も変更されていたので .eslintrc.js の修正が必要でした。 依存パッケージ更新やそれにともなう Lint エラーを修正したのが v0.3.0 です。 移行前後の比較 移行前 (v0.2.2) と移行後 (v0.3.0) の比較です。 処理時間については GitHub Actions 上で実行された 1 回の結果なので精度が高いものではありません。 処理内容も同じではないのであくまで参考値としてください。 依存パッケージ数 依存パッケージ数は大幅に減少しました。 Before After 依存パッケージ数 1751 個 439 個 脆弱性件数 (high) 12 件 0 件 脆弱性件数 (moderate) 87 件 3 件 npm ci に要した時間 37 秒 13 秒 ビルドなどの処理時間 ビルドは速くなりましたがテストは大幅に遅くなりました。 Before After Lint 4 秒 5 秒 テスト 6 秒 22 秒 ビルド 27 秒 21 秒 実際の動作を見ていると Vitest 起動時に毎回 Vuetify を変換しており、そこで時間がかかっているようです。 npm run serve した場合も Vite 自体はすぐに起動するのですが Vite 起動後の初回アクセスで変換が行われ、毎回待たされます。 ビルド成果物のサイズ JavaScript は大幅に小さくなった一方、 CSS は大幅に大きくなりました。 Before After JavaScript (合計) 325.29 KiB 215.58 KiB CSS 351.38 KiB 515.47 KiB JavaScript についてはターゲットブラウザを厳密に合わせていないため難しいところですが想像していたより小さくなりました。 CSS については設定が不十分なために Tree Shaking されていないと思われます。 まとめ Vue CLI で作成した Vuetify アプリを Vite / Vitest に移行できました。 残念ながら世間一般で言われているような高速化は確認できませんでしたが規模が大きなプロジェクトであれば確認できそうな気配はあります。 前述のとおり Vue CLI 自体は引き続き利用可能で v5 安定版リリースに向けて作業が続けられており、 Vitest も鋭意開発中であり本番利用は推奨されていない状態です。 Vuetify 自体も Vue 3 および Vite に対応した Vuetify 3 が計画されていますのでそれを待ってもよいと思います。 8 それでも今後主流になりそうな環境ということで移行を試す価値はあると思いました。 https://github.com/vuejs/vue-cli/commit/7f3d51133635114528848b29e27084ee89d53e1c ↩ https://github.com/vuejs/vue-cli/issues/6064#issuecomment-1016473985 ↩ https://github.com/vuetifyjs/vuetify/issues/13694 ↩ https://github.com/vuejs/vue-cli/issues/6064 ↩ https://vitejs.dev/config/#build-target ↩ https://github.com/vuetifyjs/vuetify/issues/13229 ↩ https://github.com/vuejs/vue-test-utils/issues/1886 ↩ https://vuetifyjs.com/en/introduction/roadmap/ ↩
- 投稿日:2022-02-01T20:27:31+09:00
Vue-CLI?Vite?いいえ、create-vueです!
Vue-CLIの動作遅いなぁ。。。 Viteを試したけれど、基本的なのしか入ってなくて他のライブラリ入れるのめんどくさいなぁ。。。 Vue のプロジェクトをすばやく構築したいなぁ。。。 そんなあなたに create-vueをご紹介! create-vue って? コマンドラインツールです。GitHub はこちら。 Vue のプロジェクトを簡単に立ち上げられます。 以下でプロジェクトの立ち上げ方を見ていきましょう! 環境 windows10 home Node.js v16.13.0 npm 8.1.0 手順 コマンドプロンプトを立ち上げてプロジェクトを立ち上げたいフォルダに移動して以下のコードを打ち込みます。ここではVue3のプロジェクトを立ち上げます。 npm init vue@3 すると以下のような画面が表示されるので、プロジェクト名を入力します。今回はプロジェクト名を vue-sample としています。 Vue.js - The Progressive JavaScript Framework ? Project name: » vue-sample プロジェクト名を入力すると、対話形式でプロジェクトのセットアップを行っていきます。 √ Project name: ... vue-sample √ Add TypeScript? ... No / Yes √ Add JSX Support? ... No / Yes √ Add Vue Router for Single Page Application development? ... No / Yes √ Add Pinia for state management? ... No / Yes √ Add Vitest for Unit Testing? ... No / Yes √ Add Cypress for End-to-End testing? ... No / Yes √ Add ESLint for code quality? ... No / Yes √ Add Prettier for code formatting? ... No / Yes 上から順に TypeScript を追加しますか? JSX をサポートしますか? SPA 開発のための Vue Router を追加しますか? 状態管理の Pinia を追加しますか? ユニットテストの Vitest を追加しますか? E2E テストの Cypress を追加しますか? ESLint を追加しますか? Prettier を追加しますか? となりますので、自分の好きなように No/Yes を選んでセットアップしてください。 プロジェクトの作成が完了したら、作成したプロジェクトのフォルダに移ります。 cd vue-sample 以下のコマンドを打ち込みます。package.json に記述されている情報を元に node_modules にインストールします。 npm install npm install について詳しく学びたい方はこちらをどうぞ。 以下のコマンドを打ち込みます。 npm run lint 以下のコマンドを打ち込んで、http://localhost:3000/ にアクセスしてみましょう。 npm run dev このような画面が表示されれば成功です!Vue-CLI で実行するより早いですね! ファイル構成 同じような構成のプロジェクトを Vue-CLI でもつくって、ファイル構成がどう違うのか見てみましょう。 作成したファイル構成はこちら。 √ Project name: ... vue-sample √ Add TypeScript? ... Yes √ Add JSX Support? ... No √ Add Vue Router for Single Page Application development? ... Yes √ Add Pinia for state management? / Yes √ Add Vitest for Unit Testing? / Yes √ Add Cypress for End-to-End testing? ... No √ Add ESLint for code quality? ... Yes √ Add Prettier for code formatting? / Yes 左がVue-CLI、右がcreate-vueです。 いろいろと違うところはありますね。 Vue-CLIではtestフォルダがsrcと同じ階層にありましたが、create-vueではsrc/componentsの中にあります。 ファイルの重さ Vue-CLIとcreate-vueで同じような構成でプロジェクトを作ってみました。 Vue-CLI create-vue 228 MB 167 MB 61MB違いますね。これはVue-CLIだと状態管理でVuexになりますが、create-vueではPiniaになるためだと考えられます。 Pinia と Vitest って? Pinia 公式はこちら。 Vue.js 向けの状態管理ライブラリ mutations がない。 state の値を変更する場合は actions を使用する Vuedevtools をサポート Vuex と比べて軽い などなど。 Vitest 公式はこちら。 2022 年 2 月 1 日現在、Vitest は開発中です。プロジェクトに組み込むときは注意してください。 Vite を搭載した超高速のユニットテストフレームワーク ホットリロードでテストできる Chai、Jest も使える などなど。 Vitestのほうがホットリロードあるし、テスト実行が速いです。 快適な開発を! create-vue を使うことで簡単にプロジェクト立ち上げられました! テストの実行方法とかは README に書いてあるので、そちらをご参照ください。 状態管理がVue-CLIだとVuexでcreate-vueだとPiniaだったり、create-vueではVitestを使っていたり、どちらを使うかは分かれると思います。 ただ、create-vueのVitestはまだ正式リリースされていないので、個人開発で遊ぶときに使うのがいいのかなと思います。 Vuetify が Vue3 に対応したら、Vuetify を入れてもっと使いたいなと思います。 ここまで読んでいただいてありがとうございました m(__)m
- 投稿日:2022-02-01T16:44:26+09:00
【Vue.js】ディレクティブ(v-if、v-for)について
ディレクティブとは ディレクティブとは、Vue.jsにおける独自の属性(v-○○)のことで、これを使うことでDOM操作ができる。 これによりDOM操作の記述を減らすことができ、開発スピードが向上する。 v-ifとv-forについて紹介する。 v-if 真偽値に基づいて要素の表示・非表示を切り替える。 html <div id="app"> <p v-if="displayFlag">Hello!!</p> </div> Vue const sample = { data() { return { displayFlag: true, }; }, }; Vue.createApp(sample).mount("#app"); 上記のサンプルではdisplayFlag=trueの場合に「Hello!!」が表示され、falseの場合は非表示になる。 v-for Vue.jsでのfor文。配列などのデータを表示させるために使う。v-for = <変数> in <配列名>のような形で書くことができる。 html <div id="app"> <ul> <li v-for="image in images"> <img :src="image.src"> </li> </ul> </div> Vue const sample = { data() { return { images: [ { src: "image1.png" }, { src: "image2.png" }, ], }; }, }; Vue.createApp(sample).mount("#app");
- 投稿日:2022-02-01T11:48:16+09:00
DockerでLaravel-Mix(Laravel8×Vue3)環境構築
はじめに 今回は、Laravel8をメインとして、その中でVue3を使う環境の構築方法をご紹介します。 環境 Docker version 20.10.12 Docker Compose version v2.2.3 Laravel Framework 8.81.0 Vue 3.2.29 構成 以下の構成を想定しています。 project ├── environment │ └── development │ ├── docker │ │ ├── mysql │ │ │ ├── Dockerfile │ │ │ ├── my.cnf │ │ │ └── sql │ │ │ └── create-database.sql │ │ ├── nginx │ │ │ └── default.conf │ │ ├── node │ │ │ └── Dockerfile │ │ └── php │ │ ├── Dockerfile │ │ └── php.ini │ └── docker-compose.yml └── server 構築 1. 全体(Docker) 1-1. docker-compose.yml作成 今回は、PHP, nginx, mysql, nodeの4つのコンテナを想定しておりますので、以下のようになります。 docker-compose.yml version: '3.9' services: php: container_name: php build: docker/php volumes: - ./../../server:/var/www:cached node: container_name: node build: docker/node volumes: - ./../../server:/project:cached tty: true # command: bash -c " # npm install; # npm run watch; # " nginx: image: nginx container_name: nginx ports: - 80:80 volumes: - ./../../server:/var/www:cached - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:cached depends_on: - php - node mysql: build: docker/mysql container_name: mysql environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: sample TZ: 'Asia/Tokyo' command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci restart: on-failure volumes: - mysql:/var/lib/mysql:cached - ./docker/mysql/sql:/docker-entrypoint-initdb.d:cached ports: - 3306:3306 volumes: mysql: 1-2. PHP Dockerfile作成 phpコンテナ構築時に使われるDockerfileをdocker/php/に作成します。 Dockerfile FROM php:8.0-fpm COPY php.ini /usr/local/etc/php/ RUN apt-get update \ && apt-get install -y zlib1g-dev libzip-dev mariadb-client libpng-dev unzip RUN docker-php-ext-install zip pdo_mysql gd #Composer install COPY --from=composer:latest /usr/bin/composer /usr/bin/composer ENV COMPOSER_ALLOW_SUPERUSER 1 ENV COMPOSER_HOME /composer ENV PATH $PATH:/composer/vendor/bin WORKDIR /var/www RUN composer global require "laravel/installer" PHP設定ファイル作成 PHPの設定ファイルをdocker/php/に作成します。以下、最低限の設定ですのでプロジェクトに応じて変更してください。 php.ini zend.exception_ignore_args = off expose_php = on max_execution_time = 60 max_input_vars = 1000 upload_max_filesize = 64M post_max_size = 128M memory_limit = 256M error_reporting = E_ALL display_errors = on display_startup_errors = on log_errors = on error_log = /dev/stderr default_charset = UTF-8 [Date] date.timezone = "Asia/Tokyo" [mbstring] mbstring.language = "Japanese" 1-3. nginx 設定ファイル作成 niginxの設定ファイルをdocker/nginx直下に作成します。以下はLaravelでの運用を前提に記載しています。 default.conf server { listen 80; root /var/www/public; index index.php; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } } 1-4. MySQL Dockerfile FROM mysql:8 COPY my.cnf /etc/mysql/conf.d/ RUN chmod 644 /etc/mysql/conf.d/my.cnf 設定ファイル my.cnf [mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci [client] default-character-set=utf8mb4 SQL docker/mysql/sql/create-database.sqlにてデータベースを作成するSQLを用意します。 CREATE DATABASE IF NOT EXISTS sample CREATE DATABASE IF NOT EXISTS sample_test 1-5. Node Dockerfile FROM node:16.0.0 WORKDIR /project RUN npm install -g agentkeepalive --save RUN npm install -g npm@8.4.0 RUN npm cache clean -f 1-6. Docker起動 dockerを起動して、Laravelプロジェクトを作成してみましょう。 docker-compose.ymlがあるディレクトリに移動して下記でdockerを起動してみましょう。 cd environment/development docker-compose up -d 2. Laravel 2-1. プロジェクト作成 コンテナに入って、Laravelプロジェクトを作成します。 cd environment/development # phpコンテナに入ります docker-compose exec php bash # Laravelプロジェクト作成 composer create-project --prefer-dist laravel/laravel ./ server以下にLaravelの各ディレクトリやファイルができています。 2-2. 動作確認 ブラウザからlocalhostにアクセスしてみましょう。以下のようにLaravelの画面が立ち上がっていれば成功です。 3. MySQL MySQLのコンテナへ接続しましょう。 3-1. .env設定 MySQLコンテナ及びデータベースへの接続情報を.envに記載します。 DB_CONNECTION=mysql DB_HOST=mysql DB_PORT=3306 DB_DATABASE=sample DB_USERNAME=root DB_PASSWORD=root 3-2. マイグレーションの実行 cd environment/development # phpコンテナに入ります docker-compose exec php bash # マイグレーションの実行 root@de1e51270b2b:/var/www# php artisan migrate Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (38.74ms) Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table (26.03ms) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (29.34ms) Migrating: 2019_12_14_000001_create_personal_access_tokens_table Migrated: 2019_12_14_000001_create_personal_access_tokens_table (40.38ms) 4. Vue 4-1. Vueインストール cd environment/development # nodeコンテナに入る docker-compose exec node bash # vueをインストール npm install vue@next vue-loader@next @vue/compiler-sfc 4-2. webpack.min.jsを修正 下記のようにvue()を追加します。 server/webpack.mix.js mix.js('resources/js/app.js', 'public/js') .postCss('resources/css/app.css', 'public/css', [ // ]).vue(); 4-3. Vueコンポーネント作成 server/resources/jsの配下にcomponentsのディレクトリを作成して、resources/js/components/TestVue.vueを作成します。 server/resources/js/components/TestVue.vue <template> Hello Vue !! </template> <script> import { onMounted } from 'vue' export default ({ setup() { console.log("start vue") onMounted(() => { console.log('start mounted !') }) }, }) </script> 4-4. Vueのマウント server/resources/js/app.jsを下記のように編集します。 server/resources/js/app.js require('./bootstrap'); import { createApp } from 'vue' import TestVue from './components/TestVue.vue'; const app = createApp({}) app.component('test-vue', TestVue); app.mount('#app') 4-5. ビルド cd environment/development docker-compose exec node bash -c "npm run dev" 4-6. Laravelビューファイルを作成する server/resources/views/app.blade.phpを作成します。 server/resources/views/app.blade.php <!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Laravel</title> <link href="{{ asset('css/app.css') }}" rel="stylesheet"/> <script src="{{ asset('js/app.js') }}" defer="defer"></script> </head> <body> <div id="app"> <test-vue></test-vue> </div> </body> </html> 4-7. Laravelのルーティング修正 server/routes/web.phpを以下のように修正します。 Route::get('/', function () { return view('app'); }); 4-8. Laravelキャッシュクリア 上記の手順で一度ビューやルーティングのキャッシュファイルが作成されていますので、以下のコマンドでキャッシュクリアしましょう。(不要なものも含まれていますが。。。) cd environment/development docker-compose exec php bash -c " php artisan cache:clear && php artisan config:clear && php artisan config:cache && php artisan route:clear && php artisan view:clear && php artisan clear-compiled && php artisan optimize && composer dump-autoload && rm -f bootstrap/cache/config.php" 4-9. 動作確認 おまけ nodeコンテナのコマンドのコメントアウトを外すと、ファイル変更のたびにnpm run devをする必要がなくなるので開発は楽になります! docker-compose.yml version: '3.9' services: php: container_name: php build: docker/php volumes: - ./../../server:/var/www:cached node: container_name: node build: docker/node volumes: - ./../../server:/project:cached tty: true command: bash -c " npm install; npm run watch; " nginx: image: nginx container_name: nginx ports: - 80:80 volumes: - ./../../server:/var/www:cached - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:cached depends_on: - php - node mysql: build: docker/mysql container_name: mysql environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: sample TZ: 'Asia/Tokyo' command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci restart: on-failure volumes: - mysql:/var/lib/mysql:cached - ./docker/mysql/sql:/docker-entrypoint-initdb.d:cached ports: - 3306:3306 volumes: mysql: Laravel Mixで環境に合わせて出力ファイルを変える方法 Laravel Mixを利用する場合に、本番環境と開発環境で出力されるJSファイルやCSSファイルを分けたいと思います。 その方法については、以下の記事で紹介しています。 詳細 おわりに SPAはSEOに弱いということで、SSRで構築することがありますが、個人的にはかなり構築しづらかったので、SEOこだわるなら今回紹介した構成でいいのでは?と、思っていますがみなさんはいかがでしょうか? 成果物はGithubにありますので、必要な方はご覧ください。 参考 LaravelでVue.js(v3)を使う方法!
- 投稿日:2022-02-01T11:48:16+09:00
DockerでLaravel8×Vue3環境構築
はじめに 今回は、Laravel8をメインとして、その中でVue3を使う環境の構築方法をご紹介します。 環境 Docker version 20.10.12 Docker Compose version v2.2.3 Laravel Framework 8.81.0 Vue 3.2.29 構成 以下の構成を想定しています。 project ├── environment │ └── development │ ├── docker │ │ ├── mysql │ │ │ ├── Dockerfile │ │ │ ├── my.cnf │ │ │ └── sql │ │ │ └── create-database.sql │ │ ├── nginx │ │ │ └── default.conf │ │ ├── node │ │ │ └── Dockerfile │ │ └── php │ │ ├── Dockerfile │ │ └── php.ini │ └── docker-compose.yml └── server 構築 1. 全体(Docker) 1-1. docker-compose.yml作成 今回は、PHP, nginx, mysql, nodeの4つのコンテナを想定しておりますので、以下のようになります。 docker-compose.yml version: '3.9' services: php: container_name: php build: docker/php volumes: - ./../../server:/var/www:cached node: container_name: node build: docker/node volumes: - ./../../server:/project:cached tty: true # command: bash -c " # npm install; # npm run watch; # " nginx: image: nginx container_name: nginx ports: - 80:80 volumes: - ./../../server:/var/www:cached - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:cached depends_on: - php - node mysql: build: docker/mysql container_name: mysql environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: sample TZ: 'Asia/Tokyo' command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci restart: on-failure volumes: - mysql:/var/lib/mysql:cached - ./docker/mysql/sql:/docker-entrypoint-initdb.d:cached ports: - 3306:3306 volumes: mysql: 1-2. PHP Dockerfile作成 phpコンテナ構築時に使われるDockerfileをdocker/php/に作成します。 Dockerfile FROM php:8.0-fpm COPY php.ini /usr/local/etc/php/ RUN apt-get update \ && apt-get install -y zlib1g-dev libzip-dev mariadb-client libpng-dev unzip RUN docker-php-ext-install zip pdo_mysql gd #Composer install COPY --from=composer:latest /usr/bin/composer /usr/bin/composer ENV COMPOSER_ALLOW_SUPERUSER 1 ENV COMPOSER_HOME /composer ENV PATH $PATH:/composer/vendor/bin WORKDIR /var/www RUN composer global require "laravel/installer" PHP設定ファイル作成 PHPの設定ファイルをdocker/php/に作成します。以下、最低限の設定ですのでプロジェクトに応じて変更してください。 php.ini zend.exception_ignore_args = off expose_php = on max_execution_time = 60 max_input_vars = 1000 upload_max_filesize = 64M post_max_size = 128M memory_limit = 256M error_reporting = E_ALL display_errors = on display_startup_errors = on log_errors = on error_log = /dev/stderr default_charset = UTF-8 [Date] date.timezone = "Asia/Tokyo" [mbstring] mbstring.language = "Japanese" 1-3. nginx 設定ファイル作成 niginxの設定ファイルをdocker/nginx直下に作成します。以下はLaravelでの運用を前提に記載しています。 default.conf server { listen 80; root /var/www/public; index index.php; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } } 1-4. MySQL Dockerfile FROM mysql:8 COPY my.cnf /etc/mysql/conf.d/ RUN chmod 644 /etc/mysql/conf.d/my.cnf 設定ファイル my.cnf [mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci [client] default-character-set=utf8mb4 SQL docker/mysql/sql/create-database.sqlにてデータベースを作成するSQLを用意します。 CREATE DATABASE IF NOT EXISTS sample CREATE DATABASE IF NOT EXISTS sample_test 1-5. Node Dockerfile FROM node:16.0.0 WORKDIR /project RUN npm install -g agentkeepalive --save RUN npm install -g npm@8.4.0 RUN npm cache clean -f 1-6. Docker起動 dockerを起動して、Laravelプロジェクトを作成してみましょう。 docker-compose.ymlがあるディレクトリに移動して下記でdockerを起動してみましょう。 cd environment/development docker-compose up -d 2. Laravel 2-1. プロジェクト作成 コンテナに入って、Laravelプロジェクトを作成します。 cd environment/development # phpコンテナに入ります docker-compose exec php bash # Laravelプロジェクト作成 composer create-project --prefer-dist laravel/laravel ./ server以下にLaravelの各ディレクトリやファイルができています。 2-2. 動作確認 ブラウザからlocalhostにアクセスしてみましょう。以下のようにLaravelの画面が立ち上がっていれば成功です。 3. MySQL MySQLのコンテナへ接続しましょう。 3-1. .env設定 MySQLコンテナ及びデータベースへの接続情報を.envに記載します。 DB_CONNECTION=mysql DB_HOST=mysql DB_PORT=3306 DB_DATABASE=sample DB_USERNAME=root DB_PASSWORD=root 3-2. マイグレーションの実行 cd environment/development # phpコンテナに入ります docker-compose exec php bash # マイグレーションの実行 root@de1e51270b2b:/var/www# php artisan migrate Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (38.74ms) Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table (26.03ms) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (29.34ms) Migrating: 2019_12_14_000001_create_personal_access_tokens_table Migrated: 2019_12_14_000001_create_personal_access_tokens_table (40.38ms) 4. Vue 4-1. Vueインストール cd environment/development # nodeコンテナに入る docker-compose exec node bash # vueをインストール npm install vue@next vue-loader@next @vue/compiler-sfc 4-2. webpack.min.jsを修正 下記のようにvue()を追加します。 mix.js('resources/js/app.js', 'public/js') .postCss('resources/css/app.css', 'public/css', [ // ]).vue(); 4-3. Vueコンポーネント作成 resources/jsの配下にcomponentsのディレクトリを作成して、resources/js/components/TestVue.vueを作成します。 <template> Hello Vue !! </template> <script> import { onMounted } from 'vue' export default ({ setup() { console.log("start vue") onMounted(() => { console.log('start mounted !') }) }, }) </script> 4-4. Vueのマウント resources/js/appを下記のように編集します。 require('./bootstrap'); import { createApp } from 'vue' import TestVue from './components/TestVue.vue'; const app = createApp({}) app.component('test-vue', TestVue); app.mount('#app') 4-5. ビルド cd environment/development docker-compose exec node bash -c "npm run dev" 4-6. Laravelビューファイルを作成する <!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Laravel</title> <script src="{{ asset('js/app.js') }}" defer="defer"></script> </head> <body> <div id="app"> <test-vue></test-vue> </div> </body> </html> 4-7. Laravelのルーティング修正 server/routes/web.phpを以下のように修正します。 Route::get('/', function () { return view('app'); }); 4-8. Laravelキャッシュクリア 上記の手順で一度ビューやルーティングのキャッシュファイルが作成されていますので、以下のコマンドでキャッシュクリアしましょう。(不要なものも含まれていますが。。。) cd environment/development docker-compose exec php bash -c " php artisan cache:clear && php artisan config:clear && php artisan config:cache && php artisan route:clear && php artisan view:clear && php artisan clear-compiled && php artisan optimize && composer dump-autoload && rm -f bootstrap/cache/config.php" 4-9. 動作確認 おまけ nodeコンテナのコマンドのコメントアウトを外すと、ファイル変更のたびにnpm run devをする必要がなくなるので開発は楽になります! docker-compose.yml version: '3.9' services: php: container_name: php build: docker/php volumes: - ./../../server:/var/www:cached node: container_name: node build: docker/node volumes: - ./../../server:/project:cached tty: true command: bash -c " npm install; npm run watch; " nginx: image: nginx container_name: nginx ports: - 80:80 volumes: - ./../../server:/var/www:cached - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:cached depends_on: - php - node mysql: build: docker/mysql container_name: mysql environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: sample TZ: 'Asia/Tokyo' command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci restart: on-failure volumes: - mysql:/var/lib/mysql:cached - ./docker/mysql/sql:/docker-entrypoint-initdb.d:cached ports: - 3306:3306 volumes: mysql: おわりに SPAはSEOに弱いということで、SSRで構築することがありますが、個人的にはかなり構築しづらかったので、SEOこだわるなら今回紹介した構成でいいのでは?と、思っていますがみなさんはいかがでしょうか? 成果物はGithubにありますので、必要な方はご覧ください。 参考 LaravelでVue.js(v3)を使う方法!
- 投稿日:2022-02-01T10:12:54+09:00
vue.js componentsの中ではなぜ’data’を関数として宣言しなければいけないのか?
vue.jsを勉強していく中で疑問に思っていたことが解消したので少しだけ。 なぜコンポーネントのdataは関数でなければいけないのか? 前提として、コンポーネントは一度定義すると使いまわせるという特徴を持っている。 <div id="components"> <TestComponent></TestComponent> {/* 同じコンポーネントを使い回している */} <TestComponent></TestComponent> {/* 同じコンポーネントを使い回している */} <TestComponent></TestComponent> {/* 同じコンポーネントを使い回している */} </div> このように同じコンポーネントを3回使い回している場合、’count’というデータを data: { count: 0 } と表記するとどのコンポーネントでも同じ’count’を参照することとなり、一つのコンポーネントで’count’を更新すると全てのコンポーネントで同じように値が更新されてしまうからです。 そうならないよう’data’を宣言するときは、 data: function () { return { count: 0 } } のように関数として宣言します。こうすることにより各コンポーネントが独自の変数として’data’を保持できるようになります。 最初に読んだ入門書では「コンポーネントを使うときはこういう書き方をします」という風にしか書かれておらず何故そうなのかを考えずに先に進んでしまいましたが「なんでだろ?」と思っていたことがスッキリしたので短いですが記事にしました。