vite-plugin-html-pages 1.2.3 → 1.2.4

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/src/assets.ts DELETED
@@ -1,236 +0,0 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import type {
4
- OutputBundle,
5
- PluginContext,
6
- } from 'rollup';
7
-
8
- export type HtmlAssetKind = 'css' | 'js';
9
-
10
- export interface HtmlAssetRef {
11
- kind: HtmlAssetKind;
12
- originalUrl: string;
13
- absolutePath: string;
14
- refId: string;
15
- }
16
-
17
- export interface ExtractedHtmlAsset {
18
- kind: HtmlAssetKind;
19
- url: string;
20
- }
21
-
22
- const EXTERNAL_URL_RE = /^(?:[a-z]+:)?\/\//i;
23
-
24
- export function isLocalAssetUrl(url: string): boolean {
25
- return (
26
- !!url &&
27
- !url.startsWith('data:') &&
28
- !url.startsWith('mailto:') &&
29
- !url.startsWith('tel:') &&
30
- !url.startsWith('#') &&
31
- !EXTERNAL_URL_RE.test(url)
32
- );
33
- }
34
-
35
- export function stripQueryAndHash(url: string): string {
36
- return url.split('#')[0].split('?')[0];
37
- }
38
-
39
- export function extractHtmlAssets(html: string): ExtractedHtmlAsset[] {
40
- const assets: ExtractedHtmlAsset[] = [];
41
-
42
- for (const match of html.matchAll(
43
- /<link\b[^>]*\brel=["']stylesheet["'][^>]*\bhref=["']([^"']+)["'][^>]*>/gi,
44
- )) {
45
- assets.push({ kind: 'css', url: match[1] });
46
- }
47
-
48
- for (const match of html.matchAll(
49
- /<script\b[^>]*\bsrc=["']([^"']+)["'][^>]*>/gi,
50
- )) {
51
- assets.push({ kind: 'js', url: match[1] });
52
- }
53
-
54
- return dedupeExtractedAssets(assets);
55
- }
56
-
57
- function dedupeExtractedAssets(
58
- assets: ExtractedHtmlAsset[],
59
- ): ExtractedHtmlAsset[] {
60
- const seen = new Set<string>();
61
- const out: ExtractedHtmlAsset[] = [];
62
-
63
- for (const asset of assets) {
64
- const key = `${asset.kind}:${asset.url}`;
65
- if (seen.has(key)) continue;
66
- seen.add(key);
67
- out.push(asset);
68
- }
69
-
70
- return out;
71
- }
72
-
73
- export function resolveLocalAssetPath(args: {
74
- root: string;
75
- pagesDir: string;
76
- pageDir?: string;
77
- url: string;
78
- }): string | null {
79
- const { root, pagesDir, pageDir, url } = args;
80
-
81
- if (!isLocalAssetUrl(url)) return null;
82
-
83
- const cleanUrl = stripQueryAndHash(url);
84
-
85
- let abs: string;
86
-
87
- if (cleanUrl.startsWith('/')) {
88
- abs = path.join(root, pagesDir, cleanUrl.slice(1));
89
- } else if (cleanUrl.startsWith(`${pagesDir}/`)) {
90
- abs = path.join(root, cleanUrl);
91
- } else {
92
- const baseDir = pageDir ?? path.join(root, pagesDir);
93
- abs = path.resolve(baseDir, cleanUrl);
94
- }
95
-
96
- return fs.existsSync(abs) ? abs : null;
97
- }
98
-
99
- export function emitHtmlAsset(args: {
100
- ctx: PluginContext;
101
- kind: HtmlAssetKind;
102
- absolutePath: string;
103
- }): string {
104
- const { ctx, kind, absolutePath } = args;
105
-
106
- if (kind === 'css' || kind === 'js') {
107
- return ctx.emitFile({
108
- type: 'chunk',
109
- id: absolutePath,
110
- name: path.basename(absolutePath, path.extname(absolutePath)),
111
- });
112
- }
113
-
114
- throw new Error(`[vite-plugin-html-pages] Unsupported asset kind: ${kind}`);
115
- }
116
-
117
- function replaceAllLiteral(
118
- input: string,
119
- search: string,
120
- replacement: string,
121
- ): string {
122
- return input.split(search).join(replacement);
123
- }
124
-
125
- export function rewriteHtmlAssetUrls(
126
- html: string,
127
- replacements: Map<string, string>,
128
- ): string {
129
- let out = html;
130
-
131
- for (const [originalUrl, builtUrl] of replacements) {
132
- out = replaceAllLiteral(
133
- out,
134
- `href="${originalUrl}"`,
135
- `href="${builtUrl}"`,
136
- );
137
- out = replaceAllLiteral(
138
- out,
139
- `href='${originalUrl}'`,
140
- `href='${builtUrl}'`,
141
- );
142
- out = replaceAllLiteral(
143
- out,
144
- `src="${originalUrl}"`,
145
- `src="${builtUrl}"`,
146
- );
147
- out = replaceAllLiteral(
148
- out,
149
- `src='${originalUrl}'`,
150
- `src='${builtUrl}'`,
151
- );
152
- }
153
-
154
- return out;
155
- }
156
-
157
- export async function collectHtmlAssetRefs(args: {
158
- ctx: PluginContext;
159
- root: string;
160
- pagesDir: string;
161
- htmlByPageKey: Map<string, { html: string; pageDir?: string }>;
162
- }): Promise<Map<string, HtmlAssetRef>> {
163
- const { ctx, root, pagesDir, htmlByPageKey } = args;
164
- const refs = new Map<string, HtmlAssetRef>();
165
-
166
- for (const { html, pageDir } of htmlByPageKey.values()) {
167
- const assets = extractHtmlAssets(html);
168
-
169
- for (const asset of assets) {
170
- const abs = resolveLocalAssetPath({
171
- root,
172
- pagesDir,
173
- pageDir,
174
- url: asset.url,
175
- });
176
-
177
- if (!abs) continue;
178
-
179
- const key = `${asset.kind}:${asset.url}`;
180
- if (refs.has(key)) continue;
181
-
182
- const refId = emitHtmlAsset({
183
- ctx,
184
- kind: asset.kind,
185
- absolutePath: abs,
186
- });
187
-
188
- refs.set(key, {
189
- kind: asset.kind,
190
- originalUrl: asset.url,
191
- absolutePath: abs,
192
- refId,
193
- });
194
- }
195
- }
196
-
197
- return refs;
198
- }
199
-
200
- export function buildHtmlAssetReplacementMap(args: {
201
- ctx: PluginContext;
202
- refs: Map<string, HtmlAssetRef>;
203
- bundle: OutputBundle;
204
- }): Map<string, string> {
205
- const { ctx, refs, bundle } = args;
206
- const replacements = new Map<string, string>();
207
-
208
- for (const ref of refs.values()) {
209
- if (ref.kind === 'js') {
210
- const fileName = ctx.getFileName(ref.refId);
211
- replacements.set(ref.originalUrl, `/${fileName}`);
212
- continue;
213
- }
214
-
215
- if (ref.kind === 'css') {
216
- const jsEntryFile = ctx.getFileName(ref.refId);
217
- const jsChunk = bundle[jsEntryFile];
218
-
219
- if (
220
- jsChunk &&
221
- jsChunk.type === 'chunk' &&
222
- 'viteMetadata' in jsChunk &&
223
- jsChunk.viteMetadata?.importedCss &&
224
- jsChunk.viteMetadata.importedCss.size > 0
225
- ) {
226
- const cssFile = [...jsChunk.viteMetadata.importedCss][0];
227
- replacements.set(ref.originalUrl, `/${cssFile}`);
228
- continue;
229
- }
230
-
231
- replacements.set(ref.originalUrl, `/${jsEntryFile}`);
232
- }
233
- }
234
-
235
- return replacements;
236
- }