Skip to content

Commit 2e528cb

Browse files
feat(fonts): warn if local font is in public dir (#13678)
Co-authored-by: Armand Philippot <git@armand.philippot.eu>
1 parent c5af903 commit 2e528cb

4 files changed

Lines changed: 44 additions & 6 deletions

File tree

.changeset/social-bats-kiss.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
Adds warnings about using local font files in the `publicDir` when the experimental fonts API is enabled.

packages/astro/src/assets/fonts/utils.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createRequire } from 'node:module';
22
import { extname } from 'node:path';
3-
import { fileURLToPath, pathToFileURL } from 'node:url';
3+
import { pathToFileURL } from 'node:url';
44
import type * as unifont from 'unifont';
55
import type { Storage } from 'unstorage';
66
import { AstroError, AstroErrorData } from '../../core/errors/index.js';
@@ -248,8 +248,11 @@ function dedupe<const T extends Array<any>>(arr: T): T {
248248

249249
function resolveVariants({
250250
variants,
251-
root,
252-
}: { variants: LocalFontFamily['variants']; root: URL }): ResolvedLocalFontFamily['variants'] {
251+
resolveEntrypoint: _resolveEntrypoint,
252+
}: {
253+
variants: LocalFontFamily['variants'];
254+
resolveEntrypoint: (url: string) => string;
255+
}): ResolvedLocalFontFamily['variants'] {
253256
return variants.map((variant) => ({
254257
...variant,
255258
weight: variant.weight.toString(),
@@ -258,7 +261,7 @@ function resolveVariants({
258261
const url = (isValue ? value : value.url).toString();
259262
const tech = isValue ? undefined : value.tech;
260263
return {
261-
url: fileURLToPath(resolveEntrypoint(root, url)),
264+
url: _resolveEntrypoint(url),
262265
tech,
263266
};
264267
}),
@@ -275,17 +278,22 @@ export async function resolveFontFamily({
275278
generateNameWithHash,
276279
root,
277280
resolveMod,
281+
resolveLocalEntrypoint,
278282
}: Omit<ResolveProviderOptions, 'provider'> & {
279283
family: FontFamily;
280284
generateNameWithHash: (family: FontFamily) => string;
285+
resolveLocalEntrypoint: (url: string) => string;
281286
}): Promise<ResolvedFontFamily> {
282287
const nameWithHash = generateNameWithHash(family);
283288

284289
if (family.provider === LOCAL_PROVIDER_NAME) {
285290
return {
286291
...family,
287292
nameWithHash,
288-
variants: resolveVariants({ variants: family.variants, root }),
293+
variants: resolveVariants({
294+
variants: family.variants,
295+
resolveEntrypoint: resolveLocalEntrypoint,
296+
}),
289297
fallbacks: family.fallbacks ? dedupe(family.fallbacks) : undefined,
290298
};
291299
}

packages/astro/src/assets/fonts/vite-plugin-fonts.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import type { PreloadData, ResolvedFontFamily } from './types.js';
2626
import {
2727
cache,
2828
extractFontType,
29+
resolveEntrypoint,
2930
resolveFontFamily,
3031
sortObjectByKey,
3132
withoutQuotes,
@@ -118,18 +119,36 @@ export function fontsPlugin({ settings, sync, logger }: Options): Plugin {
118119

119120
const families: Array<ResolvedFontFamily> = [];
120121

122+
const root = settings.config.root;
123+
const pathsToWarn = new Set<string>();
124+
121125
for (const family of settings.config.experimental.fonts!) {
122126
families.push(
123127
await resolveFontFamily({
124128
family,
125-
root: settings.config.root,
129+
root,
126130
resolveMod,
127131
generateNameWithHash: (_family) =>
128132
`${withoutQuotes(_family.name)}-${h64ToString(JSON.stringify(sortObjectByKey(_family)))}`,
133+
resolveLocalEntrypoint: (url) => {
134+
const resolvedPath = fileURLToPath(resolveEntrypoint(root, url));
135+
if (resolvedPath.startsWith(fileURLToPath(settings.config.publicDir))) {
136+
pathsToWarn.add(resolvedPath);
137+
}
138+
return resolvedPath;
139+
},
129140
}),
130141
);
131142
}
132143

144+
for (const path of [...pathsToWarn]) {
145+
// TODO: remove when stabilizing
146+
logger.warn(
147+
'assets',
148+
`Found a local font file ${JSON.stringify(path)} in the \`public/\` folder. To avoid duplicated files in the build output, move this file into \`src/\``,
149+
);
150+
}
151+
133152
await loadFonts({
134153
base: baseUrl,
135154
families,

packages/astro/test/units/assets/fonts/utils.test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
isGenericFontFamily,
1212
proxyURL,
1313
renderFontSrc,
14+
resolveEntrypoint,
1415
resolveFontFamily,
1516
toCSS,
1617
} from '../../../../dist/assets/fonts/utils.js';
@@ -280,6 +281,7 @@ describe('fonts utils', () => {
280281
resolveMod: async () => ({ provider: () => {} }),
281282
generateNameWithHash: (family) => `${family.name}-x`,
282283
root,
284+
resolveLocalEntrypoint: (url) => fileURLToPath(resolveEntrypoint(root, url)),
283285
}),
284286
{
285287
name: 'Custom',
@@ -313,6 +315,7 @@ describe('fonts utils', () => {
313315
resolveMod: async () => ({ provider: () => {} }),
314316
generateNameWithHash: (family) => `${family.name}-x`,
315317
root,
318+
resolveLocalEntrypoint: (url) => fileURLToPath(resolveEntrypoint(root, url)),
316319
}),
317320
{
318321
name: 'Custom',
@@ -341,6 +344,7 @@ describe('fonts utils', () => {
341344
resolveMod: (id) => import(id),
342345
generateNameWithHash: (family) => `${family.name}-x`,
343346
root,
347+
resolveLocalEntrypoint: (url) => fileURLToPath(resolveEntrypoint(root, url)),
344348
});
345349
assert.equal(res.name, 'Custom');
346350
// Required to make TS happy
@@ -358,6 +362,7 @@ describe('fonts utils', () => {
358362
resolveMod: (id) => import(id),
359363
generateNameWithHash: (family) => `${family.name}-x`,
360364
root,
365+
resolveLocalEntrypoint: (url) => fileURLToPath(resolveEntrypoint(root, url)),
361366
});
362367
assert.equal(res.name, 'Custom');
363368
// Required to make TS happy
@@ -379,6 +384,7 @@ describe('fonts utils', () => {
379384
resolveMod: async () => ({ provider: () => Object.assign(() => {}, { _name: 'test' }) }),
380385
generateNameWithHash: (family) => `${family.name}-x`,
381386
root,
387+
resolveLocalEntrypoint: (url) => fileURLToPath(resolveEntrypoint(root, url)),
382388
});
383389
assert.equal(res.name, 'Custom');
384390
if (res.provider !== 'local') {

0 commit comments

Comments
 (0)