petite-vue というライブラリがあります。
Vue.js の代替ディストリビューションという説明がリポジトリの README にあります。
これを動作確認する環境として、packupを採用したら快適だったのでメモです。
参考
導入
docker 環境準備
packup は、deno で動作するアプリケーションパッケージャーなので、deno 用の docker 環境を用意します。
dockerfile1 2 3 4 5 6 7
| FROM denoland/deno:centos
RUN mkdir /usr/src/app WORKDIR /usr/src/app
EXPOSE 8080 EXPOSE 35729
|
docker-compose.yml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| version: "3" services: app: build: context: . dockerfile: Dockerfile privileged: true entrypoint: - /sbin/init ports: - "8080:8080" - "35729:35729" volumes: - .:/usr/src/app:cached tty: true
|
ポート 35729 を公開しておくのが、packup を実行する上ではポイントです。
自動リロード関連の為に空いているポートの様です。
Docker 環境でディレクトリをマウントしていると、ファイル監視が効かないです。
(これは回避策がわからないのでどうにかしたい。)
が、ブラウザから通信先になっており他のロードに影響してしまうので、開けておきましょう。
packup を導入
README 通りの導入を進めます。
1 2 3 4 5 6
| $ deno run -A https://deno.land/x/packup@v0.1.12/install.ts $ which packup /usr/local/bin/packup
$ mkdir static
|
index.html を作成。
index.html1 2 3 4 5 6
| <html> <body> <script src="./main.ts"></script> <h1>Hi from packup!</h1> </body> </html>
|
main.ts を作成。
main.ts1
| console.log("hello world");
|
次のコマンドで起動。
1
| $ packup -p 8080 index.html
|
ブラウザで、localhost:8080 にアクセスするとページを取得できます。
次のコマンドでビルドをできました。
1
| $ packup build index.html
|
dist
ディレクトリが作成され index.fccc32343a257ba23b7683a823b9c262.js
が作成されていました。
index.fccc32343a257ba23b7683a823b9c262.js1 2 3 4
| (() => { console.log("hello world"); })();
|
petite-vue を導入
petite-vue の README に従い導入してみます。
index.html[書き換え1]1 2 3 4 5 6 7 8 9 10 11
| <html> <body> <script src="https://unpkg.com/petite-vue" defer init></script>
<div v-scope="{ count: 0 }"> {{ count }} <button @click="count++">inc</button> </div> </body> </html>
|
ボタンを押すと数字のカウントアップされるものが動きます。
少し書き換えてカウンターを2つ用意します。
index.html[書き換え2]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| <html lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head>
<body> <script type="module"> import { createApp } from "https://unpkg.com/petite-vue?module";
function counter() { return { count: 0, clickCount: 0, get getClickCount() { return `${this.clickCount}回`; }, increment() { this.count++; this.clickCount++; }, decrement() { this.count--; this.clickCount++; }, }; }
createApp({ counter, }).mount("#app1");
createApp({ counter, }).mount("#app2"); </script>
<div v-scope="counter()" id="app1"> <p>{{ count }}({{ getClickCount }})</p> <button @click="increment">increment</button> <button @click="decrement">decrement</button> </div>
<div v-scope="counter()" id="app2"> <p>{{ count }}({{ getClickCount }})</p> <button @click="increment">increment</button> <button @click="decrement">decrement</button> </div> </body> </html>
|
動作させると、独立して動作するカウンターと総クリック数が2つ表示できています。
これよりも高度な使い方は README に記載が有るので、そちらを参照。
テンプレートも使えるのが面白そうです。
petite-vue を packup でバンドル
本題の petite-vue を packup でバンドル をやってみます。
せっかくバンドルするので、color-hashも使ってみます。
クリックするたびに色が変わるという具合ですね。
main.ts[書き換え1]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import ColorHash from "https://deno.land/x/color_hash@v2.0.0/mod.ts"; import { createApp } from "https://cdn.skypack.dev/petite-vue";
const colorHash = new ColorHash();
function counter() { return { count: 0, clickCount: 0, get getClickCount() { return `${this.clickCount}回`; }, get getColor() { return colorHash.hex(`${this.clickCount}`); }, increment() { this.count++; this.clickCount++; }, decrement() { this.count--; this.clickCount++; }, }; }
createApp({ counter, }).mount("#app1");
createApp({ counter, }).mount("#app2");
|
petite-vue のロード先を unpkg から skypack に切り替えています。
切り替えないと次のエラーになります。
1 2
| deno:file:///usr/src/app/page/main.ts:27:26: error: [plugin: deno] Unreachable. 27 │ import { createApp } from 'https://unpkg.com/petite-vue?module'
|
続けて HTML は次の用意なります。script がスッキリしました。
index.html[書き換え3]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <html lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head>
<body> <script type="module" src="./main.ts"></script>
<div v-scope="counter()" id="app1"> <p v-bind:style="{color: getColor}">{{ count }}({{ getClickCount }})</p> <button @click="increment">increment</button> <button @click="decrement">decrement</button> </div>
<div v-scope="counter()" id="app2"> <p v-bind:style="{color: getColor}">{{ count }}({{ getClickCount }})</p> <button @click="increment">increment</button> <button @click="decrement">decrement</button> </div> </body> </html>
|
動かしてみると次のようになります。
petite-vue を packup でバンドルして使うことができました。
今回は、petite-vue のバンドルを試すにあたって vite でやろうかとも考えたものの、packup を
試してみてよかったです。
aleph や Ultra などのガチっとした react のフレームワークではなく、Deno での軽いページの開発に適したものが無かったので、とてもフィットしていました。
petite-vue は、READMEに「少しのインタラクションを振りかける」といったような表現が出てきます。
stimulus に思想が近いなぁと感じていましたが、同じような言説や、そもそもそこが意識されているという記述も見かけます。
WEBの開発も軽重有るのでこういったものもありがたいものです。
既存のVueの知識も生かせるので。(jQuery の知識が薄すぎるので、あれなだけですけれども。)
ではでは。