Skip to content

Commit ef2decf

Browse files
ztannerlubieowoce
andauthored
create-next-app: fix font file corruption when using import alias (#69806)
There's code that uses `glob` to find all template files and replaces the default import alias with whatever is specified during CNA. This does so without excluding fonts, and so we're unintentionally corrupting these `woff` files. This wasn't a problem in previous versions because we didn't use `localFont` in the default template, just `Inter`. The files were technically still being corrupted it just never manifested unless you went to actually use them. This is a quick fix to introduce minimal changes but ideally in a follow-up we should figure out a better solution for replacing aliases, ie by using an allowlist rather than an exclude list. h/t to @lubieowoce for the thorough test cases Fixes #69748 --------- Co-authored-by: Janka Uryga <[email protected]>
1 parent 555302b commit ef2decf

File tree

2 files changed

+89
-1
lines changed

2 files changed

+89
-1
lines changed

packages/create-next-app/templates/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,16 @@ export const installTemplate = async ({
103103
stats: false,
104104
// We don't want to modify compiler options in [ts/js]config.json
105105
// and none of the files in the .git folder
106-
ignore: ["tsconfig.json", "jsconfig.json", ".git/**/*"],
106+
// TODO: Refactor this to be an allowlist, rather than a denylist,
107+
// to avoid corrupting files that weren't intended to be replaced
108+
109+
ignore: [
110+
"tsconfig.json",
111+
"jsconfig.json",
112+
".git/**/*",
113+
"**/fonts/**",
114+
"**/favicon.ico",
115+
],
107116
});
108117
const writeSema = new Sema(8, { capacity: files.length });
109118
await Promise.all(
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { run, tryNextDev, useTempDir } from '../utils'
2+
3+
describe.each(['app', 'pages'] as const)(
4+
'CNA options matrix - %s',
5+
(pagesOrApp) => {
6+
let nextTgzFilename: string
7+
8+
beforeAll(() => {
9+
if (!process.env.NEXT_TEST_PKG_PATHS) {
10+
throw new Error('This test needs to be run with `node run-tests.js`.')
11+
}
12+
13+
const pkgPaths = new Map<string, string>(
14+
JSON.parse(process.env.NEXT_TEST_PKG_PATHS)
15+
)
16+
17+
nextTgzFilename = pkgPaths.get('next')!
18+
})
19+
20+
const isApp = pagesOrApp === 'app'
21+
22+
const allFlagValues = {
23+
app: [isApp ? '--app' : '--no-app'],
24+
turbo: [process.env.TURBOPACK ? '--turbo' : '--no-turbo'],
25+
26+
ts: ['--js', '--ts'],
27+
importAlias: [
28+
'--import-alias=@acme/*',
29+
'--import-alias=@/*',
30+
'--no-import-alias',
31+
],
32+
// doesn't affect if the app builds or not
33+
// eslint: ['--eslint', '--no-eslint'],
34+
eslint: ['--eslint'],
35+
36+
srcDir: ['--src-dir', '--no-src-dir'],
37+
tailwind: ['--tailwind', '--no-tailwind'],
38+
39+
// shouldn't affect if the app builds or not
40+
// packageManager: ['--use-npm', '--use-pnpm', '--use-yarn', '--use-bun'],
41+
}
42+
43+
const getPermutations = <T>(items: T[][]): T[][] => {
44+
if (!items.length) return [[]]
45+
const [first, ...rest] = items
46+
const children = getPermutations(rest)
47+
return first.flatMap((value) =>
48+
children.map((child) => [value, ...child])
49+
)
50+
}
51+
52+
const flagPermutations = getPermutations(Object.values(allFlagValues))
53+
const testCases = flagPermutations.map((flags) => ({
54+
name: flags.join(' '),
55+
flags,
56+
}))
57+
58+
let id = 0
59+
it.each(testCases)('$name', async ({ flags }) => {
60+
await useTempDir(async (cwd) => {
61+
const projectName = `cna-matrix-${pagesOrApp}-${id++}`
62+
const { exitCode } = await run(
63+
[projectName, ...flags],
64+
nextTgzFilename,
65+
{
66+
cwd,
67+
}
68+
)
69+
expect(exitCode).toBe(0)
70+
71+
await tryNextDev({
72+
cwd,
73+
projectName,
74+
isApp,
75+
})
76+
})
77+
})
78+
}
79+
)

0 commit comments

Comments
 (0)