Vite で Handlebars を 使用してHTMLファイルにデータを流し込む
Vite で Handlebars を 使用してHTMLファイルにデータを渡す方法を説明しています。
任意のディレクトリでViteのインストールとViteのプラグインとして提供されているhandlebarsをインストールします。
$ npm init
$ npm install vite --save-dev
$ npm install vite-plugin-handlebars --save-dev
最終的なディレクトリ構成は以下になります。
.
├──index.html
├──src/data/pages/index.js
├──main.js
├──package-lock.json
├──package.json
├──vite.config.js
├──node_modules
package.jsonのscriptsプロパティにvite コマンドを設定しておきます。
またあとで、ダイナミックインポートを使用するため "type": "module" を追記します。
{
"name": "project",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"test": "echo \"Error: no test specified\" && exit 1"
},
"type": "module",
"author": "",
"license": "ISC",
"devDependencies": {
"vite": "^4.5.0",
"vite-plugin-handlebars": "^1.6.0"
}
}
vite.config.jsに直接データを記述する方法で出力してみます
htmlでは渡ってきた変数を出力する箇所に{{変数名}}で展開します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
</head>
<body>
{{body}}
<script type="module" src="/main.js"></script>
</body>
</html>
vite.config.jsにhtmlに渡すデータを直接記述してみます。
import { defineConfig } from "vite";
import handlebars from "vite-plugin-handlebars";
export default defineConfig({
plugins: [
handlebars({
context: {
title: "Vite + Handlebars",
body: "This is the body"
}),
]
})
ここまででhtmlファイルに変数が展開されて表示されます。
npm run dev もしくは npm run build で確認することができます。
データをvite.config.jsに直接書くのではなく別ファイルにする
現状だとトップページにあたるindex.htmlファイルのみなので恩恵がありませんが、データファイルを置いてある構造とhtmlの構造を同じにすることでそれぞれのhtmlファイルに対応したデータファイルを自動で読み込むようにします。ダイナミックインポートで読み込むため、package.jsonに"type": "module"が必要になります。分割代入を使用してdefaultの値をdataに入れて渡すようにします。
vite.config.jsに記述していた内容をindex.jsに外部化して別ディレクトリ(/src/data/pages/index.js)に配置します。
export default {
title: "Vite + Handlebars",
body: "This is the body",
}
export default defineConfig({
plugins: [
handlebars({
context: async (pagePath) => {
const dataPagePath = `./src/data/pages${pagePath.replace('.html', '')}.js`;
try{
const { default: data } = await import(dataPagePath);
return data;
}catch(err){
console.log(err);
}
}
}),
]
})