@quilted/rollup 0.1.19 → 0.2.0

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.
Files changed (126) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/build/esm/app.mjs +443 -219
  3. package/build/esm/constants.mjs +5 -5
  4. package/build/esm/features/assets.mjs +93 -81
  5. package/build/esm/features/async.mjs +186 -0
  6. package/build/esm/features/css.mjs +26 -39
  7. package/build/esm/features/env.mjs +47 -44
  8. package/build/esm/features/esnext.mjs +57 -0
  9. package/build/esm/features/graphql/transform.mjs +60 -56
  10. package/build/esm/features/graphql.mjs +65 -47
  11. package/build/esm/features/request-router.mjs +6 -4
  12. package/build/esm/features/source-code.mjs +54 -28
  13. package/build/esm/features/system-js.mjs +13 -18
  14. package/build/esm/features/typescript.mjs +13 -10
  15. package/build/esm/features/workers.mjs +173 -0
  16. package/build/esm/index.mjs +3 -2
  17. package/build/esm/module.mjs +69 -62
  18. package/build/esm/package.mjs +275 -84
  19. package/build/esm/server.mjs +118 -0
  20. package/build/esm/shared/browserslist.mjs +141 -16
  21. package/build/esm/shared/magic-module.mjs +9 -7
  22. package/build/esm/shared/package-json.mjs +7 -1
  23. package/build/esm/shared/path.mjs +7 -0
  24. package/build/esm/shared/rollup.mjs +89 -25
  25. package/build/esm/shared/strings.mjs +7 -6
  26. package/build/tsconfig.tsbuildinfo +1 -1
  27. package/build/typescript/app.d.ts +126 -27
  28. package/build/typescript/app.d.ts.map +1 -1
  29. package/build/typescript/features/assets.d.ts +1 -2
  30. package/build/typescript/features/assets.d.ts.map +1 -1
  31. package/build/typescript/features/async.d.ts +10 -0
  32. package/build/typescript/features/async.d.ts.map +1 -0
  33. package/build/typescript/features/css.d.ts +2 -1
  34. package/build/typescript/features/css.d.ts.map +1 -1
  35. package/build/typescript/features/env.d.ts +1 -0
  36. package/build/typescript/features/env.d.ts.map +1 -1
  37. package/build/typescript/features/esnext.d.ts +9 -0
  38. package/build/typescript/features/esnext.d.ts.map +1 -0
  39. package/build/typescript/features/graphql.d.ts +2 -2
  40. package/build/typescript/features/graphql.d.ts.map +1 -1
  41. package/build/typescript/features/source-code.d.ts +9 -3
  42. package/build/typescript/features/source-code.d.ts.map +1 -1
  43. package/build/typescript/features/workers.d.ts +52 -0
  44. package/build/typescript/features/workers.d.ts.map +1 -0
  45. package/build/typescript/index.d.ts +3 -2
  46. package/build/typescript/index.d.ts.map +1 -1
  47. package/build/typescript/module.d.ts +24 -6
  48. package/build/typescript/module.d.ts.map +1 -1
  49. package/build/typescript/package.d.ts +196 -4
  50. package/build/typescript/package.d.ts.map +1 -1
  51. package/build/typescript/server.d.ts +98 -0
  52. package/build/typescript/server.d.ts.map +1 -0
  53. package/build/typescript/shared/browserslist.d.ts +20 -3
  54. package/build/typescript/shared/browserslist.d.ts.map +1 -1
  55. package/build/typescript/shared/path.d.ts +2 -0
  56. package/build/typescript/shared/path.d.ts.map +1 -0
  57. package/build/typescript/shared/rollup.d.ts +27 -1
  58. package/build/typescript/shared/rollup.d.ts.map +1 -1
  59. package/configuration/rollup.config.js +40 -0
  60. package/package.json +61 -8
  61. package/source/app.ts +466 -96
  62. package/source/features/assets.ts +5 -7
  63. package/source/features/async.ts +249 -0
  64. package/source/features/css.ts +4 -2
  65. package/source/features/env.ts +6 -0
  66. package/source/features/esnext.ts +70 -0
  67. package/source/features/graphql.ts +4 -2
  68. package/source/features/source-code.ts +26 -8
  69. package/source/features/workers.ts +292 -0
  70. package/source/index.ts +4 -0
  71. package/source/module.ts +45 -19
  72. package/source/package.ts +394 -36
  73. package/source/server.ts +245 -0
  74. package/source/shared/browserslist.ts +208 -18
  75. package/source/shared/path.ts +5 -0
  76. package/source/shared/rollup.ts +102 -4
  77. package/tsconfig.json +6 -2
  78. package/build/cjs/app.cjs +0 -441
  79. package/build/cjs/constants.cjs +0 -13
  80. package/build/cjs/features/assets.cjs +0 -240
  81. package/build/cjs/features/css.cjs +0 -71
  82. package/build/cjs/features/env.cjs +0 -135
  83. package/build/cjs/features/graphql/transform.cjs +0 -186
  84. package/build/cjs/features/graphql.cjs +0 -86
  85. package/build/cjs/features/request-router.cjs +0 -31
  86. package/build/cjs/features/source-code.cjs +0 -54
  87. package/build/cjs/features/system-js.cjs +0 -36
  88. package/build/cjs/features/typescript.cjs +0 -56
  89. package/build/cjs/index.cjs +0 -13
  90. package/build/cjs/module.cjs +0 -121
  91. package/build/cjs/package.cjs +0 -170
  92. package/build/cjs/shared/browserslist.cjs +0 -25
  93. package/build/cjs/shared/magic-module.cjs +0 -32
  94. package/build/cjs/shared/package-json.cjs +0 -31
  95. package/build/cjs/shared/rollup.cjs +0 -72
  96. package/build/cjs/shared/strings.cjs +0 -16
  97. package/build/esnext/app.esnext +0 -414
  98. package/build/esnext/constants.esnext +0 -7
  99. package/build/esnext/features/assets.esnext +0 -215
  100. package/build/esnext/features/css.esnext +0 -69
  101. package/build/esnext/features/env.esnext +0 -112
  102. package/build/esnext/features/graphql/transform.esnext +0 -181
  103. package/build/esnext/features/graphql.esnext +0 -84
  104. package/build/esnext/features/request-router.esnext +0 -29
  105. package/build/esnext/features/source-code.esnext +0 -51
  106. package/build/esnext/features/system-js.esnext +0 -33
  107. package/build/esnext/features/typescript.esnext +0 -34
  108. package/build/esnext/index.esnext +0 -3
  109. package/build/esnext/module.esnext +0 -100
  110. package/build/esnext/package.esnext +0 -148
  111. package/build/esnext/shared/browserslist.esnext +0 -23
  112. package/build/esnext/shared/magic-module.esnext +0 -30
  113. package/build/esnext/shared/package-json.esnext +0 -10
  114. package/build/esnext/shared/rollup.esnext +0 -49
  115. package/build/esnext/shared/strings.esnext +0 -14
  116. package/build/typescript/env.d.ts +0 -55
  117. package/build/typescript/env.d.ts.map +0 -1
  118. package/build/typescript/graphql/transform.d.ts +0 -17
  119. package/build/typescript/graphql/transform.d.ts.map +0 -1
  120. package/build/typescript/graphql.d.ts +0 -6
  121. package/build/typescript/graphql.d.ts.map +0 -1
  122. package/build/typescript/request-router.d.ts +0 -15
  123. package/build/typescript/request-router.d.ts.map +0 -1
  124. package/build/typescript/shared/source-code.d.ts +0 -5
  125. package/build/typescript/shared/source-code.d.ts.map +0 -1
  126. package/quilt.project.ts +0 -5
@@ -17,11 +17,10 @@ import type {
17
17
  } from '@quilted/assets';
18
18
 
19
19
  export interface AssetManifestOptions {
20
- id?: string;
21
20
  file: string;
22
21
  baseURL: string;
23
22
  priority?: number;
24
- cacheKey?: Record<string, any>;
23
+ cacheKey?: URLSearchParams;
25
24
  }
26
25
 
27
26
  export function assetManifest(manifestOptions: AssetManifestOptions): Plugin {
@@ -36,7 +35,7 @@ export function assetManifest(manifestOptions: AssetManifestOptions): Plugin {
36
35
  async function writeManifestForBundle(
37
36
  this: PluginContext,
38
37
  bundle: OutputBundle,
39
- {id, file, baseURL, cacheKey, priority}: AssetManifestOptions,
38
+ {file, baseURL, cacheKey, priority}: AssetManifestOptions,
40
39
  {format}: NormalizedOutputOptions,
41
40
  ) {
42
41
  const outputs = Object.values(bundle);
@@ -77,10 +76,9 @@ async function writeManifestForBundle(
77
76
  return id;
78
77
  }
79
78
 
80
- const manifest: AssetsBuildManifest<any> = {
81
- id,
79
+ const manifest: AssetsBuildManifest = {
82
80
  priority,
83
- cacheKey,
81
+ cacheKey: cacheKey && cacheKey.size > 0 ? cacheKey.toString() : undefined,
84
82
  assets,
85
83
  attributes: format === 'es' ? {scripts: {type: 'module'}} : undefined,
86
84
  entries: {
@@ -101,7 +99,7 @@ async function writeManifestForBundle(
101
99
  if (originalModuleId == null) continue;
102
100
 
103
101
  // This metadata is added by the rollup plugin for @quilted/async
104
- const moduleId = this.getModuleInfo(originalModuleId)?.meta.quilt?.moduleId;
102
+ const moduleId = this.getModuleInfo(originalModuleId)?.meta.quilt?.moduleID;
105
103
 
106
104
  if (moduleId == null) continue;
107
105
 
@@ -0,0 +1,249 @@
1
+ import {createHash} from 'crypto';
2
+ import {posix, sep} from 'path';
3
+
4
+ import type {Plugin, OutputChunk, OutputBundle} from 'rollup';
5
+ import {multiline} from '../shared/strings.ts';
6
+ import MagicString from 'magic-string';
7
+
8
+ const MODULE_PREFIX = 'quilt-async-module:';
9
+ const IMPORT_PREFIX = 'quilt-async-import:';
10
+
11
+ export interface Options {
12
+ preload?: boolean;
13
+ baseURL?: string;
14
+ moduleID?(details: {imported: string}): string;
15
+ }
16
+
17
+ export function asyncModules({
18
+ preload = true,
19
+ baseURL = '/assets/',
20
+ moduleID: getModuleID = defaultModuleID,
21
+ }: Options = {}): Plugin {
22
+ return {
23
+ name: '@quilted/async',
24
+ async resolveId(id, importer) {
25
+ if (id.startsWith(IMPORT_PREFIX)) return `\0${id}`;
26
+ if (!id.startsWith(MODULE_PREFIX)) return null;
27
+
28
+ const imported = id.replace(MODULE_PREFIX, '');
29
+
30
+ const resolved = await this.resolve(imported, importer, {
31
+ skipSelf: true,
32
+ });
33
+
34
+ if (resolved == null) return null;
35
+
36
+ return `\0${MODULE_PREFIX}${resolved.id}`;
37
+ },
38
+ resolveDynamicImport(specifier) {
39
+ if (
40
+ typeof specifier === 'string' &&
41
+ specifier.startsWith(IMPORT_PREFIX)
42
+ ) {
43
+ return `\0${specifier}`;
44
+ }
45
+
46
+ return null;
47
+ },
48
+ async load(id: string) {
49
+ if (id.startsWith(`\0${MODULE_PREFIX}`)) {
50
+ const imported = id.replace(`\0${MODULE_PREFIX}`, '');
51
+ const moduleID = getModuleID({imported});
52
+
53
+ const code = multiline`
54
+ const id = ${JSON.stringify(moduleID)};
55
+
56
+ export default function createAsyncModule(load) {
57
+ return {
58
+ id,
59
+ import: () => import(${JSON.stringify(
60
+ `${IMPORT_PREFIX}${imported}`,
61
+ )}).then((module) => module.default),
62
+ };
63
+ }
64
+ `;
65
+
66
+ return code;
67
+ }
68
+
69
+ if (id.startsWith(`\0${IMPORT_PREFIX}`)) {
70
+ const imported = id.replace(`\0${IMPORT_PREFIX}`, '');
71
+ const moduleID = getModuleID({imported});
72
+
73
+ const code = multiline`
74
+ import * as AsyncModule from ${JSON.stringify(imported)};
75
+
76
+ ((globalThis[Symbol.for('quilt')] ??= {}).AsyncModules ??= new Map).set(${JSON.stringify(
77
+ moduleID,
78
+ )}, AsyncModule);
79
+
80
+ export default AsyncModule;
81
+ `;
82
+
83
+ return {
84
+ code,
85
+ meta: {
86
+ quilt: {moduleID},
87
+ },
88
+ };
89
+ }
90
+
91
+ return null;
92
+ },
93
+ transform: baseURL
94
+ ? (code) =>
95
+ code.replace(/__QUILT_ASSETS_BASE_URL__/g, JSON.stringify(baseURL))
96
+ : undefined,
97
+ async generateBundle(options, bundle) {
98
+ if (preload) {
99
+ switch (options.format) {
100
+ case 'es': {
101
+ await preloadAsyncAssetsInESMBundle(bundle);
102
+ break;
103
+ }
104
+ case 'system': {
105
+ await preloadAsyncAssetsInSystemJSBundle(bundle);
106
+ break;
107
+ }
108
+ }
109
+ }
110
+ },
111
+ };
112
+ }
113
+
114
+ function defaultModuleID({imported}: {imported: string}) {
115
+ const name = imported.split(sep).pop()!.split('.')[0]!;
116
+
117
+ const hash = createHash('sha256')
118
+ .update(imported)
119
+ .digest('hex')
120
+ .substring(0, 8);
121
+
122
+ return `${name}_${hash}`;
123
+ }
124
+
125
+ async function preloadAsyncAssetsInESMBundle(bundle: OutputBundle) {
126
+ const {parse: parseImports} = await import('es-module-lexer');
127
+
128
+ for (const chunk of Object.values(bundle)) {
129
+ if (chunk.type !== 'chunk') continue;
130
+ if (chunk.dynamicImports.length === 0) continue;
131
+
132
+ const {code} = chunk;
133
+
134
+ const newCode = new MagicString(code);
135
+
136
+ const imports = (await parseImports(code))[0];
137
+
138
+ for (const imported of imports) {
139
+ const {s: start, e: end, ss: importStart, d: dynamicStart} = imported;
140
+
141
+ // es-module-lexer only sets `d >= 0` when the import is a dynamic one
142
+ if (dynamicStart < 0) continue;
143
+
144
+ // Get rid of the quotes
145
+ const importSource = code.slice(start + 1, end - 1);
146
+
147
+ const dependencies = getDependenciesForImport(
148
+ importSource,
149
+ chunk,
150
+ bundle,
151
+ );
152
+
153
+ // The only dependency is the file itself, no need to preload
154
+ if (dependencies.size === 1) continue;
155
+
156
+ const originalImport = code.slice(importStart, end + 1);
157
+ newCode.overwrite(
158
+ importStart,
159
+ end + 1,
160
+ preloadContentForDependencies(dependencies, originalImport),
161
+ );
162
+ }
163
+
164
+ chunk.code = newCode.toString();
165
+ }
166
+ }
167
+
168
+ async function preloadAsyncAssetsInSystemJSBundle(bundle: OutputBundle) {
169
+ for (const chunk of Object.values(bundle)) {
170
+ if (chunk.type !== 'chunk') continue;
171
+ if (chunk.dynamicImports.length === 0) continue;
172
+
173
+ const {code} = chunk;
174
+
175
+ const newCode = new MagicString(code);
176
+
177
+ const systemDynamicImportRegex = /\bmodule\.import\(([^)]*)\)/g;
178
+
179
+ let match: RegExpExecArray | null;
180
+
181
+ while ((match = systemDynamicImportRegex.exec(code))) {
182
+ const [originalImport, imported] = match;
183
+
184
+ // Get rid of surrounding space and quotes
185
+ const importSource = imported!.trim().slice(1, imported!.length - 1);
186
+
187
+ const dependencies = getDependenciesForImport(
188
+ importSource,
189
+ chunk,
190
+ bundle,
191
+ );
192
+
193
+ if (dependencies.size === 1) continue;
194
+
195
+ newCode.overwrite(
196
+ match.index,
197
+ match.index + originalImport!.length,
198
+ preloadContentForDependencies(dependencies, originalImport!),
199
+ );
200
+ }
201
+
202
+ chunk.code = newCode.toString();
203
+ }
204
+ }
205
+
206
+ function preloadContentForDependencies(
207
+ dependencies: Iterable<string>,
208
+ originalExpression: string,
209
+ ) {
210
+ return `Promise.resolve().then(() => globalThis[Symbol.for('quilt')]?.AsyncModules?.preload?.(${Array.from(
211
+ dependencies,
212
+ )
213
+ .map((dependency) => JSON.stringify(dependency))
214
+ .join(',')})).then(function(){return ${originalExpression}})`;
215
+ }
216
+
217
+ function getDependenciesForImport(
218
+ imported: string,
219
+ chunk: OutputChunk,
220
+ bundle: OutputBundle,
221
+ ) {
222
+ const originalFilename = chunk.fileName;
223
+ const dependencies = new Set<string>();
224
+ const analyzed = new Set<string>();
225
+
226
+ const normalizedFile = posix.join(posix.dirname(originalFilename), imported);
227
+
228
+ const addDependencies = (filename: string) => {
229
+ if (filename === originalFilename) return;
230
+ if (analyzed.has(filename)) return;
231
+
232
+ analyzed.add(filename);
233
+ const chunk = bundle[filename];
234
+
235
+ if (chunk == null) return;
236
+
237
+ dependencies.add(chunk.fileName);
238
+
239
+ if (chunk.type !== 'chunk') return;
240
+
241
+ for (const imported of chunk.imports) {
242
+ addDependencies(imported);
243
+ }
244
+ };
245
+
246
+ addDependencies(normalizedFile);
247
+
248
+ return dependencies;
249
+ }
@@ -3,12 +3,13 @@ import type {Plugin} from 'rollup';
3
3
  export interface Options {
4
4
  minify?: boolean;
5
5
  emit?: boolean;
6
+ targets?: string[];
6
7
  }
7
8
 
8
9
  const CSS_REGEX = /\.css$/;
9
10
  const CSS_MODULE_REGEX = /\.module\.css$/;
10
11
 
11
- export function css({minify = true, emit = true}: Options) {
12
+ export function css({minify = true, emit = true, targets}: Options) {
12
13
  const styles = new Map<string, string>();
13
14
 
14
15
  return {
@@ -16,13 +17,14 @@ export function css({minify = true, emit = true}: Options) {
16
17
  async transform(code, id) {
17
18
  if (!CSS_REGEX.test(id)) return;
18
19
 
19
- const {transform} = await import('lightningcss');
20
+ const {transform, browserslistToTargets} = await import('lightningcss');
20
21
 
21
22
  const transformed = transform({
22
23
  filename: id,
23
24
  code: new TextEncoder().encode(code),
24
25
  cssModules: CSS_MODULE_REGEX.test(id),
25
26
  minify: emit && minify,
27
+ targets: targets ? browserslistToTargets(targets) : undefined,
26
28
  });
27
29
 
28
30
  styles.set(id, new TextDecoder().decode(transformed.code));
@@ -69,6 +69,12 @@ export interface MagicModuleEnvOptions {
69
69
  | {roots?: never; files?: string[]};
70
70
  }
71
71
 
72
+ export function resolveEnvOption(
73
+ option?: MagicModuleEnvOptions['mode'] | MagicModuleEnvOptions,
74
+ ) {
75
+ return typeof option === 'string' ? {mode: option} : option ?? {};
76
+ }
77
+
72
78
  export function magicModuleEnv({
73
79
  mode,
74
80
  dotenv = {roots: ['.', 'configuration']},
@@ -0,0 +1,70 @@
1
+ import {createRequire} from 'module';
2
+
3
+ import babel, {type RollupBabelInputPluginOptions} from '@rollup/plugin-babel';
4
+ import esbuild from 'rollup-plugin-esbuild';
5
+
6
+ const require = createRequire(import.meta.url);
7
+
8
+ export function esnext({
9
+ mode,
10
+ targets,
11
+ babel: useBabel = true,
12
+ }: {
13
+ mode?: 'development' | 'production';
14
+ targets?: readonly string[];
15
+ babel?:
16
+ | boolean
17
+ | {
18
+ options?(
19
+ options: RollupBabelInputPluginOptions,
20
+ ): RollupBabelInputPluginOptions | void;
21
+ };
22
+ }) {
23
+ if (!useBabel) {
24
+ return esbuild({
25
+ // Support very modern features
26
+ include: /\.esnext$/,
27
+ target: 'es2022',
28
+ loaders: {
29
+ '.esnext': 'js',
30
+ },
31
+ });
32
+ }
33
+
34
+ let babelOptions: RollupBabelInputPluginOptions = {
35
+ envName: mode,
36
+ configFile: false,
37
+ babelrc: false,
38
+ presets: [
39
+ [
40
+ require.resolve('@babel/preset-env'),
41
+ {
42
+ useBuiltIns: false,
43
+ bugfixes: true,
44
+ shippedProposals: true,
45
+ // I thought I wanted this, but it seems to break the `targets` option
46
+ // passed as a root argument.
47
+ // ignoreBrowserslistConfig: targets != null,
48
+ } satisfies import('@babel/preset-env').Options,
49
+ ],
50
+ ],
51
+ plugins: [
52
+ [
53
+ require.resolve('@babel/plugin-proposal-decorators'),
54
+ {version: '2023-01'},
55
+ ],
56
+ ],
57
+ include: /\.esnext$/,
58
+ extensions: ['.esnext'],
59
+ babelHelpers: 'bundled',
60
+ skipPreflightCheck: true,
61
+ // Babel doesn’t like this option being set to `undefined`.
62
+ ...(targets ? {targets: targets as string[]} : {}),
63
+ };
64
+
65
+ if (typeof useBabel === 'object') {
66
+ babelOptions = useBabel.options?.(babelOptions) ?? babelOptions;
67
+ }
68
+
69
+ return babel(babelOptions);
70
+ }
@@ -10,11 +10,11 @@ import {
10
10
  extractGraphQLImports,
11
11
  } from './graphql/transform.ts';
12
12
 
13
- export interface Options {
13
+ export interface GraphQLOptions {
14
14
  manifest?: string | boolean;
15
15
  }
16
16
 
17
- export function graphql({manifest}: Options = {}): Plugin {
17
+ export function graphql({manifest}: GraphQLOptions = {}): Plugin {
18
18
  const shouldWriteManifest = Boolean(manifest);
19
19
  const manifestPath =
20
20
  typeof manifest === 'string' ? manifest : `manifests/graphql.json`;
@@ -75,6 +75,8 @@ export function graphql({manifest}: Options = {}): Plugin {
75
75
  }
76
76
  }
77
77
 
78
+ if (Object.keys(operations).length === 0) return;
79
+
78
80
  await mkdir(dirname(manifestPath), {recursive: true});
79
81
  await writeFile(manifestPath, JSON.stringify(operations, null, 2));
80
82
  },
@@ -1,18 +1,28 @@
1
1
  import {createRequire} from 'module';
2
2
 
3
- import babel from '@rollup/plugin-babel';
3
+ import babel, {type RollupBabelInputPluginOptions} from '@rollup/plugin-babel';
4
4
  import esbuild from 'rollup-plugin-esbuild';
5
+ import type {Options as PresetEnvOptions} from '@babel/preset-env';
5
6
 
6
7
  const require = createRequire(import.meta.url);
7
8
 
8
9
  export function sourceCode({
9
10
  mode,
10
11
  targets,
12
+ react = true,
11
13
  babel: useBabel = true,
12
14
  }: {
13
15
  mode?: 'development' | 'production';
14
- targets?: string[];
15
- babel?: boolean;
16
+ react?: boolean | 'react' | 'preact';
17
+ targets?: readonly string[];
18
+ babel?:
19
+ | boolean
20
+ | {
21
+ useBuiltIns?: PresetEnvOptions['useBuiltIns'];
22
+ options?(
23
+ options: RollupBabelInputPluginOptions,
24
+ ): RollupBabelInputPluginOptions | void;
25
+ };
16
26
  }) {
17
27
  if (!useBabel) {
18
28
  return esbuild({
@@ -24,7 +34,10 @@ export function sourceCode({
24
34
  });
25
35
  }
26
36
 
27
- return babel({
37
+ const babelOverride = typeof useBabel === 'boolean' ? {} : useBabel;
38
+ const useBuiltIns = babelOverride.useBuiltIns;
39
+
40
+ let babelOptions: RollupBabelInputPluginOptions = {
28
41
  envName: mode,
29
42
  configFile: false,
30
43
  babelrc: false,
@@ -34,16 +47,17 @@ export function sourceCode({
34
47
  require.resolve('@babel/preset-react'),
35
48
  {
36
49
  runtime: 'automatic',
37
- importSource: 'react',
50
+ importSource: typeof react === 'string' ? react : 'react',
38
51
  development: mode === 'development',
39
52
  },
40
53
  ],
41
54
  [
42
55
  require.resolve('@babel/preset-env'),
43
56
  {
44
- useBuiltIns: false,
45
57
  bugfixes: true,
46
58
  shippedProposals: true,
59
+ useBuiltIns,
60
+ corejs: useBuiltIns ? 3 : undefined,
47
61
  // I thought I wanted this, but it seems to break the `targets` option
48
62
  // passed as a root argument.
49
63
  // ignoreBrowserslistConfig: targets != null,
@@ -71,6 +85,10 @@ export function sourceCode({
71
85
  babelHelpers: 'bundled',
72
86
  skipPreflightCheck: true,
73
87
  // Babel doesn’t like this option being set to `undefined`.
74
- ...(targets ? {targets} : {}),
75
- });
88
+ ...(targets ? {targets: targets as string[]} : {}),
89
+ };
90
+
91
+ babelOptions = babelOverride.options?.(babelOptions) ?? babelOptions;
92
+
93
+ return babel(babelOptions);
76
94
  }