Vue3向けのコンポーザブルライブラリ作ってみた。
React向けのカスタムフックライブラリを見てみると、useListというカスタムフックがあった。
Vue3向けにこういうライブラリ作れそうだなーと思ったので、ライブラリの作成の練習としてやってみた。
とりあえず、結果としてできたのが以下です。npmへのリンクとGitHubへのリンクを貼ります。
とりあえず、ライブラリ作成に関しての知見がゼロなので、Vueのコミュニティで「参考記事ないですかー」と問うたら、@kazuponさん(Vue-I18nというライブラリを作られている方)から、参考となる記事をいただいた。
Vueのコミュニティの暖かさに感謝。
参考となる記事をベースに、自分でライブラリを作ってみたら、かなり簡単にできた。
また作ろ
Laravel sailのシェルスクリプトの中身を見てみる。
Laravelの環境構築に便利なsail。curl
コマンド一発で呼び出せて、withである程度好きな構成で立ち上げられる。
しかし、バージョンを指定して構築できない。
適当に素振りする程度だとあまり困らないが、ハンズオン的な資料を見つつやるとディレクトリ構成などがバージョン毎に異なっていて戸惑うことがある。
バージョン指定できない理由がわからないため、とりあえずシェルスクリプトの中身を見てみることにしてみた。
シェルスクリプトを覗いてみる
以下のURLをクリックすることで、ブラウザ上でシェルスクリプトの中身が見れる。
https://laravel.build/project_name
または、curl
コマンドを利用してローカル上にファイルを作成する
curl https://laravel.build/project_name -o laravelsail.sh
とりあえず以下に展開してみる。あまり中身難しくなくてホッとした。
わかる範囲で、コメントを付けてみた。
# Dockerの有無確認 docker info > /dev/null 2>&1 # Ensure that Docker is running... if [ $? -ne 0 ]; then echo "Docker is not running." exit 1 fi docker run --rm \ --pull=always \ -v "$(pwd)":/opt \ -w /opt \ laravelsail/php82-composer:latest \ bash -c "laravel new project_name && cd project_name && php ./artisan sail:install --with=mysql,redis,meilisearch,mailpit,selenium " # laravel/installerを利用してLaravelを構築して、sailをインストールしている # プロジェクトフォルダに移動 cd project_name # ここはよくわからない。なぜこの条件…? # Allow build with no additional services.. if [ "mysql redis meilisearch mailpit selenium" == "none" ]; then ./vendor/bin/sail build else ./vendor/bin/sail pull mysql redis meilisearch mailpit selenium ./vendor/bin/sail build fi CYAN='\033[0;36m' LIGHT_CYAN='\033[1;36m' BOLD='\033[1m' NC='\033[0m' echo "" # 構築したディレクトリ配下の所有者を$USER変更 if sudo -n true 2>/dev/null; then sudo chown -R $USER: . echo -e "${BOLD}Get started with:${NC} cd project_name && ./vendor/bin/sail up" else echo -e "${BOLD}Please provide your password so we can make some final adjustments to your application's permissions.${NC}" echo "" sudo chown -R $USER: . echo "" echo -e "${BOLD}Thank you! We hope you build something incredible. Dive in with:${NC} cd project_name && ./vendor/bin/sail up" fi
Laravelのインストールにはlaravel/installerを利用している。
このlaravel/installerがバージョン指定できず、必ず最新のLaravelのバージョンを取得しているよう。なんでだろう。
Laravelの特定のバージョンを指定してインストールしたい場合には、laravel/installerを利用せず、composer経由でインストールを行えば良い。
コマンドとしては以下のようになる。
composer create-project "laravel/laravel={{ version_number }}" dirname
シェルスクリプトをバージョン指定できるように変更してみる。
先程の項で、シェルスクリプトを覗いた結果、どこの部分を変更すればLaravelの特定のバージョンを指定できるかがわかったので、それを反映してみる。
docker info >/dev/null 2>&1 # Ensure that Docker is running... if [ $? -ne 0 ]; then echo "Docker is not running." exit 1 fi docker run --rm \ --pull=always \ -v "$(pwd)":/opt \ -w /opt \ laravelsail/php82-composer:latest \ bash -c "composer create-project 'laravel/laravel={{ version }}' {{ project_name }} && cd {{ project_name }} && php ./artisan sail:install --with=mysql,redis,meilisearch,mailpit,selenium " cd {{ project_name }} # Allow build with no additional services.. if [ "mysql redis meilisearch mailpit selenium" == "none" ]; then ./vendor/bin/sail build else ./vendor/bin/sail pull mysql redis meilisearch mailpit selenium ./vendor/bin/sail build fi CYAN='\033[0;36m' LIGHT_CYAN='\033[1;36m' BOLD='\033[1m' NC='\033[0m' echo "" if sudo -n true 2>/dev/null; then sudo chown -R $USER: . echo -e "${BOLD}Get started with:${NC} cd project_name && ./vendor/bin/sail up" else echo -e "${BOLD}Please provide your password so we can make some final adjustments to your application's permissions.${NC}" echo "" sudo chown -R $USER: . echo "" echo -e "${BOLD}Thank you! We hope you build something incredible. Dive in with:${NC} cd project_name && ./vendor/bin/sail up" fi
大した変更はしてなくて、laravel new
しているところをcomposer create-project
としただけ。
使う機会あるかわからないけど、自分向けに。
withの部分やdevcontainerはお好きなように。
【備忘録】Laravel + Vue3 + Inertia.jsの環境構築方法
最近、LaravelとVueの組み合わせで苦しいという話があって、Inertia.jsがそれを救ってくれるかもしれないという話からInertia.jsを素振りし始めた。
ただ、Inertia.jsのInstallationでつまづいたので、備忘録として、ブログに残しておく
Laravelの環境構築
sailを使って、Laravelの環境構築を行う。DBはmysqlよりpostgresを利用したいため、withクエリでpgsqlを指定する。
# Laravelの環境構築 curl -s "https://laravel.build/{{ project_name }}?with=pgsql" | bash # {{ project_name }}に移動 cd {{ project_name }}
サーバーサイド側の設定
Laravelの環境構築が終わったらサーバーサイド側の設定を行っていく。
sailコマンドは、.bashrcまたは.zshrcにaliasを設定しているものとして、進めていく。
inertiajs/inertia-laravelのインストール
sail composer require inertiajs/inertia-laravel
インストール完了後は、以下コマンドを実行してミドルウェアを生成する。
sail artisan inertia:middleware
app/Http/Middleware/HandleInertiaRequests.php
が生成される。
app/Http/Kernel.php
の修正
先手順で生成したファイルを、app/Http/Kernel.php
ファイルに追記する。
<?php // 省略 protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, \App\Http\Middleware\HandleInertiaRequests::class, // <- 最後に追記 ], 'api' => [ // 省略 ], ];
optional1: tightenco/ziggy をインストールする
この手順は公式にもないため、オプションとなるが、設定をするとVueファイルからLaravelのルーティングをroute('routing.name')
このように指定可能となるため、便利。
以下コマンドで、tightenco/ziggyをインストールを行う。
# インストール sail composer require tightenco/ziggy
テンプレート追加
エントリポイントとなる、bladeファイルを追加する。
または既存のwelcome.blade.phpファイルをリネームする
touch resources/views/app.blade.php # or mv resources/views/welcome.blade.php resources/views/app.blade.php
テンプレート修正
先手順で追加したapp.blade.phpファイルの内容を以下の内容に変更する
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> @routes @vite('resources/js/app.js') @inertiaHead </head> <body> @inertia </body> </html>
@routesについては、optional: tightenco/ziggy をインストールするの項をスキップした場合は不要となる。
クライアントサイド側の設定
クライアントサイドの設定を行っていく。
このあたりの手順でつまづいた。
必要なパッケージのインストール
sail npm install @inertiajs/vue3 vue @vitejs/plugin-vue
vite.config.jsの設定
vite.config.jsの設定を行う
import { defineConfig } from "vite"; import laravel from "laravel-vite-plugin"; import vue from "@vitejs/plugin-vue"; export default defineConfig({ plugins: [ laravel({ input: ["resources/css/app.css", "resources/js/app.js"], refresh: true, }), vue({ template: { transformAssetUrls: { base: null, includeAbsolute: false, }, }, }), ], });
optional2: pluginを作る
optional: tightenco/ziggy をインストールするの項をスキップした場合は不要な手順。
tightenco/ziggyをインストールしただけでは、Vueのtemplateからroute
にはアクセスできないので、プラグインを作成し、Vueのtemplateからアクセスできるようにする。
以下コマンドでディレクトリとファイルを作る
mkdir resources/js/plugins touch resources/js/plugins/ziggy.js
プラグインを作ると言っても中身は単純で、以下の様に記載すれば良い。
export default { install(app) { app.config.globalProperties.$route = route; }, };
app.jsを編集
app.jsの編集を行う
import "./bootstrap"; import { createApp, h } from "vue"; import { createInertiaApp } from "@inertiajs/vue3"; import ziggy from './plugins/ziggy' createInertiaApp({ resolve: (name) => { const pages = import.meta.glob("./Pages/**/*.vue", { eager: true }); return pages[`./Pages/${name}.vue`]; }, setup({ el, App, props, plugin }) { createApp({ render: () => h(App, props) }) .use(plugin) .use(ziggy) .mount(el); }, });
まとめ
こんな感じで環境構築完了できた。
あとは、Laravelで普通に開発進めていけばSPAの開発が進んでいくので、体感はよいけどMPAの利点を捨てるのがどうなんだろうか…
SSRできるけど、本番環境にNode.js必要となるしね
ちなみにtightenco/ziggyを利用した際に気づいたんだけど、Laravelのルーティング設定毎にsail artisan ziggy:generate
を実行しないといけないのがめんどくさい。自動化できないものかな
2023/07/19追記: ziggyが自動的に生成されなくてだるいっていう話は、構築ミスによるものだった。
tightenco/ziggy#advanced-setupに記載されてる。
ただ、若干嫌な点としてroutingの情報がheadに全て載る。
@route使わないほうがいいかもなぁ。
date-ioっていうライブラリが便利そう。
Vuetify3系のアップデートとかを追ってて、2023年06月23日現在、Labsに含まれているuseDateっていうAPIを見ていて、date-ioという見慣れないライブラリがあった。少し調べたら、Material-UIのデートピッカーとかにも使われていた。
要は、Moment.jsとか、date-fnsとか、luxonとかの日付操作ライブラリの抽象化を行ってくれるライブラリで、date-ioを通すことで各ライブラリで異なるAPIを吸収してくれるもの。
手動でインターフェースの拡張可能なのでAPIが案件にフィットしなくても自分で解消できそう
とりあえずdate-ioとMoment.js組み合わせてサクッと作って後々いい感じのライブラリに切り替えるっていうのもそんなに負荷かからずにできそうなのかな。
試したリポジトリ github.com
【小ネタ】style要素にcontenteditableつけるとブラウザでリアルタイムにスタイリングできる
これ元ネタはTwitterで見たんだけど、いいねもブックマークもしていなかったのでどこかに流れてしまった。 備忘録含めてこちらにメモ。
body要素内にstyle要素を配置して、contenteditable属性を付与。style要素にdisplay: block; white-space: pre;のスタイルをあててあげると不思議とブラウザ上でリアルタイムにスタイリング可能な領域ができあがります。
上記clone後、index.htmlをブラウザで開くとなんとなく言ってること分かると思う。
仕様的な部分ってどうなの。
body内にstyle要素を含めるのは適切じゃないので、飽くまでお遊びです。
参考:HTML Standard 日本語訳
でもcontenteditable含むグローバル属性は指定可みたい。draggableとかautofucusとか要らなくね?なんとなく雑感。
実務では恐らく役に立たないけど、覚えとくと少しドヤれる…かも
追記
🔥 Weird one: Any HTML element can be visible and editable with display:block; and contenteditable - including style tags! pic.twitter.com/zRf2zFYb1i
— Wes Bos (@wesbos) October 29, 2022
見つけた。これこれ。
DenoのWebフレームワークfreshでパスワード生成アプリ作ってみた
作りました。めちゃくちゃ雑だけど。
なんで作ったのか。
fresh触りたかったから。
あと業務でVue2系しか触っていないので、React系統のライブラリを触っておきたいなーと思ったので。
これでなにかを解決!とかは全くないです。
機能
一応紹介しておきます。
以下の機能をアプリの主機能として実装してます。
正直特に言うことないです。ハイ。
- パスワード生成
- CSVに出力する機能
freshとはなに?
island architectureというのを採用しているフレームワークで、
サーバー側でレンダリングされる静的な部分と、インタラクティブ(JavaScriptによる動的)な部分を独立して表示させることが可能です。
今回作ったアプリでいうと、インプットフォーム周りと、生成したパスワードを一覧表示するテーブルをインタラクティブな部分として表示させています。
作ってみて
まぁ、楽しい。
今回のようなアプリケーションだと、freshのカスタムハンドラという機能を用いてサーバー側でパスワード生成してフロントに渡して出力するということも可能でした。
今回はサーバー側に処理させると割とすぐにタイムアウトになっちゃうのでフロント側に寄せたんですが、あんまり効果感じなかった…(謎
このアーキテクチャがメジャーになっていくのなら、設計が結構大変になってくるのかなと思った。
直接関係はないけど、フォームの処理結構手こずってしまった。expressとかちゃんと触ったことがなかったので、今後はNodejs、Denoのサーバ系の処理ちゃんと書けるようになりたいな〜