-
Notifications
You must be signed in to change notification settings - Fork 31.9k
Expand file tree
/
Copy pathgenerate-browser-variant-aliases.mjs
More file actions
97 lines (90 loc) · 3.48 KB
/
Copy pathgenerate-browser-variant-aliases.mjs
File metadata and controls
97 lines (90 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// @ts-check
/**
* Generates the list of Next.js modules that have a browser-specific variant,
* i.e. a `<module>.ts` (the default, used on the server and any unbundled
* runtime) paired with a sibling `<module>.browser.ts`. The browser bundle is
* aliased to the `.browser` variant by both bundlers:
*
* - webpack: packages/next/src/build/create-compiler-aliases.ts
* - Turbopack: crates/next-core/src/next_import_map.rs
*
* Both consumers read the generated lists produced here so the set stays in
* sync with the filesystem. CI runs this script followed by `git diff
* --exit-code` to ensure the committed lists are up to date.
*/
import { execFileSync } from 'child_process'
import { writeFileSync } from 'fs'
import { join, dirname } from 'path'
import { fileURLToPath } from 'url'
const __dirname = dirname(fileURLToPath(import.meta.url))
const repoRoot = join(__dirname, '..')
const srcRel = 'packages/next/src'
const tsOut = join(repoRoot, srcRel, 'build/browser-variant-modules.ts')
const rsOut = join(repoRoot, 'crates/next-core/src/browser_variant_modules.rs')
/** Git-tracked files (posix paths relative to the repo root) under a pathspec. */
function trackedFiles(pathspec) {
return execFileSync('git', ['ls-files', '--', pathspec], {
cwd: repoRoot,
encoding: 'utf8',
})
.split('\n')
.filter(Boolean)
}
/**
* Find `<module>.browser.{ts,tsx}` files that have a base `<module>.{ts,tsx}`
* sibling, returning posix module paths relative to `packages/next/src` without
* an extension (e.g. `client/components/unstable-rethrow`). Enumerated from
* git so generated output, ignored files, and build artifacts never leak in.
*/
function collectModules() {
const tracked = trackedFiles(srcRel)
const trackedSet = new Set(tracked)
/** @type {string[]} */
const modules = []
for (const file of tracked) {
const match = file.match(/^(.*)\.browser\.tsx?$/)
if (!match) continue
const stem = match[1]
if (!trackedSet.has(`${stem}.ts`) && !trackedSet.has(`${stem}.tsx`))
continue
modules.push(stem.slice(srcRel.length + 1))
}
return modules.sort()
}
function renderTs(modules) {
const entries = modules.map((m) => ` '${m}',`).join('\n')
return `// This file is @generated by \`pnpm generate-browser-variant-aliases\`.
// Do not edit by hand.
//
// Modules with a \`.browser\` sibling. The default module is aliased to its
// \`.browser\` variant for the browser bundle in
// \`packages/next/src/build/create-compiler-aliases.ts\`. Paths are relative to
// \`packages/next/dist\` (extension omitted).
export const browserVariantModules = [
${entries}
] as const
`
}
function renderRust(modules) {
const entries = modules.map((m) => ` "${m}",`).join('\n')
return `//! This file is @generated by \`pnpm generate-browser-variant-aliases\`.
//! Do not edit by hand.
//!
//! Modules with a \`.browser\` sibling. The default module is aliased to its
//! \`.browser\` variant for the browser bundle in
//! \`get_next_client_resolved_map\` (see \`next_import_map.rs\`). Paths are
//! relative to \`next/dist\` (extension omitted).
// rustfmt::skip keeps this list one-per-line (and matching the generator
// output) instead of collapsing short lists onto a single line.
#[rustfmt::skip]
pub static BROWSER_VARIANT_MODULES: &[&str] = &[
${entries}
];
`
}
const modules = collectModules()
writeFileSync(tsOut, renderTs(modules))
writeFileSync(rsOut, renderRust(modules))
console.log(
`Generated ${modules.length} browser-variant module(s):\n ${modules.join('\n ')}`
)