まくろぐ
更新: / 作成:

最近またビリヤードにちょこちょこ行くようになったので、むか〜し買ったキューを引っ張り出して初めてのタップ交換をしてみました(タップというのは先端部分の革のところです)。 15 年くらい放置してた古いキューです。おかえりなさい。

調べてみたら、タップって普通は数ヶ月とかで交換するものらしい。マジですか。 今回買ったのは、Kamui original というタップですけど 2500 円くらいします。 頻繁に交換するとなると結構な出費ですね。

タップは接着剤でくっつけてから、形を整えるために削っていくのですが、このときにフェラル(白いところ)を削ってしまうと取り返しがつかなくなるのでちょっと怖いです。 タップ自体も高いので失敗はできません。

さっそく挑戦です。ガクガク((( ;゚Д゚)))ブルブル

これが、

/p/ggpa2nk/img-001.jpg

こうなって、

/p/ggpa2nk/img-002.jpg

こう!

/p/ggpa2nk/img-003.jpg

できたっ! ٩(๑❛ᴗ❛๑)۶ わーぃ

ちょっとデコボコだけど、まぁまぁかな。 フェラルも少し削ってしまった気がするけどまぁいいや。 初めての柔らかめタップなので、撞いたときの感触が楽しみです。 このまえ久しぶりにビリヤードしたら全然球が入らなかったんですが、いいタップにしたので全て入るようになるはずです(違う)。

ちなみに、今はカーボン製のシャフトとかハイテクなシャフトが流行っているみたいです。 上の 20 年もののキューは、どノーマルキューです。 もはやビリヤード場でほとんど見かけることはなくなったかもしれませんが、撞き心地はとてもよいので大切にしたいです。

でもいい加減、最新のキューにもチャレンジしなきゃかなぁ。昔と比べてキュー高くなってるんですよね。。。

最後に今回使ったアイテムを広告。 タップは高いけど、交換用の道具は 1000 円もかかっていません。

  • 『タップ カムイ オリジナル S』 … 今は革の積層タップが主流らしい。2000円〜4000円くらいが相場ですかね。日本が誇るカムイは昔から積層タップを作り続けています。
  • 『セメダイン 3000 多用途』 … タップをくっつける接着剤は多用途がよいらしい。接着剤で打感が変わるという都市伝説もありますが、ご冗談でしょうファインマンさん。
  • 『プロ用 鋭黒片刃』 … 古いタップをきれいに取り除き、新しいタップの側面を削る。まっすぐ削るために片刃であることが重要らしいです。確かに削りやすかった。
  • 『紙ヤスリ #120』 … タップの接着面(GLUE と印字されている)は最初はツルツルでくっつかないのでまずはこの荒いヤスリで削ります。あと、最終的なタップの R 出しにも使えます。
  • 『紙ヤスリ #1000』 … タップの接着面は、上のヤスリで荒く削ったあと、これで綺麗にならしてからくっ付けます。実はこれかけない方がよく接着されそうな気もします。知らんけど。

関連記事

更新: / 作成:

統計のお勉強です。 標準正規分布の上側確率 の表を作ったので、それを使った問題に慣れます。

\( \lt \) と \( \leq \) の差(\( \gt \) と \( \geq \) の差)は微々たるものなので、ここでは気にしないことにします。

確率変数 \( X \) が標準正規分布に従うとき

問: 確率 \( P(X \gt 2) \) を求めよ

確率変数 \( X \) が標準正規分布に従うとき、つまり \( X \sim N(0, 1) \) のとき、確率 \( P(X \gt 2) \) は、標準正規分布の上側確率の表の 2.00 のところを見るだけで OK です。 上側確率は 0.0228 となっているので、

$$ P(X \gt 2) = 0.0228 $$

が答えです。

☝️ 正規分布の表現 正規分布のグラフの形状は平均と分散の 2 変数だけで決まります。 平均が \( \mu \)、分散が \( \sigma^2 \) の正規分布は一般的に \( N(\mu, \sigma^2) \) のように表現されます。 標準正規分布は平均が 0 で分散が 1 の正規分布なので \( N(0, 1) \) です。 確率変数 \( X \) が標準正規分布に従う場合、\( X \sim N(0, 1) \) と表現します(複数の確率変数 \( X_i \) がある場合は、\( X_i \sim N(0, 1) \) と表現されることもあります)。

問: 確率 \( P(X \lt -2) \) を求めよ

正規分布のグラフは左右対称なので、下側確率 \( P(X \lt -2) \) は上側確率 \( P(X \gt 2) \) と等しくなります。 よって、上側確率の表だけあれば求められます。

$$ \begin{align} P(X \lt -2) &= P(X \gt 2) \\ &= 0.0228 \end{align} $$

問: 確率 \( P(-2 \lt X \lt 2) \) を求めよ

全体の確率 1 から、上側確立 \( P(X \gt 2) \) と下側確率 \( P(X \lt -2) \) を引くことで求められます。

$$ \begin{align} P(-2 \lt X \lt 2) &= 1 - P(X \gt 2) - P(X \lt -2) \\ &= 1 - 2 P(X \gt 2) \\ &= 1 - 2 \times 0.0228 \\ &= 0.9544 \end{align} $$

確率変数 \( X \) が期待値 1、分散 9 の正規分布に従うとき

確率変数における「期待値」は「平均値」と考えてしまえばよいです。 この問題の分布は \( X \sim N(1, 3^2) \) ですが、これをどのように標準正規分布の上側確率の問題に落とし込むかがポイントです。

問: 確率 \( P(X > 2) \) を求めよ

確率変数 \( X \) は正規分布には従いますが、平均 0、分散 1 ではないので、そのままでは標準正規分布の上側確率の表が使えません。 そこで、以下のように標準化した確率変数 \( Z \) を作ります(平均を引いて標準偏差で割ります)。

$$ \begin{align} Z &= \frac{X - \mu}{\sigma} \\ &= \frac{X - 1}{3} \end{align} $$

すると、この確率変数 \( Z \) は平均 0、分散 1 の標準正規分布に従います(\( Z \sim N(0, 1) \))。 よって、\( P(X \gt ◯) \) という形の問題を \( P(Z \gt ●) \) という形に変換できれば、標準正規分布の上側確率の表を使って答えを求めることができます。

上の変換式から、\( X = 3Z + 1 \) なので、これを元々の問題である \( P(X \gt 2) \) の \( X \) に代入します。

$$ \begin{align} P(X \gt 2) &= P(3Z + 1 \gt 2) \\ &= P(3Z \gt 1) \\ &= P(Z \gt 1/3) \\ \end{align} $$

よって、標準正規分布の上側確率の 0.33 の部分を参照すればよく、答えは 0.3707 です。

次のように、元々の式全体を一気に標準化してしまう方法もあります。 やってることは同じですが、慣れるとこちらの方が速いです。

$$ \begin{align} P(X \gt 2) &= P(\frac{X - 1}{3} \gt \frac{2 - 1}{3}) \\ &= P(Z \gt \frac{2 - 1}{3}) \\ &= P(Z \gt 1/3) \\ &= 0.3707 \end{align} $$

問: 確率 \( P(-1 \lt X \lt 2) \) を求めよ

同様に、平均(期待値)1 と標準偏差 3 による標準化を行って \( P(Z \gt ●) \) の形に変換すれば OK です。

$$ \begin{align} P(-1 \lt X \lt 2) &= P(\frac{-1 - 1}{3} \lt \frac{X - 1}{3} \lt \frac{2 - 1}{3}) \\ &= P(\frac{-1 - 1}{3} \lt Z \lt \frac{2 - 1}{3}) \\ &= P(-\frac{2}{3} \lt Z \lt \frac{1}{3}) \\ &= 1 - P(Z > \frac{2}{3}) - P(Z > \frac{1}{3}) \\ &= 1 - 0.2514 - 0.3707 \\ &= 0.3779 \end{align} $$

(応用)合計値の平均と分散

問1

9800 ポンドの荷物を運べるエレベーターで、49 個の貨物を運ばなければいけないとします。貨物 1 つあたりの重さは、平均 \( \mu = \) 205 ポンド、標準偏差 \( \sigma = \) 15 ポンドの正規分布に従います。すべての貨物を安全に運べる確率を求めてください。

すべての荷物の重さの合計を \( T \) とおくと、この問題は確率 \( P(T \leq 9800) \) を求めよという問題です。 これも、\( T \) の分布を標準化して、\( P(Z \gt ●) \) の問題に書き換えられれば解決です。

標準化のためには、まずは \( T \) がどのような正規分布なのかが分からなければいけません。 貨物 1 つ当たりの重さの平均(期待値)が 205、標準偏差が 15 ということなので、それを 49 個集めた合計 \( T \) の平均は \( 10045 (= 205 \cdot 49) \)、標準偏差は \( 105 (= \sqrt{49} \cdot 15) \) になります。 つまり、\( T \) の分布は \( T \sim N(10045, 105^2) \) と書けます。

☝️ 合計値の平均と分散は n 倍になる 確率変数 \( X \) が平均 \( \mu \)、分散 \( \sigma^2 \) の正規分布に従うとき(\( X \sim N(\mu, \sigma^2) \))、それを \( n \) 個集めた合計 \( T \) の分布は、平均と分散がそれぞれ \( n \) 倍になります(\( T \sim N(n \cdot \mu, n \cdot \sigma^2) \))。 平均も分散も項の和の形で計算するものなので、その数が \( n \) 倍になれば、平均も分散も単純に \( n \) 倍になります。 ちなみに、標準偏差は \( \sqrt{n} \) 倍の \( \sqrt{n} \cdot \sigma \) になります。

確率変数 \( T \) の分布形状が分かったので、あとは問題とされている \( P(T \leq 9800) \) を標準化していくだけです。

$$ \begin{align} P(T \leq 9800) &= P(\frac{T - 10045}{105} \leq \frac{9800 - 10045}{105}) \\ &= P(Z \leq \frac{9800 - 10045}{105}) \\ &= P(Z \leq -2.333) \\ &= P(Z \geq 2.333) \\ &= 0.0099 \end{align} $$

問2

一人あたりのチケット購入枚数が、平均 \( \mu = \) 2.4 枚、標準偏差 \( \sigma = \) 2.0 枚の正規分布に従うとします。チケットの残りが 250 枚のとき、100 人が購入できる確率を求めてください。

合計購入枚数を確率変数 \( T \) とおくと、この問題は確率 \( P(T \leq 250) \) を求めよという問題です。 これを標準化して \( P(Z \geq ●) \) の形に持っていければゲームクリアです。

まず、確率変数 \( T \) がどのような正規分布なのかを考えます。 問題文より、1 人当たりの購入枚数を \( X \) とおくと、\( X \sim N(2.4, 2.0^2) \) です。 100 人の合計枚数 \( T \) では、\( T \sim N(100 \cdot 2.4, (10 \cdot 2.0)^2) \) になります (平均が 100 倍、標準偏差が 10 倍)。

確率変数 \( T \) の分布形状が分かった (\( \mu = 240, \sigma = 20 \)) ので、あとは標準化していきます。

$$ \begin{align} P(T \leq 250) &= P(\frac{T - 240}{20} \leq \frac{250 - 240}{20}) \\ &= P(Z \leq \frac{250 - 240}{20}) \\ &= P(Z \leq 0.5) \\ &= 1 - P(Z \gt 0.5) \\ &= 1 - 0.3085 \\ &= 0.6915 \end{align} $$

問3

あるガソリンスタンドで毎週購入されるガソリンの量は、平均 \( \mu = \) 50,000 ガロン、標準偏差 \( \sigma = \) 10,000 ガロンの正規分布に従います。 ガソリンの初期供給量は 74,000 ガロンで、毎週 47,000 ガロンの定期配達があります。 11 週間後の残りが 20,000 ガロン未満になる確率を計算してください。

11 週間の合計消費量を \( T \) とおくと、その分布は平均 \( 550000 = 50000 \cdot 11 \)、標準偏差 \( 10000 \cdot \sqrt{11} \) の正規分布に従います。

また、11 週間後の供給量合計は \( 74000 + 47000 \cdot 11 = 591000 \) ガロンで、残りが 20000 未満になる確率ということは、合計消費量 \( T \) が 571000 (= 591000 - 20000) ガロン以上になる確率を求めればよいことになります。

つまり、\( P(T \geq 571000) \) を求めればよいので、この式の \( T \) を標準化して標準正規分布に従う \( Z \) にして、\( P(Z \geq ●) \) の形にすれば解決です。

$$ \begin{align} P(T \geq 571000) &= P(\frac{T - 550000}{10000 \cdot \sqrt{11}} \geq \frac{571000 - 550000}{10000 \cdot \sqrt{11}}) \\ &= P(Z \geq \frac{571000 - 550000}{10000 \cdot \sqrt{11}}) \\ &= P(Z \geq 0.63…) \\ &= 0.2643 \end{align} $$

問4

あるガソリンスタンドで毎週購入されるガソリンの量は、平均 \( \mu = \) 50,000 ガロン、標準偏差 \( \sigma = \) 10,000 ガロンの正規分布に従います。 ガソリンの初期供給量は 74,000 ガロンで、毎週 47,000 ガロンの定期配達があります。 11 週間後の残りが 20,000 ガロン未満になる確率を 0.5% とするには、毎週の配達量は何ガロンにするべきでしょうか?

この問題は、毎週の供給量を求める問題ですが、簡単にするために 11 週間の 合計供給量を \( s \) とおいて、この値を求めることにします(最終的な答えは \( s / 11 \) になります)。

11 週間の 合計消費量を \( T \) と置くと、その分布は平均 \( 55000 \cdot 11 \)、標準偏差 \( 10000 \cdot \sqrt{11} \) の正規分布に従います。 式で書くと、\(T \sim N(550000, (10000 \cdot \sqrt{11})^2) \) です。

最初に 74,000 ガロンあって、\( s \) ガロン供給し、\( T \) ガロン消費するので、最終的に残っているガソリンは \( 74000 + s - T \) です。 この値が 20,000 ガロン未満になる確率が 0.5% ということは、以下のような式を満たす \( s \) の値を求めよということです。

$$ P(74000 + s - T \lt 20000) = 0.005 $$

標準正規分布(z 分布)の値を使うには、この式を標準化して、\( P(Z \gt ●) = 0.005 \) の形にする必要があります。 正規分布に従う \( T \) という確率変数が含まれているので、この \( T \) を左側に持ってくるとうまく標準化できます(\( T \) から平均を引いて標準偏差で割って \( Z \) にする)。

$$ \begin{align} P(74000 + s - T \lt 20000) &= P(T \gt 54000 + s) \\ &= P(\frac{T - 550000}{10000 \cdot \sqrt{11}} \gt \frac{54000 + s - 550000}{10000 \cdot \sqrt{11}}) \\ & = P(Z \gt \frac{54000 + s - 550000}{10000 \cdot \sqrt{11}}) \end{align} $$

ここで、標準正規分布の上側確率 が 0.005 になる z 値を確認すると、約 2.575(2.57 と 2.58 の間)ということが分かります。 つまり、標準化された \( Z \) を使うと次のように表現できます。

$$ P(Z \gt 2.575) = 0.005 $$

この 2.575 という値は、前述の式の \( P(Z \gt ●) \) の ● の部分と同じ値になるはずなので、以下のような方程式が成り立ちます。

$$ \frac{54000 + s - 550000}{10000 \cdot \sqrt{11}} = 2.575 $$

あとは、これを計算すれば \( s \approx 581403 \) という値が求まります。 \( s \) は 11 週間の合計供給量なので、1 週間あたりの供給量は \( s / 11 = 52854.8 \) になります。

Python で計算する例
>>> s = 2.575 * 10000 * math.sqrt(11) + 550000 - 54000
>>> print("{:.1f}".format(s/11))
52854.8

(応用)標本平均 \( \bar{x} \) の平均 \( s_{\bar{x}} \) と分散 \( s^2_{\bar{x}} \)

問1

母集団は、平均 \( \mu = \) 500、標準偏差 \( \sigma = \) 80 の正規分布とします。 ここからサイズ 100 の標本を抽出したとき、標本平均 \( \bar{x} \) が (490, 510) の範囲に入る確率を求めてください。

この問題は、サイズ n の標本の平均値(標本平均 \( \bar{x} \))がどのように分布するかという問題です。 標本平均を \( \bar{X} \) とすると、\( P(490 \lt \bar{X} \lt 510) \) を求めよという問題です。 なので、標本平均の分布がどのような正規分布になるかが分かればクリアです。

正規分布 \( N(\mu, \sigma^2) \) に従う母集団から n 個のサンプルを抽出してその平均(標本平均)を取ると、標本平均は \( N(\mu, \frac{\sigma^2}{n}) \) の正規分布に従います。 平均は同じで、分散が \( \frac{1}{n} \)(標準偏差は \( \frac{1}{\sqrt{n}} \))に減少するということですね(証明は省略)。

今回のケースでは、標本平均の分布は平均 が \( \mu = 500 \) のままで、標準偏差が \( \sigma = \frac{80}{\sqrt{100}} = 8 \) の正規分布に従うことになります (\( \bar{X} \sim N(500, 8^2) \))。 分布が分かったので、あとは標準化していきます。

$$ \begin{align} P(490 \lt \bar{X} \lt 510) &= P(\frac{490 - 500}{8} \lt \frac{\bar{X} - 500}{8} \lt \frac{510 - 500}{8}) \\ &= P(-\frac{10}{8} \lt Z \lt \frac{10}{8}) \\ &= P(-1.25 \lt Z \lt 1.25) \\ &= 1 - 2 \cdot P(Z \geq 1.25) \\ &= 1 - 2 \cdot 0.1056 \\ &= 0.7888 \end{align} $$

問2

母集団は、平均 \( \mu = \) 500、標準偏差 \( \sigma = \) 80 の正規分布とします。 ここからサイズ 100 の標本を抽出したとき、標本平均の分布が中央 95% をカバーする区間を求めてください。

標本平均を \( \bar{X} \) とおくと、\( P(a \leq \bar{X} \leq b) = 0.95 \) となる \( a \) と \( b \) の値を求めよという問題です。 標本平均 \( \bar{X} \) の分布は、平均 500 (\( = \mu \)) 、標準偏差 8 (\( = \frac{\sigma}{\sqrt{n}} = \frac{80}{\sqrt{100}} \)) に従います。

中央 95% (0.95) をカバーする領域というのは、言い換えると、両端の 5% を除いた残りの部分ということになります。 標準正規分布の上側確率の表から、上側確率 0.025 (2.5%) になる部分を探すと、\( P(z \gt 1.96) \) の領域だということが分かります。

つまり、標本平均 \( \bar{X} \) 標準化した値を \( Z \) としたときの、\( -1.96 \leq Z \leq 1.96 \) が求める区間になります。 標準化は \( Z = \frac{\bar{X} - 500}{8} \) という計算を行った結果ですから、これを代入すれば \( \bar{X} \) 基準での区間が求まります。

$$ \begin{align} -1.96 \leq Z \leq 1.96 &= -1.96 \leq \frac{\bar{X} - 500}{8} \leq 1.96 \\ &= -15.68 \leq \bar{X} - 500 \leq 15.68 \\ &= 484.32 \leq \bar{X} \leq 515.68 \end{align} $$

関連記事

更新: / 作成:

何をするか

Vite は TypeScript ビルドや、開発用サーバー、バンドリングなどの機能を備えた統合的なフロントエンド開発ツールです。 ここでは、Vite で複数の TypeScript ファイルを 1 つの JavaScript ファイルの形にビルドする方法を説明します(この作業をバンドルと呼びます)。

/p/59mfj7b/img-001.drawio.svg
図: 複数の .ts/.css/.svg ファイルを 1 つの JavaScript ファイルに結合

最終的な成果物として、複数の Web サイトから <script> 要素で読み込み可能な JavaScript ライブラリ を作成することを想定しています。 画像ファイルやスタイルシート (CSS) などのリソースファイルも、単一の JavaScript に埋め込む形でバンドルできます。

Vite プロジェクトの作成

npm create vite コマンドを使って Vite のプロジェクトを作成します。 React などのフレームワークを使わず、純粋な TypeScript ファイルをビルドするだけであれば、ウィザードに従って、VinillaTypeScript と選択していきます。

Vite プロジェクト (myscript) を生成する
$ npm create vite@latest myscript
✔ Select a framework: › Vanilla
✔ Select a variant: › TypeScript
$ cd myscript

次のようなファイルが生成されます。

myscript/
  +-- .gitignore
  +-- index.html  # <script> 要素による表示の確認用
  +-- package.json
  +-- tsconfig.json
  +-- public  # 最終的には必要なし
  |    +-- vite.svg
  +-- src/  # 最終的には全部書き換える
       +-- counter.ts
       +-- main.ts
       +-- style.css
       +-- typescript.svg
       +-- vite-env.d.ts

src ディレクトリにはサンプル実装の TypeScript コードや画像ファイルが入っているので、この中身は最終的には全部書き換えることになります。 その他の package.jsontsconfig.json などは大部分は使いまわせるはずです。

プロジェクトが生成されたら、依存パッケージ (tsc, vite) をインストールしておきます。

$ npm install

bundle.js 出力用のプロジェクトに書き換える

他の Web サイトから 1 つの <script> 要素で利用可能なライブラリにするには、複数の TypeScript ファイルを単一の JavaScript ファイルの形にバンドルする必要があります。 テンプレートとして生成されたプロジェクトを npm run build (tsc & vite build) でそのままビルドすると、Web サイト用の index.html や各種アセットファイル (.css, .js) などが出力されてしまいます。 そこで、下記の設定手順に従い、1 つの JavaScript ファイルとして出力するようカスタマイズする必要があります。

CSS ファイルを .js ファイルに埋め込む

テンプレートプロジェクトの main.ts ファイルでは、import "./style.css" のように外部の CSS ファイルを読み込んでいます。 デフォルトでは CSS ファイルは独立したアセットファイルとして出力されてしまうので、1 つの JavaScript ファイルに埋め込むように設定する必要があります。 もちろん、CSS ファイルを使わないプロジェクトではこの設定は必要ありません。

CSS を JavaScript に埋め込むための vite-plugin-css-injected-by-js という Vite プラグインが公開されているのでこれをインストールします。

$ npm install vite-plugin-css-injected-by-js --save-dev

vite.config.ts の作成

vite.config.ts.js でも可)を作成して、単一の dist/bundle.js ファイルとして出力するように設定します(この設定を Library Mode と呼びます)。 上記でインストールした Vite プラグインはここで読み込みます。 出力ファイル名は dist/bundle.js としています。

vite.config.ts
import { defineConfig } from "vite";
import cssInjectedByJsPlugin from "vite-plugin-css-injected-by-js";

export default defineConfig({
  plugins: [cssInjectedByJsPlugin()], // CSS を JS に埋め込むプラグイン
  build: {
    lib: {
      entry: "src/main.ts",
      formats: ["iife"], // Web サイト組み込み用に即時実行形式 (function(){})() で出力
      name: "MyScript", // static API 用のグローバルオブジェクト名
    },
    rollupOptions: {
      output: {
        dir: "dist", // 出力ディレクトリ (default: dist)
        entryFileNames: "bundle.js", // 出力ファイル名
      },
    },
  },
});

ビルド

リリース用の JavaScript ファイルを生成するには、npm run build (=tsc & vite build) コマンドでビルドします。 次のように dist/bundle.js だけが生成されれば成功です。

$ npm run build
...
✓ 5 modules transformed.
dist/bundle.js  3.81 kB │ gzip: 2.02 kB

bundle.js ファイルの内容を見ると、svg ファイルや css ファイルの内容がインラインで埋め込まれていることを確認できます。

開発用サーバー

Vite の開発サーバーを起動すると、src/main.ts ファイルの修正を監視してリアルタイムに表示内容を確認できます。 開発中はこの機能を使うと便利です。

開発サーバーを起動してついでにブラウザで開く
$ npm run dev -- --open

次のように index.html の内容が表示されれば成功です。 ちなみに今回の用途では、index.html ファイルは完全に開発時の表示確認用になります。

/p/59mfj7b/img-002.png
図: bundle.js の動作確認

とはいっても、dist/bundle.js ファイルは特にサーバーサイドで実行する必要はないので、次のような HTML ファイルを作成して、ローカルファイルとして Web ブラウザで開くことでも動作確認できます(public/ ディレクトリ以下の vite.svg ファイルなどは参照できなくなりますが)。

test.html
<!doctype html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Test</title>
    <script src="./dist/bundle.js" defer></script>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

その他

public/ ディレクトリには、そのまま Web サイト用のリソースとしてデプロイされる画像ファイルなどが格納されていますが、今回の用途では必要ないのでディレクトリごと削除してしまっても大丈夫です。 public/ ディレクトリを削除した場合は、ソースコード内の vite.svg を参照している箇所も削除してください。

(応用)UI 部分に Svelte を使う方法

HTML の UI 部分を出力するような JavaScript ライブラリーを作成する場合は、Svelte などのフレームワークを使うと便利です。 React や Vue などのフレームワークも同様に使えますが、最終的なリリース物が大きくなりがちなので、小規模なライブラリーの場合は Svelte を使うことをお勧めします。

Vite + Svelte プロジェクトの作成

Vite のプロジェクトを作成する際に、フレームワークとして Svelte を使うよう指定します。

Vite プロジェクトを生成する(Svelte 用のテンプレートを使用)
$ npm create vite@latest myscript
✔ Select a framework: › Svelte
✔ Select a variant: › TypeScript

$ cd myscript
$ npm install

先ほどと同様に、CSS コードを JavaScript に埋め込むための Vite プラグインをインストールしておきます。

CSS 埋め込み用の Vite プラグインをインストール
$ npm install vite-plugin-css-injected-by-js --save-dev

実装

vite.config.ts ファイルを編集して、Svelte や CSS のコードを単一の JavaScript ファイル (dist/bundle.js) にバンドルするように設定します。

vite.config.ts (Svelte)
import { defineConfig } from "vite";
import { svelte } from "@sveltejs/vite-plugin-svelte";
import cssInjectedByJsPlugin from "vite-plugin-css-injected-by-js";

export default defineConfig({
  plugins: [svelte(), cssInjectedByJsPlugin()],
  build: {
    lib: {
      entry: "src/main.ts",
      formats: ["iife"], // Web サイト組み込み用に即時実行形式 (function(){})() で出力
      name: "MyScript", // static API 用のグローバルオブジェクト名
    },
    rollupOptions: {
      output: {
        dir: "dist", // 出力ディレクトリ (default: dist)
        entryFileNames: "bundle.js", // 出力ファイル名
      },
    },
  },
});

下記は、Svelte コンポーネントによる UI 実装の例です。 ここでは同じディレクトリにある svelte.svg という画像ファイルをインポートしていますが、このようにインポートした画像ファイルは、最終的に出力ファイルである JavaScript ファイルにバンドルされます。

src/App.svelte
<script lang="ts">
  import svelteLogo from './svelte.svg';

  let count = 0;
  function increment() {
    count += 1;
  }
</script>

<div class="container">
  <img src={svelteLogo} alt="Svelte Logo" />
  <button on:click={increment}>
    Clicked {count} {count === 1 ? 'time' : 'times'}
  </button>
</div>

<style>
  .container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
  }

  img {
    height: 6em;
    padding: 1.5em;
    will-change: filter;
    transition: filter 300ms;
  }

  img:hover {
    filter: drop-shadow(0 0 2em #ff3e00aa);
  }
</style>

エントリーポイントとなる src/main.ts では、上記の App.svelte を読み込んで document.body にマウントするようにしておきます。

src/main.ts
import App from "./App.svelte";

new App({ target: document.body });

テスト

ローカルテスト用の index.html ファイルでは、<script> タグでエントリーポイントとなる /src/main.ts を読み込むようにしておきます。

index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + Svelte + TS</title>
  </head>
  <body>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

開発サーバーを起動して、ブラウザで表示を確認します。

開発サーバーを起動してついでにブラウザで開く (Svelte)
$ npm run dev -- --open

次のように表示されれば成功です。

/p/59mfj7b/img-003.png
図: Vite + Svelte の動作確認

リリース用ビルド

npm run build コマンドでリリース用の JavaScript ファイルを生成します。

リリース用ビルド(bundle.js の生成)
$ npm run build

出力された dist/bundle.js は、他の Web サイトから <script> 要素で読み込むことができる単一の JavaScript ライブラリーになっています。 次のように defer 属性を付けて読み込むと、ページの読み込みが完了してから JavaScript ファイルが実行され、自動的に App.svelte コンポーネントが表示されます。

他の Web サイトから読み込む例
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + Svelte + TS</title>
    <script src="./bundle.js" defer></script>
  </head>
  <body>
    <!-- ... -->
  </body>

もちろん、別のサーバーで bundle.js をホスト(共有)して、各 Web サイトから読み込むことも可能です。

٩(๑❛ᴗ❛๑)۶ わーぃ

関連記事

メニュー

まくろぐ
サイトマップまくへのメッセージ