vite-pug-static-builder 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 maigo999
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,338 @@
1
+ # vite-pug-static-builder
2
+
3
+ [![MIT](https://img.shields.io/badge/License-MIT-green.svg?style=flat-square)](./LICENSE)
4
+ [![TypeScript](https://img.shields.io/badge/TypeScript-3178c6?style=flat-square&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
5
+ [![Vite](https://img.shields.io/badge/Vite-646cff?style=flat-square&logo=Vite&logoColor=white)](https://vitejs.dev/)
6
+ [![Pug](https://img.shields.io/badge/Pug-a86454?style=flat-square&logo=pug&logoColor=white)](https://pugjs.org/)
7
+ [![Vitest](https://img.shields.io/badge/Vitest-6E9F18?style=flat-square&logo=vitest&logoColor=white)](https://vitest.dev/)
8
+
9
+ **Vite 7 & Vitest 3.2対応版** - Vite + Pugを使用した高性能静的サイトビルダー
10
+
11
+ 複数のPugファイルを効率的に静的HTMLファイルとしてビルドできる、最新のViteプラグインです。
12
+
13
+ ## ✨ 新機能(v1.0.0)
14
+
15
+ ### 🚀 Vite 7対応
16
+ - **Environment API**: 新しいVite 7のEnvironment APIに完全対応
17
+ - **最新型システム**: TypeScript 5.6の最新機能を活用した型安全性の向上
18
+ - **パフォーマンス向上**: Vite 7の高速化されたビルドシステムを活用
19
+
20
+ ### 🧪 Vitest 3.2対応
21
+ - **Projects API**: workspace → projectsへの移行完了
22
+ - **Enhanced Coverage**: v8カバレッジプロバイダーによる詳細なテストカバレッジ
23
+ - **型チェック**: TypeScriptの型チェックを統合したテスト実行
24
+ - **並列実行**: マルチスレッドによる高速テスト実行
25
+
26
+ ## 特徴
27
+
28
+ - 🚀 **超高速ビルド**: Vite 7の最新ビルドシステムによる極速開発体験
29
+ - 📝 **Pugサポート**: Pugテンプレートエンジンで効率的なHTML作成
30
+ - 🔄 **開発時リアルタイム更新**: HMR (Hot Module Replacement) 対応
31
+ - 📱 **静的サイト生成**: 本番環境向けに最適化された静的HTMLファイルを生成
32
+ - 🎨 **高度なカスタマイズ**: 豊富な設定オプションでプロジェクトに合わせた細かな調整
33
+ - 🛡️ **型安全**: TypeScript完全対応による開発時エラーの早期発見
34
+ - 🧪 **テスト統合**: Vitest 3.2による包括的なテストサポート
35
+
36
+ ## インストール
37
+
38
+ ```bash
39
+ # npm
40
+ npm install vite-pug-static-builder
41
+
42
+ # yarn
43
+ yarn add vite-pug-static-builder
44
+
45
+ # pnpm
46
+ pnpm add vite-pug-static-builder
47
+ ```
48
+
49
+ ## 必要環境
50
+
51
+ - **Node.js**: 18.0.0以上
52
+ - **Vite**: 7.0.0-beta.0以上
53
+ - **Pug**: 3.0.0以上
54
+
55
+ ## 基本的な使用方法
56
+
57
+ ### 1. Vite設定ファイル
58
+
59
+ ```typescript
60
+ // vite.config.ts
61
+ import { defineConfig } from 'vite'
62
+ import pugPlugin from 'vite-pug-static-builder'
63
+
64
+ export default defineConfig({
65
+ plugins: [
66
+ pugPlugin({
67
+ buildOptions: {
68
+ basedir: './src',
69
+ pretty: true
70
+ },
71
+ buildLocals: {
72
+ title: 'My Website',
73
+ env: 'production'
74
+ },
75
+ serveOptions: {
76
+ basedir: './src',
77
+ pretty: true
78
+ },
79
+ serveLocals: {
80
+ title: 'My Website (Dev)',
81
+ env: 'development'
82
+ }
83
+ })
84
+ ]
85
+ })
86
+ ```
87
+
88
+ ### 2. プロジェクト構造例
89
+
90
+ ```
91
+ src/
92
+ ├── index.pug # → dist/index.html
93
+ ├── about/
94
+ │ └── index.pug # → dist/about/index.html
95
+ ├── blog/
96
+ │ ├── index.pug # → dist/blog/index.html
97
+ │ └── post1.pug # → dist/blog/post1.html
98
+ ├── _layouts/
99
+ │ └── base.pug # レイアウトテンプレート
100
+ ├── _includes/
101
+ │ └── header.pug # 部分テンプレート
102
+ └── assets/
103
+ ├── style.css
104
+ └── script.js
105
+ ```
106
+
107
+ ### 3. Pugファイル例
108
+
109
+ ```pug
110
+ //- src/index.pug
111
+ extends _layouts/base
112
+
113
+ block content
114
+ main
115
+ h1= title
116
+ p ようこそ、#{title}へ!
117
+
118
+ if env === 'development'
119
+ .dev-info 開発モードで実行中
120
+
121
+ include _includes/header
122
+ ```
123
+
124
+ ## 詳細設定オプション
125
+
126
+ ### プラグイン設定
127
+
128
+ ```typescript
129
+ interface Settings {
130
+ // ビルド時のPugコンパイルオプション
131
+ buildOptions?: Pug.Options
132
+
133
+ // ビルド時のPugローカル変数
134
+ buildLocals?: Pug.LocalsObject
135
+
136
+ // 開発サーバー時のPugコンパイルオプション
137
+ serveOptions?: Pug.Options
138
+
139
+ // 開発サーバー時のPugローカル変数
140
+ serveLocals?: Pug.LocalsObject
141
+
142
+ // 無視パターン(glob形式)
143
+ ignorePattern?: string | string[]
144
+
145
+ // ホットリロード設定
146
+ reload?: boolean
147
+ }
148
+ ```
149
+
150
+ ### 高度な設定例
151
+
152
+ ```typescript
153
+ // プラグインの詳細設定
154
+ pugPlugin({
155
+ buildOptions: {
156
+ basedir: './src',
157
+ pretty: false, // 本番環境では圧縮
158
+ compileDebug: false,
159
+ cache: true,
160
+ inlineRuntimeFunctions: false
161
+ },
162
+ buildLocals: {
163
+ title: 'Production Site',
164
+ version: process.env.npm_package_version,
165
+ buildTime: new Date().toISOString(),
166
+ author: 'Your Name',
167
+ description: 'A modern static site built with Vite and Pug'
168
+ },
169
+ serveOptions: {
170
+ basedir: './src',
171
+ pretty: true, // 開発時は読みやすく
172
+ compileDebug: true,
173
+ cache: false // 開発時はキャッシュ無効
174
+ },
175
+ serveLocals: {
176
+ title: 'Development Site',
177
+ version: 'dev',
178
+ buildTime: 'dev-mode'
179
+ },
180
+ ignorePattern: [
181
+ '/_*/**', // アンダースコアで始まるディレクトリを無視
182
+ '/admin/**', // adminディレクトリを無視
183
+ '/**/*.draft.pug' // .draft.pugファイルを無視
184
+ ],
185
+ reload: true
186
+ })
187
+ ```
188
+
189
+ ## 開発コマンド
190
+
191
+ ```bash
192
+ # 開発サーバー起動
193
+ npm run dev
194
+
195
+ # 本番ビルド
196
+ npm run build
197
+
198
+ # ビルドのプレビュー
199
+ npm run preview
200
+
201
+ # 型チェック
202
+ npm run type-check
203
+
204
+ # テスト実行(Vitest 3.2)
205
+ npm test
206
+
207
+ # カバレッジ付きテスト
208
+ npm run coverage
209
+
210
+ # ウォッチモードでテスト
211
+ npm run test:watch
212
+ ```
213
+
214
+ ## TypeScript統合
215
+
216
+ 完全なTypeScript対応により、設定ファイルやPugテンプレート内でも型安全性を確保できます:
217
+
218
+ ```typescript
219
+ // types/pug.d.ts
220
+ declare module '*.pug' {
221
+ const content: string
222
+ export default content
223
+ }
224
+
225
+ // vite-env.d.ts
226
+ /// <reference types="vite/client" />
227
+
228
+ interface ImportMetaEnv {
229
+ readonly VITE_APP_TITLE: string
230
+ readonly VITE_API_URL: string
231
+ }
232
+
233
+ interface ImportMeta {
234
+ readonly env: ImportMetaEnv
235
+ }
236
+ ```
237
+
238
+ ## パフォーマンス最適化
239
+
240
+ Vite 7の新機能と組み合わせて、プラグインの設定を最適化できます:
241
+
242
+ ```typescript
243
+ // より高速なビルドのための設定
244
+ pugPlugin({
245
+ buildOptions: {
246
+ cache: true, // キャッシュ有効化
247
+ inlineRuntimeFunctions: false, // ランタイム関数の外部化
248
+ compileDebug: false // デバッグ情報削除
249
+ },
250
+ serveOptions: {
251
+ cache: false, // 開発時はキャッシュ無効
252
+ compileDebug: true // 開発時はデバッグ有効
253
+ }
254
+ })
255
+ ```
256
+
257
+ ## トラブルシューティング
258
+
259
+ ### よくある問題と解決法
260
+
261
+ **Q: Pugファイルが更新されてもブラウザが更新されない**
262
+ ```typescript
263
+ // reload: true を設定してください
264
+ pugPlugin({
265
+ reload: true
266
+ })
267
+ ```
268
+
269
+ **Q: ビルド時にPugの依存関係が正しく解決されない**
270
+ ```typescript
271
+ // basedirを正しく設定してください
272
+ pugPlugin({
273
+ buildOptions: {
274
+ basedir: path.resolve(__dirname, 'src')
275
+ }
276
+ })
277
+ ```
278
+
279
+ **Q: 開発サーバーでのエラーハンドリング**
280
+ ```pug
281
+ //- エラーを防ぐため、変数の存在チェックを行う
282
+ if typeof title !== 'undefined'
283
+ h1= title
284
+ else
285
+ h1 Default Title
286
+ ```
287
+
288
+ ## マイグレーションガイド
289
+
290
+ ### 他のPugプラグインからの移行
291
+
292
+ ```diff
293
+ - import { createPugPlugin } from 'vite-plugin-pug'
294
+ + import pugPlugin from 'vite-pug-static-builder'
295
+
296
+ - createPugPlugin({
297
+ - pugOptions: { basedir: './src' }
298
+ - })
299
+ + pugPlugin({
300
+ + buildOptions: { basedir: './src' },
301
+ + serveOptions: { basedir: './src' }
302
+ + })
303
+ ```
304
+
305
+ ## ライセンス
306
+
307
+ [MIT](./LICENSE) © 2025 maigo999
308
+
309
+ ## 貢献
310
+
311
+ プルリクエストや Issue の報告を歓迎します!
312
+
313
+ 1. このリポジトリをフォーク
314
+ 2. フィーチャーブランチを作成 (`git checkout -b feature/amazing-feature`)
315
+ 3. 変更をコミット (`git commit -m 'Add amazing feature'`)
316
+ 4. ブランチにプッシュ (`git push origin feature/amazing-feature`)
317
+ 5. プルリクエストを作成
318
+
319
+ ## 変更履歴
320
+
321
+ ### v1.0.0 (2025-01-XX)
322
+ - 🚀 Vite 7 (ベータ版) 対応
323
+ - 🧪 Vitest 3.2 対応
324
+ - 🛡️ TypeScript 5.6 完全対応
325
+ - ✨ Environment API 対応
326
+ - 🎯 型安全性の大幅向上
327
+ - 📦 依存関係の最新化
328
+ - 🧹 コードベースの全面リファクタリング
329
+
330
+ ---
331
+
332
+ **注意**: 現在Vite 7はベータ版のため、本番環境での使用は安定版リリース後を推奨します。
333
+
334
+ ## 関連リンク
335
+
336
+ - [Vite](https://vitejs.dev/)
337
+ - [Pug](https://pugjs.org/)
338
+ - [GitHub Repository](https://github.com/ozekimasaki/vite-pug-static-builder)
@@ -0,0 +1,19 @@
1
+ import type Pug from 'pug';
2
+ import type { Plugin } from 'vite';
3
+ /**
4
+ * Pugビルド設定
5
+ */
6
+ interface BuildSettings {
7
+ /** Pugコンパイルオプション */
8
+ readonly options?: Pug.Options;
9
+ /** Pugローカル変数オブジェクト */
10
+ readonly locals?: Pug.LocalsObject;
11
+ }
12
+ /**
13
+ * Vite用Pugビルドプラグイン
14
+ * @param settings - ビルド設定
15
+ * @returns Viteプラグイン
16
+ */
17
+ export declare const vitePluginPugBuild: (settings: BuildSettings) => Plugin;
18
+ export {};
19
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,GAAG,MAAM,KAAK,CAAA;AAE1B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAIlC;;GAEG;AACH,UAAU,aAAa;IACrB,oBAAoB;IACpB,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IAC9B,sBAAsB;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,YAAY,CAAA;CACnC;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,aAAa,KAAG,MA6D5D,CAAA"}
package/dist/build.js ADDED
@@ -0,0 +1,57 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { compileFile } from 'pug';
4
+ import { outputLog } from './utils.js';
5
+ /**
6
+ * Vite用Pugビルドプラグイン
7
+ * @param settings - ビルド設定
8
+ * @returns Viteプラグイン
9
+ */
10
+ export const vitePluginPugBuild = (settings) => {
11
+ const { options, locals } = settings;
12
+ const pathMap = new Map();
13
+ return {
14
+ name: 'vite-plugin-pug-build',
15
+ enforce: 'pre',
16
+ apply: 'build',
17
+ resolveId(source) {
18
+ const parsedPath = path.parse(source);
19
+ if (parsedPath.ext !== '.pug') {
20
+ return null;
21
+ }
22
+ const pathAsHtml = path.format({
23
+ dir: parsedPath.dir,
24
+ name: parsedPath.name,
25
+ ext: '.html',
26
+ });
27
+ pathMap.set(pathAsHtml, source);
28
+ return pathAsHtml;
29
+ },
30
+ load(id) {
31
+ if (path.extname(id) !== '.html') {
32
+ return null;
33
+ }
34
+ try {
35
+ // PugファイルのHTMLへの変換
36
+ if (pathMap.has(id)) {
37
+ const pugPath = pathMap.get(id);
38
+ const compiledTemplate = compileFile(pugPath, options);
39
+ const html = compiledTemplate(locals);
40
+ outputLog('info', 'compiled:', path.relative(process.cwd(), pugPath));
41
+ return html;
42
+ }
43
+ // 既存のHTMLファイルの読み込み
44
+ if (fs.existsSync(id)) {
45
+ return fs.readFileSync(id, 'utf-8');
46
+ }
47
+ }
48
+ catch (error) {
49
+ // エラーログの出力
50
+ const errorMessage = error instanceof Error ? error.message : String(error);
51
+ outputLog('error', 'compilation failed:', id, errorMessage);
52
+ throw error;
53
+ }
54
+ return null;
55
+ },
56
+ };
57
+ };
@@ -0,0 +1,27 @@
1
+ import type Pug from 'pug';
2
+ import type Picomatch from 'picomatch';
3
+ /**
4
+ * プラグイン設定
5
+ */
6
+ interface Settings {
7
+ /** ビルド時のPugコンパイルオプション */
8
+ readonly buildOptions?: Pug.Options;
9
+ /** ビルド時のPugローカル変数 */
10
+ readonly buildLocals?: Pug.LocalsObject;
11
+ /** 開発サーバー時のPugコンパイルオプション */
12
+ readonly serveOptions?: Pug.Options;
13
+ /** 開発サーバー時のPugローカル変数 */
14
+ readonly serveLocals?: Pug.LocalsObject;
15
+ /** 無視パターン */
16
+ readonly ignorePattern?: Picomatch.Glob;
17
+ /** リロード設定 */
18
+ readonly reload?: boolean;
19
+ }
20
+ /**
21
+ * Vite Pug静的サイトプラグイン
22
+ * @param userSettings - ユーザー設定
23
+ * @returns Viteプラグイン配列
24
+ */
25
+ declare const vitePluginPugStatic: (userSettings?: Settings) => import("vite").Plugin<any>[];
26
+ export default vitePluginPugStatic;
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,KAAK,CAAA;AAC1B,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AAKtC;;GAEG;AACH,UAAU,QAAQ;IAChB,yBAAyB;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACnC,qBAAqB;IACrB,QAAQ,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,YAAY,CAAA;IACvC,4BAA4B;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACnC,wBAAwB;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,YAAY,CAAA;IACvC,aAAa;IACb,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC,IAAI,CAAA;IACvC,aAAa;IACb,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAC1B;AAID;;;;GAIG;AACH,QAAA,MAAM,mBAAmB,GAAI,eAAe,QAAQ,iCA2BnD,CAAA;AAED,eAAe,mBAAmB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ import { vitePluginPugBuild } from './build.js';
2
+ import { vitePluginPugServe } from './serve.js';
3
+ const defaultSettings = {};
4
+ /**
5
+ * Vite Pug静的サイトプラグイン
6
+ * @param userSettings - ユーザー設定
7
+ * @returns Viteプラグイン配列
8
+ */
9
+ const vitePluginPugStatic = (userSettings) => {
10
+ const settings = {
11
+ ...defaultSettings,
12
+ ...userSettings,
13
+ };
14
+ const { buildOptions, buildLocals, serveOptions, serveLocals, ignorePattern, reload, } = settings;
15
+ return [
16
+ vitePluginPugBuild({
17
+ ...(buildOptions && { options: buildOptions }),
18
+ ...(buildLocals && { locals: buildLocals }),
19
+ }),
20
+ vitePluginPugServe({
21
+ ...(serveOptions && { options: serveOptions }),
22
+ ...(serveLocals && { locals: serveLocals }),
23
+ ...(ignorePattern && { ignorePattern }),
24
+ ...(reload !== undefined && { reload }),
25
+ }),
26
+ ];
27
+ };
28
+ export default vitePluginPugStatic;
package/dist/pug.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import type Pug from 'pug';
2
+ import type { ModuleGraph } from 'vite';
3
+ /**
4
+ * Pugファイルをコンパイル
5
+ * @param moduleGraph - モジュールグラフ
6
+ * @param url - ルート相対パス
7
+ * @param pugPath - Pugファイルの絶対パス(POSIX形式)
8
+ * @param options - Pugコンパイルオプション
9
+ * @param locals - Pugローカル変数オブジェクト
10
+ * @returns コンパイル結果(成功時はtrue、エラー時はErrorオブジェクト)
11
+ */
12
+ export declare const compilePug: (moduleGraph: ModuleGraph, url: string, pugPath: string, options?: Pug.Options, locals?: Pug.LocalsObject) => Promise<boolean | Error>;
13
+ //# sourceMappingURL=pug.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pug.d.ts","sourceRoot":"","sources":["../src/pug.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,GAAG,MAAM,KAAK,CAAA;AAE1B,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,MAAM,CAAA;AAkCnD;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,GACrB,aAAa,WAAW,EACxB,KAAK,MAAM,EACX,SAAS,MAAM,EACf,UAAU,GAAG,CAAC,OAAO,EACrB,SAAS,GAAG,CAAC,YAAY,KACxB,OAAO,CAAC,OAAO,GAAG,KAAK,CAoDzB,CAAA"}
package/dist/pug.js ADDED
@@ -0,0 +1,67 @@
1
+ import path from 'node:path';
2
+ import { compileFile } from 'pug';
3
+ import { outputLog } from './utils.js';
4
+ /**
5
+ * モジュールグラフに祖先モジュールを反映
6
+ * @param moduleGraph - モジュールグラフ
7
+ * @param compiledModule - HTMLにコンパイルされるPugモジュール
8
+ * @param ancestors - compiledModuleの祖先ファイルパス配列
9
+ */
10
+ const reflectAncestorsIntoModuleMap = (moduleGraph, compiledModule, ancestors) => {
11
+ // モジュールマップに祖先を追加
12
+ for (const ancestor of ancestors) {
13
+ const ancestorModules = moduleGraph.getModulesByFile(ancestor);
14
+ const ancestorModule = (ancestorModules && [...ancestorModules][0]) ||
15
+ moduleGraph.createFileOnlyEntry(ancestor);
16
+ ancestorModule.importers.add(compiledModule); // TODO: 依存関係から削除された場合の処理
17
+ compiledModule.importedModules.add(ancestorModule); // オプション
18
+ }
19
+ };
20
+ /**
21
+ * Pugファイルをコンパイル
22
+ * @param moduleGraph - モジュールグラフ
23
+ * @param url - ルート相対パス
24
+ * @param pugPath - Pugファイルの絶対パス(POSIX形式)
25
+ * @param options - Pugコンパイルオプション
26
+ * @param locals - Pugローカル変数オブジェクト
27
+ * @returns コンパイル結果(成功時はtrue、エラー時はErrorオブジェクト)
28
+ */
29
+ export const compilePug = async (moduleGraph, url, pugPath, options, locals) => {
30
+ try {
31
+ const compiledModule = (await moduleGraph.getModuleByUrl(url)) ||
32
+ (await moduleGraph.ensureEntryFromUrl(url));
33
+ // 作成時の初期化
34
+ if (compiledModule.file !== pugPath) {
35
+ if (compiledModule.file) {
36
+ moduleGraph.fileToModulesMap.delete(compiledModule.file);
37
+ }
38
+ compiledModule.file = pugPath;
39
+ moduleGraph.fileToModulesMap.set(pugPath, new Set([compiledModule]));
40
+ }
41
+ // モジュールが無効化されていない場合はスキップ
42
+ if (compiledModule.transformResult) {
43
+ return true;
44
+ }
45
+ // コンパイル開始
46
+ const map = null;
47
+ const compiledTemplate = compileFile(pugPath, options);
48
+ // Pugコンパイラから祖先情報を取得
49
+ const ancestors = compiledTemplate.dependencies;
50
+ if (ancestors.length > 0) {
51
+ reflectAncestorsIntoModuleMap(moduleGraph, compiledModule, ancestors);
52
+ }
53
+ // HTML生成
54
+ const code = compiledTemplate(locals);
55
+ outputLog('info', 'compiled:', path.relative(process.cwd(), pugPath));
56
+ compiledModule.transformResult = { code, map };
57
+ return true;
58
+ }
59
+ catch (error) {
60
+ const errorMessage = error instanceof Error ? error.message : String(error);
61
+ outputLog('error', 'compilation failed:', pugPath, errorMessage);
62
+ if (error instanceof Error) {
63
+ return error;
64
+ }
65
+ return new Error(`Pug compilation failed: ${errorMessage}`);
66
+ }
67
+ };
@@ -0,0 +1,29 @@
1
+ import type http from 'node:http';
2
+ import type Pug from 'pug';
3
+ import type { Plugin, Connect } from 'vite';
4
+ import type Picomatch from 'picomatch';
5
+ /**
6
+ * 開発サーバー設定
7
+ */
8
+ interface ServeSettings {
9
+ /** Pugコンパイルオプション */
10
+ readonly options?: Pug.Options;
11
+ /** Pugローカル変数オブジェクト */
12
+ readonly locals?: Pug.LocalsObject;
13
+ /** 無視パターン(Pugファイル変換の除外用) */
14
+ readonly ignorePattern?: Picomatch.Glob;
15
+ /** リロード設定(現在は有効/無効制御のみ) */
16
+ readonly reload?: boolean;
17
+ }
18
+ /**
19
+ * Connectミドルウェア型定義
20
+ */
21
+ export type Middleware = (req: Connect.IncomingMessage, res: http.ServerResponse, next: Connect.NextFunction) => void | http.ServerResponse | Promise<void | http.ServerResponse>;
22
+ /**
23
+ * Vite用Pug開発サーバープラグイン
24
+ * @param settings - サーブ設定
25
+ * @returns Viteプラグイン
26
+ */
27
+ export declare const vitePluginPugServe: (settings: ServeSettings) => Plugin;
28
+ export {};
29
+ //# sourceMappingURL=serve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAEjC,OAAO,KAAK,GAAG,MAAM,KAAK,CAAA;AAC1B,OAAO,KAAK,EAAE,MAAM,EAAiB,OAAO,EAAE,MAAM,MAAM,CAAA;AAE1D,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AAKtC;;GAEG;AACH,UAAU,aAAa;IACrB,oBAAoB;IACpB,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IAC9B,sBAAsB;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,YAAY,CAAA;IAClC,4BAA4B;IAC5B,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC,IAAI,CAAA;IACvC,2BAA2B;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CACvB,GAAG,EAAE,OAAO,CAAC,eAAe,EAC5B,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,IAAI,EAAE,OAAO,CAAC,YAAY,KACvB,IAAI,GAAG,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,CAAA;AA8FrE;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,aAAa,KAAG,MAiC5D,CAAA"}
package/dist/serve.js ADDED
@@ -0,0 +1,104 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { URL } from 'node:url';
4
+ import { send } from 'vite';
5
+ import picomatch from 'picomatch';
6
+ import { compilePug } from './pug.js';
7
+ /**
8
+ * 開発サーバー用ミドルウェア生成
9
+ * @param settings - サーブ設定
10
+ * @param server - Vite開発サーバー
11
+ * @returns Connectミドルウェア
12
+ */
13
+ const createMiddleware = (settings, server) => {
14
+ const { options, locals, ignorePattern } = settings;
15
+ const ignoreMatcher = ignorePattern ? picomatch(ignorePattern) : null;
16
+ return async (req, res, next) => {
17
+ // 特殊なURLパスをスキップ
18
+ if (!req.url ||
19
+ req.url.startsWith('/@') || // @fs @vite @react-refresh etc...
20
+ req.url.startsWith('/__inspect/') // vite-plugin-inspect
21
+ ) {
22
+ return next();
23
+ }
24
+ const url = new URL(req.url, 'relative:///').pathname;
25
+ // 無視パターンにマッチする場合はスキップ
26
+ if (ignoreMatcher?.call(null, url)) {
27
+ return next();
28
+ }
29
+ const reqAbsPath = path.posix.join(server.config.root, url, url.endsWith('/') ? 'index.html' : '');
30
+ const parsedReqAbsPath = path.posix.parse(reqAbsPath);
31
+ // HTMLファイル以外はスキップ
32
+ if (parsedReqAbsPath.ext !== '.html') {
33
+ return next();
34
+ }
35
+ // 既存のHTMLファイルがある場合はスキップ
36
+ if (fs.existsSync(reqAbsPath)) {
37
+ return next();
38
+ }
39
+ // 対応するPugファイルのパスを生成
40
+ const pugAbsPath = path.posix.format({
41
+ dir: parsedReqAbsPath.dir,
42
+ name: parsedReqAbsPath.name,
43
+ ext: '.pug',
44
+ });
45
+ // Pugファイルが存在しない場合は404
46
+ if (!fs.existsSync(pugAbsPath)) {
47
+ return send(req, res, '404 Not Found', 'html', {});
48
+ }
49
+ try {
50
+ // Pugファイルをコンパイル
51
+ const compileResult = await compilePug(server.moduleGraph, url, pugAbsPath, options, locals);
52
+ // Pugコンパイルエラー
53
+ if (compileResult instanceof Error) {
54
+ return next(compileResult);
55
+ }
56
+ // HTMLの変換処理
57
+ const transformResult = await server.transformRequest(url);
58
+ if (transformResult) {
59
+ const html = await server.transformIndexHtml(url, transformResult.code);
60
+ return send(req, res, html, 'html', {});
61
+ }
62
+ // transformResultがnullまたは予期しないエラー
63
+ return next(new Error('An unexpected error has occurred during HTML transformation.'));
64
+ }
65
+ catch (error) {
66
+ const errorMessage = error instanceof Error ? error.message : String(error);
67
+ return next(new Error(`Pug compilation failed: ${errorMessage}`));
68
+ }
69
+ };
70
+ };
71
+ /**
72
+ * Vite用Pug開発サーバープラグイン
73
+ * @param settings - サーブ設定
74
+ * @returns Viteプラグイン
75
+ */
76
+ export const vitePluginPugServe = (settings) => {
77
+ const { reload } = settings;
78
+ let server;
79
+ return {
80
+ name: 'vite-plugin-pug-serve',
81
+ enforce: 'pre',
82
+ apply: 'serve',
83
+ configureServer(_server) {
84
+ server = _server;
85
+ server.middlewares.use(createMiddleware(settings, server));
86
+ },
87
+ handleHotUpdate(context) {
88
+ const fileModules = server.moduleGraph.getModulesByFile(context.file);
89
+ if (fileModules) {
90
+ for (const fileModule of fileModules) {
91
+ for (const importer of fileModule.importers) {
92
+ if (importer.file && path.extname(importer.file) === '.pug') {
93
+ server.moduleGraph.invalidateModule(importer);
94
+ }
95
+ }
96
+ }
97
+ }
98
+ // リロード設定に基づいてフルリロードを実行
99
+ if (reload !== false) {
100
+ context.server.ws.send({ type: 'full-reload' });
101
+ }
102
+ },
103
+ };
104
+ };
@@ -0,0 +1,2 @@
1
+ export declare function outputLog(type: 'info' | 'warn' | 'warnOnce' | 'error', green?: string, yellow?: string, dim?: string): void;
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAKA,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,EAC5C,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,QAQb"}
package/dist/utils.js ADDED
@@ -0,0 +1,9 @@
1
+ import { createLogger } from 'vite';
2
+ import ansis from 'ansis';
3
+ const logger = createLogger();
4
+ export function outputLog(type, green, yellow, dim) {
5
+ return logger[type](ansis.cyanBright('[pug-static]') +
6
+ (green ? ansis.green(` ${green}`) : '') +
7
+ (yellow ? ansis.yellow(` ${yellow}`) : '') +
8
+ (dim ? ansis.dim(` ${dim}`) : ''));
9
+ }
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "vite-pug-static-builder",
3
+ "version": "1.0.0",
4
+ "description": "Vite + Pugを使用した静的サイトビルダー - 複数のPugファイルを静的HTMLとしてビルドするViteプラグイン",
5
+ "author": "maigo999",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/ozekimasaki/vite-pug-static-builder#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/ozekimasaki/vite-pug-static-builder.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/ozekimasaki/vite-pug-static-builder/issues"
14
+ },
15
+ "keywords": [
16
+ "vite",
17
+ "vite-plugin",
18
+ "static",
19
+ "pug",
20
+ "static-site",
21
+ "site-builder",
22
+ "html-generator"
23
+ ],
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "type": "module",
28
+ "main": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "exports": {
31
+ ".": {
32
+ "import": "./dist/index.js",
33
+ "types": "./dist/index.d.ts"
34
+ }
35
+ },
36
+ "scripts": {
37
+ "clean": "rimraf ./dist",
38
+ "type-check": "tsc --noEmit -p .",
39
+ "test": "vitest run",
40
+ "test:update": "vitest run -u",
41
+ "test:watch": "vitest",
42
+ "coverage": "vitest run --coverage",
43
+ "tsc": "tsc -p .",
44
+ "build": "pnpm clean && pnpm tsc",
45
+ "prepublishOnly": "pnpm coverage && pnpm build"
46
+ },
47
+ "dependencies": {
48
+ "ansis": "^3.2.0",
49
+ "picomatch": "^4.0.2",
50
+ "pug": "^3.0.3"
51
+ },
52
+ "peerDependencies": {
53
+ "pug": "^3.0.0",
54
+ "vite": "^7.0.0-beta.0"
55
+ },
56
+ "devDependencies": {
57
+ "@types/picomatch": "^2.3.3",
58
+ "@types/pug": "^2.0.10",
59
+ "@vitest/coverage-v8": "^3.2.1",
60
+ "axios": "^1.7.9",
61
+ "rimraf": "^6.0.1",
62
+ "typescript": "^5.6.3",
63
+ "vite": "7.0.0-beta.0",
64
+ "vitest": "^3.2.1"
65
+ }
66
+ }