forked from OHIF/Viewers
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreact-compiler.scope.cjs
More file actions
163 lines (146 loc) · 5.71 KB
/
Copy pathreact-compiler.scope.cjs
File metadata and controls
163 lines (146 loc) · 5.71 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
// Where the React Compiler applies.
//
// Every consumer of that decision reads this file, so changing the lists here
// changes all of them at once:
//
// babel.config.js the compiler pass (pnpm dev, package builds, jest)
// rsbuild.config.ts the compiler pass (pnpm dev:fast, pnpm build)
// eslint.config.mjs which files the compiler lint rules run on
// scripts/reactCompilerBudget.mjs which files the coverage gate scans
//
// A file is compiled when it sits under `<root>/src/` for one of `roots` and is
// not under any of `excluded`. Per-file opt-outs are still 'use no memo'
// directives in the source, tracked by .react-compiler-budget.json; this file
// is for whole directories.
//
// CommonJS because babel.config.js is CommonJS. The ESM and TS consumers import
// it without trouble.
const fs = require('node:fs');
const path = require('node:path');
const repoRoot = __dirname;
/** Workspace packages whose `src/` the compiler applies to. `*` matches one directory. */
const roots = [
'platform/app',
'platform/core',
'platform/i18n',
'platform/ui-next',
'extensions/*',
'modes/*',
];
/** Directories the compiler must never touch, even if they sit under a root. */
const excluded = [
// Frozen legacy UI package. Its rules-of-React violations were never counted
// in the lint budget, and its only in-app consumer is the LegacyWorkList route,
// which is itself opted out, so nothing compiled depends on it.
'platform/ui',
];
// REACT_COMPILER=off disables the compiler pass everywhere. It is a DIAGNOSTIC,
// not a fallback. 3.14 removed the hand-written useMemo/useCallback wrappers the
// compiler makes redundant, so with the pass off the app runs with LESS
// memoization than any release has ever shipped with. Components that depend on
// stable references - viewport overlays, effects keyed on callbacks - re-run or
// misbehave.
//
// That also changes what the switch tells you. "Works with it off, breaks with
// it on" used to point at the compiler. Now it usually means the component
// breaks the Rules of React by relying on re-running every render, and the
// compiler is right to stop that. Never build or deploy with the switch set.
const enabled = process.env.REACT_COMPILER !== 'off';
if (!enabled) {
console.warn(
'[react-compiler] REACT_COMPILER=off: the app is running with no memoization at all. ' +
'This is a diagnostic setting, not a fallback. Do not build or deploy this way.'
);
}
const SOURCE = /\.[jt]sx?$/;
/** Repo-relative, forward-slash form of an absolute or relative path. */
function toRelative(file) {
const rel = path.isAbsolute(file) ? path.relative(repoRoot, file) : file;
return rel.split(path.sep).join('/');
}
/** Does `rel` sit under `<root>/src/`? `*` in the root matches exactly one segment. */
function underRoot(rel, root) {
const want = root.split('/');
const have = rel.split('/');
if (have.length < want.length + 2) {
return false; // needs <root segments> + 'src' + at least a file name
}
return (
want.every((segment, i) => segment === '*' || segment === have[i]) &&
have[want.length] === 'src'
);
}
function isExcluded(rel) {
return excluded.some(dir => rel === dir || rel.startsWith(dir + '/'));
}
/**
* True when the compiler applies to this file. Accepts an absolute path (what
* babel and the bundlers pass) or a repo-relative one (what `git ls-files`
* prints). Anything outside the repo, under node_modules, not a JS/TS source
* file, or under an excluded directory is false.
*/
function isCompiled(file) {
if (!file) {
return false;
}
const rel = toRelative(file);
if (rel.startsWith('..') || /(^|\/)node_modules\//.test(rel)) {
return false;
}
if (!SOURCE.test(rel) || isExcluded(rel)) {
return false;
}
return roots.some(root => underRoot(rel, root));
}
// Derived forms, for the consumers that cannot take a predicate.
/** ESLint `files` globs. */
const globs = roots.map(root => `${root}/src/**/*.{js,jsx,ts,tsx}`);
/** ESLint `ignores` entries for the excluded directories. */
const ignoreGlobs = excluded.map(dir => `${dir}/**`);
/** `git ls-files` pathspecs. */
const gitPathspecs = roots.map(root => `${root}/src/**`);
// The bundlers treat a string condition as a plain prefix match on the absolute
// resource path. Every directory handed to them therefore ends in a separator:
// without it, `...\platform\ui` also matches every file under
// `...\platform\ui-next`, and all of ui-next silently stops being compiled.
// (The regexes this file replaced guarded the same edge with `(?!ui[\\/])`.)
const asDirPrefix = dir => path.join(repoRoot, dir) + path.sep;
/**
* Absolute `<root>/src/` directory prefixes for a bundler `include`, with `*`
* expanded against the directories present on disk. Read once at config time,
* so a package added while a dev server is running needs a restart - which is
* already true of everything else in the bundler config.
*/
function includeDirs() {
return roots.flatMap(root => {
const parts = root.split('/');
const star = parts.indexOf('*');
if (star === -1) {
return [asDirPrefix(path.join(root, 'src'))];
}
const parent = path.join(repoRoot, ...parts.slice(0, star));
if (!fs.existsSync(parent)) {
return [];
}
return fs
.readdirSync(parent)
.map(name => path.join(parent, name, ...parts.slice(star + 1), 'src'))
.filter(dir => fs.existsSync(dir))
.map(dir => dir + path.sep);
});
}
/** Absolute directory prefixes for a bundler `exclude`, separator-terminated. */
function excludeDirs() {
return excluded.map(asDirPrefix);
}
module.exports = {
enabled,
roots,
excluded,
isCompiled,
globs,
ignoreGlobs,
gitPathspecs,
includeDirs,
excludeDirs,
};