ウェブ開発で、過去に作ったUI部品やアルゴリズムを再利用できると便利ですよね!今回は、Viteを使って「Hello World」を表示するシンプルなライブラリーを作成し、どのようにして他のプロジェクトに組み込むかを解説します。
はじめに
再利用可能なライブラリーを作っておくと、コードをメンテナンスしたり、他プロジェクトでの応用するときに非常に役立ちます。この記事では、Viteを使用して、背景色を虹色に輝かせる「Hello World」を表示するJavaScriptライブラリーの作り方をステップ・バイ・ステップで紹介します。
この記事に記載したソースコードはこちらで公開しています。
1. プロジェクトのセットアップ
まず、Viteを使ってプロジェクトをセットアップします。以下の手順に従って進めてください。
Viteのインストール
npm init vite@latest hello-lib
途中で選択肢が出てきます。今回は素の(Valnilla)JavaScriptで開発してみるので、以下を選択してください。
✔ Select a framework: › Vanilla
✔ Select a variant: › JavaScript
プロジェクトの初期化後、依存関係をインストールします。
cd hello-lib
npm install
2. 不要なファイルの削除と、必要なディレクトリー・ファイルの追加
この状態でnpm run dev
を実行するとViteを使ったカウンターアプリを実行できます。ただ今回は不要なので、削除しておきます。
rm *.html *.css *.js *.svg
rm -rf public
今回、ライブラリーのソースコードはsrc
ディレクトリーの下に作っていきます。
mkdir src
また、gitで管理するときに、誤って余計なファイルを公開してしまわないよう、.gitignore
ファイルを作っておきます。また、gitを初期化しておきます。
curl https://raw.githubusercontent.com/vitejs/vite/main/.gitignore -o .gitignore
git init
3. HTMLテンプレートの作成
次に、表示するコンテンツである「Hello World」のHTMLテンプレートを作成します。さらに、背景色を虹色に輝かせるCSSを追加してスタイルを整えます。
<div class="hello-world">Hello World!</div>
.hello-world {
font-size: 24px;
color: white;
background-image: linear-gradient(
270deg,
red,
orange,
yellow,
green,
blue,
indigo,
violet
);
background-size: 400% 400%;
animation: rainbowBackground 5s ease infinite;
padding: 10px;
border-radius: 5px;
}
@keyframes rainbowBackground {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
4. Injectionロジックの実装
ここでは、テンプレートとスタイルをウェブページに挿入するJavaScriptコードを実装します。HelloLib.init()
関数を作成し、指定されたDOM要素にHTMLとCSSを挿入します。
import template from './template.html?raw';
import style from './style.css?raw';
const HelloLib = {
init(container) {
const styleElement = document.createElement('style');
styleElement.innerHTML = style;
document.head.appendChild(styleElement);
container.innerHTML = template;
}
};
export default HelloLib;
ファイルを文字列としてインポートする?raw
今回制作するライブラリーは、テンプレートのHTMLやCSSを文字列としてインポートして、動的に注入します。Viteでは外部ファイルをimport
でインポートする際、ファイル名の末尾に?raw
をつければ文字列として扱えます。
外部から参照するためのexport default
モジュールとして定義したHelloLibを外部から参照できるようにするため、export default HelloLib;
を記述しておくことは非常に重要です。詳しくはビルドの章で説明します。
5. ライブラリーのビルドとパッケージ化
ライブラリーをビルドしてパッケージ化するには、vite.config.js
ファイルを設定し、ライブラリーモードを利用する必要があります。このファイルはプロジェクトのルートディレクトリーに置きます。
import { defineConfig } from 'vite';
export default defineConfig({
build: {
lib: {
entry: './src/main.js',
name: 'HelloLib',
formats: ["es", "umd"],
fileName: (format) => `hello-lib.${format}.js`,
},
},
});
ビルドコマンド
次に、以下のコマンドを実行してライブラリーをビルドします。
npm run build
実行結果は次の通りです:
> hello-lib@0.0.0 build
> vite build
vite v5.4.3 building for production...
✓ 3 modules transformed.
dist/hello-lib.es.js 0.36 kB │ gzip: 0.26 kB
dist/hello-lib.umd.js 0.59 kB │ gzip: 0.41 kB
✓ built in 29ms
ESMとUMDの違い
ビルドが完了すると、dist
フォルダに2つの形式のファイルが生成されます。
ESM形式 (hello-lib.es.js
)
JavaScriptのESモジュール(ESM)形式のファイルです。ESM形式は、モジュールを他のモジュールとしてインポートするための標準的な仕組みです。
ESM形式では、import文を使ってモジュールを読み込みます。例えば、他のJavaScriptファイルで以下のようにインポートします。
import HelloLib from './dist/hello-lib.es.js';
HelloLib.init(container);
モダンなブラウザや、ESMをサポートするNode.js環境で使用されます。
開発時には、ESM形式を使って直接モジュールを利用し、動作確認ができるようにします。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>HelloLib Example</title>
</head>
<body>
<div id="hello-container"></div>
<script type="module">
import HelloLib from './src/main.js';
const container = document.getElementById("hello-container");
HelloLib.init(container);
</script>
</body>
</html>
UMD形式 (hello-lib.umd.js
)
UMD(Universal Module Definition)形式は、モジュールをブラウザやNode.jsの両方で動作させるために使用される形式です。UMD形式では、グローバルスコープにモジュールが自動的に定義されます。
UMD形式では、<script>
タグで読み込むと、HelloLibがグローバルオブジェクトとして定義され、直接利用できます。
<script src="/dist/hello-lib.umd.js"></script>
<script>
const container = document.getElementById('hello-container');
HelloLib.init(container);
</script>
UMD形式は、ブラウザやNode.jsの両方で動作するため、幅広い環境で使用されます。
ビルドしたUMD形式のファイルが正しく動作しているかを確認するため、test
ディレクトリーを作り、その下に確認用のindex.html
を置いて動作を確認できるようにします。
mkdir test
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>Test of HelloLib Example</title>
</head>
<body>
<h3>Test</h3>
<div id="hello-container"></div>
<script src="../dist/hello-lib.umd.js"></script>
<script>
const container = document.getElementById("hello-container");
HelloLib.init(container);
</script>
</body>
</html>
6. 動作確認
ホットリロードを活用した効率的な開発
前述した通り、ESM形式を使うindex.html
と、UMD形式を使うtest/index.html
を準備したら、動作を確認してみます。
開発用サーバーを実行し、index.html
でHello Worldが正しく表示されているかを確認します。ホットリロードが有効になっているため、関連するソースコードを変更すると自動的に再読み込みされます。
npm run dev
を実行して、表示されたURLにアクセスしてみましょう。
VITE v5.4.3 ready in 89 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help
ビルドした成果物の動作確認
開発が一段落したら、ビルドで出力されたライブラリーが正しく動作しているかを確認します。
npm run build
でビルドが成功したら、test/index.html
を開いて正しく表示されることを確認します。
7. ライブラリーの設定をpackage.json
に追加
ライブラリーがさまざまなJavaScriptの環境でスムーズに動作するよう、公式ドキュメントが推奨するpackage.json
の記述を追記しておきます。
{
"name": "hello-lib",
"private": true,
"version": "0.0.0",
"type": "module",
"files": [
"dist"
],
"main": "./dist/hello-lib.umd.js",
"module": "./dist/hello-lib.es.js",
"exports": {
".": {
"import": "./dist/hello-lib.es.js",
"require": "./dist/hello-lib.umd.js"
}
},
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"devDependencies": {
"vite": "^5.4.1"
}
}
追記する項目について説明します。
-
files
フィールド
files: 公開時にnpmパッケージに含めるファイルを指定します。パッケージを軽量化するため、不要なファイルのみを定義します。 -
main
フィールド
main: CommonJS形式のエントリーポイントを指定します。これは、古いJavaScript環境やNode.jsで使われる形式です。ここでは、ビルドしたUMD形式のファイルを指定します("main": "./dist/hello-lib.umd.js"
)。 -
module
フィールド
module: ESモジュール形式(ESM)でのエントリーポイントを指定します。これは、モダンなブラウザやJavaScript環境で利用される形式です("module": "./dist/hello-lib.es.js"
)。
main
とmodule
の2つのフィールドを指定することで、ユーザーは自動的に環境に応じて適切な形式を選択してライブラリをインポートできます。 -
exports
フィールド
exports: ライブラリがどの形式でエクスポートされるかを詳細に定義します。これにより、環境ごとに適切なビルド形式を提供できます。たとえば、ESM形式が必要な場合と、CommonJS形式が必要な場合のパスを指定できます。以下の例は、import
を使用する場合はESM
が、require
を使用する場合はUMD/CJS
が読み込まれるようになります。
{
"exports": {
"./": {
"import": "./dist/hello-lib.es.js",
"require": "./dist/hello-lib.umd.js"
}
}
}
.cjs
ファイルについての注意事項
Viteのライブラリーモードでビルドを行う際、vite.config.js
でfileName
を指定しないと、UMD形式のファイルはデフォルトで拡張子.cjs
として出力されます。しかし、.cjs
拡張子はNode.jsでのCommonJSモジュールとして使用されることが一般的であり、ブラウザでは適切に処理されない場合があります。
特に、Cloudflareなどのホスティングサービスでは、.cjs
ファイルがapplication/node
というMIMEタイプで提供されることがあります。このMIMEタイプはブラウザでは実行できないため、次のようなエラーが発生します。
Refused to execute script from 'https://your-site/dist/hello-lib.umd.cjs' because its MIME type ('application/node') is not executable.
このエラーは、ブラウザが.cjs
ファイルをNode.js専用のモジュールとして認識してしまうためです。この問題を回避するためには、vite.config.js
でformats
とfileName
を明示的に指定し、UMD形式のファイルを.js
として出力する設定に変更します。
lib: {
...
formats: ["es", "umd"],
fileName: (format) => `hello-lib.${format}.js`,
これにより、ビルドされたUMD形式のライブラリーは.js
拡張子で出力され、クラウドホスティングサービス上でのMIMEタイプエラーを防ぎ、ブラウザで正しく認識・実行されます。
まとめ
今回の記事では、Viteを使って「Hello World」を表示するJavaScriptライブラリーを作成しました。この記事の手順に従うことで、他のプロジェクトに再利用可能なライブラリーを作成できるようになります。
この記事には基本的なことしか書いてありませんが、皆さんがこれまでに開発してきた資産を再利用するきっかけになれば幸いです。