⚙️

Svelte5でJSライブラリを作成する方法(素のJS向けにビルドする方法)

に公開

まえがき

なんのJSフレームワークも使っていない純粋な HTML, CSS, JS で構成されたプロジェクトに、リッチな機能を組み込みたい!みたいなときありますよね。

そういうときにSvelteで実装するための備忘録です。

ただSvelteが書きたいだけで細かい設定とかに頭使いたくないですよね。

下準備

セットアップコマンドを実行してセットアップする

公式に書いてある通りにセットアップします。

https://svelte.jp/docs/kit/creating-a-project

npx sv create my-app

my-app のところは自由に変更しても良い。
省略するとおそらく今のディレクトリに作られる。

設定は Svelte library を選択。それ以外は好きなもので良い。
(もしかしたら Svelte library じゃなくても良いかも)

終わったら作ったディレクトリに移動する

cd my-app で移動する。

動くか確認する

npm run dev を実行し o + Enter でブラウザを開き Welcome to your library project みたいなページがブラウザで開けばOK。

ライブラリにしたいコンポーネントを準備する

src/lib/Main.svelte に以下のようなファイルを作る。

src/lib/Main.svelte
<script lang="ts">
  let count = $state(0);
</script>

<button onclick={() => count++}>click {count}</button>

<style>
  button {
    color: blue;
  }
</style>

ファイル名は何でもいいし場所もlibじゃなくてもいい。

作ったコンポーネントの動作を確認する

src/routes/+page.svelte

src/routes/+page.svelte
<script>
  import Main from '$lib/Main.svelte';
</script>

<Main></Main>

クリックするとカウントが増えるだけのボタン。

JSライブラリ向けにビルドするための設定をする

ここからが本番です。普通にビルドするとSvelte向けにビルドされます。

index.ts(js) で作ったコンポーネントを export する

src/lib/index.ts

src/lib/index.ts
export { mount } from 'svelte';
export { default as Main } from './Main.svelte';

npm run build を修正

package.json
-"build": "vite build && npm run prepack",
+"build": "vite build",

vite.config.ts(js) の設定を修正

vite.config.ts
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import { resolve } from 'path';
import { svelte } from '@sveltejs/vite-plugin-svelte';

export default defineConfig(({ command }) => ({
  plugins: [command === 'build' ? svelte() : sveltekit()],
  build: {
    lib: {
      entry: resolve(__dirname, 'src/lib/index.ts'),
      formats: ['umd'],
      name: 'components',
      fileName: 'components',
    },
    outDir: 'dist',
  },
}));

  • defineConfig の引数で command を受け取って build かどうか判定
  • build なら svelte() にする
  • umd でビルドするように設定を追記する
  • name, fileName はなんでもいい
  • 細かい説明は端折ります

ビルドしてみる

npm run build を叩く。

dist に js と css が出来上がっている。

実際に読み込んで動くか試す

適当に index.html とかを作って読み込んでブラウザで開くと動いてるのが確認できる。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Main</title>
  <!-- ビルドした js と css を読み込む -->
  <script src="./dist/components.umd.cjs"></script>
  <link rel="stylesheet" href="./dist/components.css">
</head>
<body>
  <div id="main"></div>
  <script>
    {
      const { mount, Main } = components;
      mount(Main, {
        target: document.getElementById('main'),
      });
    }
  </script>
</body>
</html>

あとがき

svelte4 から svelte5 に変わってコンポーネントのマウント方法がnewからmountになっていたのがちょっとした罠でした。

これでもう今後は迷うことなくできそうです。

Discussion