Vite の vanilla-ts テンプレートで生成したプロジェクトで vite-plugin-handlebars を利用する
上記スクラップを記事としてリライト
状況
npm create vite@latest ${PROJECT_NAME} -- --template vanilla-ts
という感じで vanilla
, vanilla-ts
で生成したプロジェクトにて。
テンプレートを使って値を埋め込みたい、とかは不要で、長大になってしまった index.html
を別ファイルに分割し、index.html
で include したい、といったことへの対応したい。また、できるだけプラグインの設定などもシンプルなものが良い、という観点で調べてみた。
調査
vite import partial html
でググった最初に出てきた Stack Overflow
そうそう。そーゆーことがしたい。
回答にあったのは以下 2 点。
- vite-plugin-handlebars
- vite-plugin-html
上記で紹介されていたプラグインは Awesome Vite.js の Plugins > Transformers
にも記載あり。
せっかくなのでほかもざっと眺めてみて、結果、以下の 3 つが良いかなー、という感じになった。
- vite-plugin-handlebars
- vite-plugin-html
- vite-plugin-html-inject
比較
プラグイン同士の比較と、、、
vite-plugin-handlebars | vite-plugin-html | |
---|---|---|
source | https://github.com/alexlafroscia/vite-plugin-handlebars | https://github.com/vbenjs/vite-plugin-html |
npm | https://www.npmjs.com/package/vite-plugin-handlebars | https://www.npmjs.com/package/vite-plugin-html |
Weekly Downloads | 2,492 | 142,397 |
Version | 1.6.0 | 3.2.0 |
License | MIT | MIT |
Unpacked Size | 50.8 kB | 25.4 kB |
Total Files | 10 | 5 |
Issues | 8 | 47 |
Pull Requests | 6 | 13 |
Last publish | 2 years ago | a year ago |
プラグインで利用しているテンプレートエンジンの利用状況など、、、
https://handlebarsjs.com | https://ejs.co | |
---|---|---|
source | https://github.com/handlebars-lang/handlebars.js | https://github.com/mde/ejs |
npm | https://www.npmjs.com/package/handlebars | https://www.npmjs.com/package/ejs |
Weekly Downloads | 11,700,707 | 11,666,499 |
Version | 4.7.7 | 3.1.8 |
License | MIT | Apache-2.0 |
Unpacked Size | 2.72 MB | 140 kB |
Total Files | 118 | 13 |
Issues | 66 | 90 |
Pull Requests | 18 | 11 |
Last publish | 2 years ago | 10 months ago |
あと vite-plugin-html-inject で、こちらは依存なしのためプラグイン自体の数値のみ。
vite-plugin-html-inject | |
---|---|
source | https://github.com/donnikitos/vite-plugin-html-inject |
npm | https://www.npmjs.com/package/vite-plugin-html-inject |
Weekly Downloads | 3,016 |
Version | 1.0.1 |
License | MIT |
Unpacked Size | 9.77 kB |
Total Files | 6 |
Issues | 1 |
Pull Requests | 0 |
Last publish | 3 months ago |
検証・結果
./index.html
と ./src/partials/header.html
がある想定で試してみる。
vite-plugin-html-inject
Plugin 設定したら ./index.html
に以下のように記載するのみ。
<load ="src/partials/header.html" />
なのだが、やはり属性名が無い感じの記述がすごく気になる。
実装としては <load>
タグを置換しているだけなので、
<load foo="src/partials/header.html" />
という感じに、適当な属性名(上記では foo
)を設定しても動くが、それもそれでなんとなく気になる感じではある。結果、以下の点などから採用を見送った。
-
<load>
というタグ名が汎用にすぎないか
=> たとえばカスタム要素みたいに<load-partials>
とかになっててもよいのではないか - 属性名無しで値あり、みたいな記述が構文的に気になる
=>src
とかじゃだめだったのだろうか - 閉じタグ
</load>
を書いてしまうとそれ以後の他のタグの表示がおかしくなる
=> エディタで自動補完とかされちゃうといきなり表示崩れたりするのが少しイヤ
しかし今回の要件は満たしてくれるし、ミニマムで個人的にはかなり好き。
残念。
vite-plugin-html
利用数は今回の 3 つで一番多そうで、できることも多そうな印象なんだけど、逆に設定がなんだか面倒そうだな、と思っていた。
結果 <%- include('/src/partials/header.html'); %>
と書いても
ENOENT: no such file or directory, open '/src/partials/header.html'
と、なんかうまく行かず、設定いじったりパス変えて試してみたけど途中で面倒になって、んじゃもう 1 つの vite-plugin-handlebars
を試すか、となって検証やめた。
vite-plugin-handlebars
結局 Stack Overflow で最初に見たものを採用することとした。
プラグインの設定が不要だった vite-plugin-html-inject
に比べて設定が必要になる、とはいえ実際は以下の記述だけだし。
// vite.config.js
import { resolve } from 'path';
import handlebars from 'vite-plugin-handlebars';
export default {
plugins: [
handlebars({
partialDirectory: resolve(__dirname, 'src/partials'),
}),
],
};
https://github.com/alexlafroscia/vite-plugin-handlebars#partials
というわけで今回は vite-plugin-handlebars
を採用することとした。
注意点
ただし以下の箇所に記載の内容に注意が必要。
https://github.com/alexlafroscia/vite-plugin-handlebars#quirks
Assets included in a partial using a relative path will probably not work how you would first expect; the relative path is left alone, making it relative to the output file, not the partial itself. It's recommended that you use the resolve-from-root helper to ensure paths are resolved from the project root, rather than relative to a particular file.
相対パスを使ってパーシャルに含まれるアセットは、おそらく最初に期待したようには動作しません。相対パスは放置され、パーシャル自体ではなく、出力ファイルに対する相対パスとなります。相対パスはそのままで、パーシャル自体ではなく出力ファイルへの相対パスとなります。特定のファイルへの相対パスではなく、プロジェクトルートからのパスを確実に解決するために resolve-from-root ヘルパーを使用することをお勧めします。
というわけで resolve-from-root
を使ってみたが、うまくいく場合とうまく行かずにローカル環境のフルパスが展開されてしまうパターンがあったため、結果としては、
相対パスはそのままで、パーシャル自体ではなく出力ファイルへの相対パスとなります。
という形で対応とすることとする。
つまり以下のような構成の場合、
.
├── index.html
└── src
├── logo.jpg
└── partials
└── header.html
-
./index.html
で./src/partials/header.html
をインクルード -
./src/partials/header.html
内に<img>
タグを配置 -
<img>
タグには./src/logo.jpg
を表示したい
といった場合、 src
の値は
./src/partials/header.html
からの相対パス ../logo.jpg
ではなく、
./index.html
からの相対パス ./src/logo.jpg
となる。
Discussion