@atlaspack/transformer-js 3.2.3-canary.49 → 3.2.3-canary.490

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.
@@ -1,17 +1,24 @@
1
- // @flow
2
1
  import type {
3
2
  JSONObject,
4
3
  EnvMap,
5
4
  SourceLocation,
6
5
  FilePath,
7
6
  FileCreateInvalidation,
8
- ConditionMeta,
7
+ Config,
8
+ PluginOptions,
9
9
  } from '@atlaspack/types';
10
+ import {createBuildCache} from '@atlaspack/build-cache';
10
11
  import type {SchemaEntity} from '@atlaspack/utils';
11
12
  import type {Diagnostic} from '@atlaspack/diagnostic';
12
- import SourceMap from '@parcel/source-map';
13
+ import SourceMap from '@atlaspack/source-map';
13
14
  import {Transformer} from '@atlaspack/plugin';
14
- import {transform, transformAsync} from '@atlaspack/rust';
15
+ import {
16
+ transform,
17
+ transformAsync,
18
+ determineJsxConfiguration,
19
+ } from '@atlaspack/rust';
20
+ import {type CompiledCssInJsConfigPlugin} from '@atlaspack/rust';
21
+ import invariant from 'assert';
15
22
  import browserslist from 'browserslist';
16
23
  import semver from 'semver';
17
24
  import nullthrows from 'nullthrows';
@@ -22,11 +29,12 @@ import ThrowableDiagnostic, {
22
29
  import {validateSchema, remapSourceLocation, globMatch} from '@atlaspack/utils';
23
30
  import pkg from '../package.json';
24
31
  import {getFeatureFlag} from '@atlaspack/feature-flags';
32
+ import path, {join} from 'path';
25
33
 
26
34
  const JSX_EXTENSIONS = {
27
35
  jsx: true,
28
36
  tsx: true,
29
- };
37
+ } as const;
30
38
 
31
39
  const JSX_PRAGMA = {
32
40
  react: {
@@ -49,7 +57,7 @@ const JSX_PRAGMA = {
49
57
  pragmaFrag: undefined,
50
58
  automatic: undefined,
51
59
  },
52
- };
60
+ } as const;
53
61
 
54
62
  const BROWSER_MAPPING = {
55
63
  and_chr: 'chrome',
@@ -63,7 +71,7 @@ const BROWSER_MAPPING = {
63
71
  bb: null,
64
72
  kaios: null,
65
73
  op_mini: null,
66
- };
74
+ } as const;
67
75
 
68
76
  // List of browsers to exclude when the esmodule target is specified.
69
77
  // Based on https://caniuse.com/#feat=es6-module
@@ -108,16 +116,35 @@ const CONFIG_SCHEMA: SchemaEntity = {
108
116
  },
109
117
  ],
110
118
  },
119
+ addReactDisplayName: {
120
+ type: 'boolean',
121
+ },
111
122
  magicComments: {
112
123
  type: 'boolean',
113
124
  },
114
125
  unstable_inlineConstants: {
115
126
  type: 'boolean',
116
127
  },
128
+ jsx: {
129
+ type: 'object',
130
+ },
117
131
  },
118
132
  additionalProperties: false,
119
133
  };
120
134
 
135
+ // Mirrors the CONFIG_SCHEMA
136
+ interface JsTransformerConfig {
137
+ inlineFS?: boolean;
138
+ inlineEnvironment?: boolean | string[];
139
+ addReactDisplayName?: boolean;
140
+ magicComments?: boolean;
141
+ unstable_inlineConstants?: boolean;
142
+ // This is exclusively used in Rust so not worth typing
143
+ jsx: any;
144
+ }
145
+
146
+ const configCache = createBuildCache();
147
+
121
148
  const SCRIPT_ERRORS = {
122
149
  browser: {
123
150
  message: 'Browser scripts cannot have imports or exports.',
@@ -133,143 +160,306 @@ const SCRIPT_ERRORS = {
133
160
  'Service workers cannot have imports or exports without the `type: "module"` option.',
134
161
  hint: "Add {type: 'module'} as a second argument to the navigator.serviceWorker.register() call.",
135
162
  },
136
- };
163
+ } as const;
137
164
 
138
165
  type TSConfig = {
139
166
  compilerOptions?: {
140
167
  // https://www.typescriptlang.org/tsconfig#jsx
141
- jsx?: 'react' | 'react-jsx' | 'react-jsxdev' | 'preserve' | 'react-native',
168
+ jsx?: 'react' | 'react-jsx' | 'react-jsxdev' | 'preserve' | 'react-native';
142
169
  // https://www.typescriptlang.org/tsconfig#jsxFactory
143
- jsxFactory?: string,
170
+ jsxFactory?: string;
144
171
  // https://www.typescriptlang.org/tsconfig#jsxFragmentFactory
145
- jsxFragmentFactory?: string,
172
+ jsxFragmentFactory?: string;
146
173
  // https://www.typescriptlang.org/tsconfig#jsxImportSource
147
- jsxImportSource?: string,
174
+ jsxImportSource?: string;
148
175
  // https://www.typescriptlang.org/tsconfig#experimentalDecorators
149
- experimentalDecorators?: boolean,
176
+ experimentalDecorators?: boolean;
150
177
  // https://www.typescriptlang.org/tsconfig#useDefineForClassFields
151
- useDefineForClassFields?: boolean,
178
+ useDefineForClassFields?: boolean;
152
179
  // https://www.typescriptlang.org/tsconfig#target
153
- target?: string, // 'es3' | 'es5' | 'es6' | 'es2015' | ... |'es2022' | ... | 'esnext'
154
- ...
155
- },
156
- ...
180
+ target?: string; // 'es3' | 'es5' | 'es6' | 'es2015' | ... |'es2022' | ... | 'esnext';
181
+ };
157
182
  };
158
183
 
159
- type MacroAsset = {|
160
- type: string,
161
- content: string,
162
- |};
184
+ type MacroAsset = {
185
+ type: string;
186
+ content: string;
187
+ };
163
188
 
164
189
  // NOTE: Make sure this is in sync with the TypeScript definition in the @atlaspack/macros package.
165
- type MacroContext = {|
166
- addAsset(asset: MacroAsset): void,
167
- invalidateOnFileChange(FilePath): void,
168
- invalidateOnFileCreate(FileCreateInvalidation): void,
169
- invalidateOnEnvChange(string): void,
170
- invalidateOnStartup(): void,
171
- invalidateOnBuild(): void,
172
- |};
173
-
174
- export default (new Transformer({
175
- async loadConfig({config, options}) {
176
- let pkg = await config.getPackage();
177
- let isJSX,
178
- pragma,
179
- pragmaFrag,
180
- jsxImportSource,
181
- automaticJSXRuntime,
182
- reactRefresh,
183
- decorators,
184
- useDefineForClassFields;
185
- if (config.isSource) {
186
- let reactLib;
187
- if (pkg?.alias && pkg.alias['react']) {
188
- // e.g.: `{ alias: { "react": "preact/compat" } }`
189
- reactLib = 'react';
190
- } else {
191
- // Find a dependency that we can map to a JSX pragma
192
- reactLib = Object.keys(JSX_PRAGMA).find(
193
- (libName) =>
194
- pkg?.dependencies?.[libName] ||
195
- pkg?.devDependencies?.[libName] ||
196
- pkg?.peerDependencies?.[libName],
197
- );
198
- }
190
+ type MacroContext = {
191
+ addAsset(asset: MacroAsset): void;
192
+ invalidateOnFileChange(arg1: FilePath): void;
193
+ invalidateOnFileCreate(arg1: FileCreateInvalidation): void;
194
+ invalidateOnEnvChange(arg1: string): void;
195
+ invalidateOnStartup(): void;
196
+ invalidateOnBuild(): void;
197
+ };
199
198
 
200
- reactRefresh =
201
- options.hmrOptions &&
202
- options.mode === 'development' &&
203
- Boolean(
204
- pkg?.dependencies?.react ||
205
- pkg?.devDependencies?.react ||
206
- pkg?.peerDependencies?.react,
207
- );
199
+ type AtlaskitTokensConfigPartial = {
200
+ shouldUseAutoFallback?: boolean;
201
+ shouldForceAutoFallback?: boolean;
202
+ forceAutoFallbackExemptions?: Array<string>;
203
+ defaultTheme?: 'light' | 'legacy-light';
204
+ tokenDataPath: string;
205
+ };
208
206
 
209
- const compilerOptions: TSConfig['compilerOptions'] = getFeatureFlag(
210
- 'granularTsConfigInvalidation',
211
- )
212
- ? (
213
- await config.getConfigFrom<TSConfig['compilerOptions']>(
214
- options.projectRoot + '/index',
215
- ['tsconfig.json', 'jsconfig.json'],
216
- {configKey: 'compilerOptions'},
217
- )
218
- )?.contents
219
- : (
220
- await config.getConfigFrom<TSConfig>(
221
- options.projectRoot + '/index',
222
- ['tsconfig.json', 'jsconfig.json'],
223
- )
224
- )?.contents?.compilerOptions;
225
-
226
- // Use explicitly defined JSX options in tsconfig.json over inferred values from dependencies.
227
- pragma =
228
- compilerOptions?.jsxFactory ||
229
- (reactLib ? JSX_PRAGMA[reactLib].pragma : undefined);
230
- pragmaFrag =
231
- compilerOptions?.jsxFragmentFactory ||
232
- (reactLib ? JSX_PRAGMA[reactLib].pragmaFrag : undefined);
207
+ type AtlaskitTokensConfig = Required<AtlaskitTokensConfigPartial>;
233
208
 
234
- if (
235
- compilerOptions?.jsx === 'react-jsx' ||
236
- compilerOptions?.jsx === 'react-jsxdev' ||
237
- compilerOptions?.jsxImportSource
238
- ) {
239
- jsxImportSource = compilerOptions?.jsxImportSource;
240
- automaticJSXRuntime = true;
241
- } else if (reactLib) {
242
- let effectiveReactLib =
243
- pkg?.alias && pkg.alias['react'] === 'preact/compat'
244
- ? 'preact'
245
- : reactLib;
246
- let automaticVersion = JSX_PRAGMA[effectiveReactLib]?.automatic;
247
- let reactLibVersion =
248
- pkg?.dependencies?.[effectiveReactLib] ||
249
- pkg?.devDependencies?.[effectiveReactLib] ||
250
- pkg?.peerDependencies?.[effectiveReactLib];
251
- reactLibVersion = reactLibVersion
252
- ? semver.validRange(reactLibVersion)
209
+ const TOKENS_CONFIG_SCHEMA = {
210
+ type: 'object',
211
+ properties: {
212
+ shouldUseAutoFallback: {type: 'boolean'},
213
+ shouldForceAutoFallback: {type: 'boolean'},
214
+ forceAutoFallbackExemptions: {
215
+ type: 'array',
216
+ items: {type: 'string'},
217
+ },
218
+ defaultTheme: {type: 'string', enum: ['light', 'legacy-light']},
219
+ tokenDataPath: {type: 'string'},
220
+ },
221
+ additionalProperties: false,
222
+ } as const;
223
+
224
+ interface JsxConfig {
225
+ isJSX: boolean | undefined;
226
+ jsxPragma: string | undefined;
227
+ jsxPragmaFrag: string | undefined;
228
+ jsxImportSource: string | undefined;
229
+ automaticJSXRuntime: boolean | undefined;
230
+ reactRefresh: boolean | null | undefined;
231
+ }
232
+
233
+ async function legacyDetemineJsxConfig(
234
+ config: Config,
235
+ options: PluginOptions,
236
+ ): Promise<JsxConfig> {
237
+ let packageJson = await config.getPackage();
238
+ let isJSX,
239
+ jsxPragma,
240
+ jsxPragmaFrag,
241
+ jsxImportSource,
242
+ automaticJSXRuntime,
243
+ reactRefresh;
244
+
245
+ if (config.isSource) {
246
+ let reactLib;
247
+ if (packageJson?.alias && packageJson.alias['react']) {
248
+ // e.g.: `{ alias: { "react": "preact/compat" } }`
249
+ reactLib = 'react';
250
+ } else {
251
+ // Find a dependency that we can map to a JSX pragma
252
+ reactLib = Object.keys(JSX_PRAGMA).find(
253
+ (libName) =>
254
+ packageJson?.dependencies?.[libName] ||
255
+ packageJson?.devDependencies?.[libName] ||
256
+ packageJson?.peerDependencies?.[libName],
257
+ );
258
+ }
259
+
260
+ reactRefresh = Boolean(
261
+ packageJson?.dependencies?.react ||
262
+ packageJson?.devDependencies?.react ||
263
+ packageJson?.peerDependencies?.react,
264
+ );
265
+
266
+ const compilerOptions: TSConfig['compilerOptions'] = (
267
+ await config.getConfigFrom<TSConfig>(
268
+ options.projectRoot + '/index',
269
+ ['tsconfig.json', 'jsconfig.json'],
270
+ {
271
+ readTracking: true,
272
+ },
273
+ )
274
+ )?.contents?.compilerOptions;
275
+
276
+ // Use explicitly defined JSX options in tsconfig.json over inferred values from dependencies.
277
+ jsxPragma =
278
+ compilerOptions?.jsxFactory ||
279
+ // @ts-expect-error TS7053
280
+ (reactLib ? JSX_PRAGMA[reactLib].pragma : undefined);
281
+ jsxPragmaFrag =
282
+ compilerOptions?.jsxFragmentFactory ||
283
+ // @ts-expect-error TS7053
284
+ (reactLib ? JSX_PRAGMA[reactLib].pragmaFrag : undefined);
285
+
286
+ if (
287
+ compilerOptions?.jsx === 'react-jsx' ||
288
+ compilerOptions?.jsx === 'react-jsxdev' ||
289
+ compilerOptions?.jsxImportSource
290
+ ) {
291
+ jsxImportSource = compilerOptions?.jsxImportSource;
292
+ automaticJSXRuntime = true;
293
+ } else if (reactLib) {
294
+ let effectiveReactLib =
295
+ packageJson?.alias && packageJson.alias['react'] === 'preact/compat'
296
+ ? 'preact'
297
+ : reactLib;
298
+ // @ts-expect-error TS7053
299
+ let automaticVersion = JSX_PRAGMA[effectiveReactLib]?.automatic;
300
+ let reactLibVersion =
301
+ packageJson?.dependencies?.[effectiveReactLib] ||
302
+ packageJson?.devDependencies?.[effectiveReactLib] ||
303
+ packageJson?.peerDependencies?.[effectiveReactLib];
304
+ // @ts-expect-error TS2322
305
+ reactLibVersion = reactLibVersion
306
+ ? semver.validRange(reactLibVersion)
307
+ : null;
308
+ let minReactLibVersion =
309
+ reactLibVersion !== null && reactLibVersion !== '*'
310
+ ? // @ts-expect-error TS2345
311
+ semver.minVersion(reactLibVersion)?.toString()
253
312
  : null;
254
- let minReactLibVersion =
255
- reactLibVersion !== null && reactLibVersion !== '*'
256
- ? semver.minVersion(reactLibVersion)?.toString()
257
- : null;
258
-
259
- automaticJSXRuntime =
260
- automaticVersion &&
261
- !compilerOptions?.jsxFactory &&
262
- minReactLibVersion != null &&
263
- semver.satisfies(minReactLibVersion, automaticVersion, {
264
- includePrerelease: true,
265
- });
266
313
 
267
- if (automaticJSXRuntime) {
268
- jsxImportSource = reactLib;
269
- }
314
+ automaticJSXRuntime =
315
+ automaticVersion &&
316
+ !compilerOptions?.jsxFactory &&
317
+ minReactLibVersion != null &&
318
+ semver.satisfies(minReactLibVersion, automaticVersion, {
319
+ includePrerelease: true,
320
+ });
321
+
322
+ if (automaticJSXRuntime) {
323
+ jsxImportSource = reactLib;
270
324
  }
325
+ }
326
+
327
+ isJSX = Boolean(compilerOptions?.jsx || jsxPragma);
328
+ }
329
+
330
+ return {
331
+ isJSX,
332
+ jsxPragma,
333
+ jsxPragmaFrag,
334
+ jsxImportSource,
335
+ automaticJSXRuntime,
336
+ reactRefresh,
337
+ };
338
+ }
339
+
340
+ export async function loadTokensConfig(config: Config, options: PluginOptions) {
341
+ const conf = await config.getConfigFrom(options.projectRoot + '/index', [], {
342
+ packageKey: '@atlaspack/transformer-tokens',
343
+ });
344
+
345
+ if (conf && conf.contents) {
346
+ validateSchema.diagnostic(
347
+ TOKENS_CONFIG_SCHEMA,
348
+ {
349
+ data: conf.contents,
350
+ source: () => options.inputFS.readFileSync(conf.filePath, 'utf8'),
351
+ filePath: conf.filePath,
352
+ prependKey: `/${encodeJSONKeyComponent('@atlaspack/transformer-tokens')}`,
353
+ },
354
+ '@atlaspack/transformer-tokens',
355
+ 'Invalid config for @atlaspack/transformer-tokens',
356
+ );
357
+
358
+ // @ts-expect-error TS2339
359
+ const tokensConfig: AtlaskitTokensConfigPartial = conf.contents;
360
+
361
+ let resolvedConfig: AtlaskitTokensConfig = {
362
+ shouldUseAutoFallback: tokensConfig.shouldUseAutoFallback ?? true,
363
+ shouldForceAutoFallback: tokensConfig.shouldForceAutoFallback ?? true,
364
+ forceAutoFallbackExemptions:
365
+ tokensConfig.forceAutoFallbackExemptions ?? [],
366
+ defaultTheme: tokensConfig.defaultTheme ?? 'light',
367
+ tokenDataPath: path.join(options.projectRoot, tokensConfig.tokenDataPath),
368
+ };
369
+ return resolvedConfig;
370
+ }
371
+ }
372
+
373
+ export async function loadCompiledCssInJsConfig(
374
+ config: Config,
375
+ options: PluginOptions,
376
+ ): Promise<CompiledCssInJsConfigPlugin> {
377
+ const DEFAULT_IMPORT_SOURCES = ['@compiled/react', '@atlaskit/css'];
378
+
379
+ const conf = await config.getConfigFrom<CompiledCssInJsConfigPlugin>(
380
+ join(options.projectRoot, 'index'),
381
+ ['.compiledcssrc', '.compiledcssrc.json'],
382
+ {
383
+ packageKey: '@atlaspack/transformer-compiled-css-in-js',
384
+ },
385
+ );
386
+
387
+ const resolvedBrowserslistEnv =
388
+ conf?.contents.browserslistEnv ??
389
+ process.env.BROWSERSLIST_ENV ??
390
+ process.env.NODE_ENV ??
391
+ 'production';
392
+
393
+ const contents: CompiledCssInJsConfigPlugin = {
394
+ ...conf?.contents,
395
+ importSources: [
396
+ ...DEFAULT_IMPORT_SOURCES,
397
+ ...(conf?.contents.importSources ?? []),
398
+ ],
399
+ extract: conf?.contents.extract && options.mode !== 'development',
400
+ // Use explicit env or process env (BROWSERSLIST_ENV/NODE_ENV). Default to "production"
401
+ // to match browserslist/caniuse defaults and the legacy Babel plugin behavior.
402
+ browserslistEnv: resolvedBrowserslistEnv,
403
+ };
404
+
405
+ return contents;
406
+ }
407
+
408
+ export default new Transformer({
409
+ async loadConfig({config, options}) {
410
+ let conf = await config.getConfigFrom<JsTransformerConfig>(
411
+ options.projectRoot + '/index',
412
+ [],
413
+ {
414
+ packageKey: '@atlaspack/transformer-js',
415
+ },
416
+ );
417
+
418
+ if (conf && conf.contents) {
419
+ validateSchema.diagnostic(
420
+ CONFIG_SCHEMA,
421
+ {
422
+ data: conf.contents,
423
+ source: () => options.inputFS.readFileSync(conf.filePath, 'utf8'),
424
+ filePath: conf.filePath,
425
+ prependKey: `/${encodeJSONKeyComponent('@atlaspack/transformer-js')}`,
426
+ },
427
+ // FIXME
428
+ '@atlaspack/transformer-js',
429
+ 'Invalid config for @atlaspack/transformer-js',
430
+ );
431
+ }
432
+
433
+ let packageJson = await config.getPackage();
434
+ let decorators, useDefineForClassFields;
435
+
436
+ let {
437
+ isJSX,
438
+ jsxPragma,
439
+ jsxPragmaFrag,
440
+ jsxImportSource,
441
+ automaticJSXRuntime,
442
+ reactRefresh,
443
+ } = options.featureFlags.newJsxConfig
444
+ ? (determineJsxConfiguration(
445
+ config.searchPath,
446
+ config.isSource,
447
+ conf?.contents?.jsx,
448
+ options.projectRoot,
449
+ ) as JsxConfig)
450
+ : await legacyDetemineJsxConfig(config, options);
451
+
452
+ if (config.isSource) {
453
+ const compilerOptions: TSConfig['compilerOptions'] = (
454
+ await config.getConfigFrom<TSConfig>(
455
+ options.projectRoot + '/index',
456
+ ['tsconfig.json', 'jsconfig.json'],
457
+ {
458
+ readTracking: true,
459
+ },
460
+ )
461
+ )?.contents?.compilerOptions;
271
462
 
272
- isJSX = Boolean(compilerOptions?.jsx || pragma);
273
463
  decorators = compilerOptions?.experimentalDecorators;
274
464
  useDefineForClassFields = compilerOptions?.useDefineForClassFields;
275
465
  if (
@@ -289,36 +479,99 @@ export default (new Transformer({
289
479
  // Check if we should ignore fs calls
290
480
  // See https://github.com/defunctzombie/node-browser-resolve#skip
291
481
  let ignoreFS =
292
- pkg &&
293
- pkg.browser &&
294
- typeof pkg.browser === 'object' &&
295
- pkg.browser.fs === false;
296
-
297
- let conf = await config.getConfigFrom(options.projectRoot + '/index', [], {
298
- packageKey: '@atlaspack/transformer-js',
299
- });
482
+ packageJson &&
483
+ packageJson.browser &&
484
+ typeof packageJson.browser === 'object' &&
485
+ packageJson.browser.fs === false;
300
486
 
301
487
  let inlineEnvironment = config.isSource;
302
488
  let inlineFS = !ignoreFS;
303
489
  let inlineConstants = false;
304
490
  let magicComments = false;
491
+ let addReactDisplayName = false;
492
+
493
+ let enableSsrTypeofReplacement =
494
+ options.env.NATIVE_SSR_TYPEOF_REPLACEMENT === 'true';
495
+ let globalAliasingConfig =
496
+ options.env.NATIVE_GLOBAL_ALIASING &&
497
+ JSON.parse(options.env.NATIVE_GLOBAL_ALIASING);
498
+ let enableLazyLoading = options.env.NATIVE_LAZY_LOADING === 'true';
499
+ let enableReactHooksRemoval =
500
+ options.env.NATIVE_REACT_HOOKS_REMOVAL === 'true';
501
+ let enableReactAsyncImportLift =
502
+ options.env.NATIVE_REACT_ASYNC_IMPORT_LIFT === 'true';
503
+ let reactAsyncLiftByDefault =
504
+ options.env.REACT_ASYNC_IMPORT_LIFTING_BY_DEFAULT === 'true';
505
+ let reactAsyncLiftReportLevel =
506
+ options.env.REACT_ASYNC_LIFT_REPORT_LEVEL || 'none';
507
+ let enableStaticPrevaluation = options.env.NATIVE_PREVALUATION === 'true';
508
+ let enableDeadReturnsRemoval =
509
+ options.env.NATIVE_DEAD_RETURNS_REMOVAL === 'true';
510
+ let enableUnusedBindingsRemoval =
511
+ options.env.NATIVE_UNUSED_BINDINGS_REMOVAL === 'true';
512
+ let syncDynamicImportConfig:
513
+ | {
514
+ entrypoint_filepath_suffix: string;
515
+ actual_require_paths: string[];
516
+ activate_reject_on_unresolved_imports?: boolean;
517
+ }
518
+ | undefined;
519
+
520
+ if (config.env.isTesseract() && options.env.SYNC_DYNAMIC_IMPORT_CONFIG) {
521
+ try {
522
+ let config = configCache.get(
523
+ 'SYNC_DYNAMIC_IMPORT_CONFIG',
524
+ ) as typeof syncDynamicImportConfig;
525
+
526
+ if (!config) {
527
+ config = JSON.parse(options.env.SYNC_DYNAMIC_IMPORT_CONFIG);
528
+
529
+ invariant(typeof config?.entrypoint_filepath_suffix === 'string');
530
+ invariant(Array.isArray(config.actual_require_paths));
531
+ invariant(
532
+ typeof (config.activate_reject_on_unresolved_imports ?? false) ===
533
+ 'boolean',
534
+ );
305
535
 
306
- if (conf && conf.contents) {
307
- validateSchema.diagnostic(
308
- CONFIG_SCHEMA,
309
- {
310
- data: conf.contents,
311
- // FIXME
312
- source: await options.inputFS.readFile(conf.filePath, 'utf8'),
313
- filePath: conf.filePath,
314
- prependKey: `/${encodeJSONKeyComponent('@atlaspack/transformer-js')}`,
315
- },
316
- // FIXME
317
- '@atlaspack/transformer-js',
318
- 'Invalid config for @atlaspack/transformer-js',
319
- );
536
+ configCache.set('SYNC_DYNAMIC_IMPORT_CONFIG', config);
537
+ }
538
+
539
+ syncDynamicImportConfig = config;
540
+ } catch {
541
+ // eslint-disable-next-line no-console
542
+ console.warn(
543
+ 'Failed to parse SYNC_DYNAMIC_IMPORT_CONFIG to JSON or config shape did not match. Config will not be applied.',
544
+ );
545
+
546
+ const fallback = {
547
+ entrypoint_filepath_suffix: '__NO_MATCH__',
548
+ actual_require_paths: [],
549
+ activate_reject_on_unresolved_imports: false,
550
+ };
551
+
552
+ // Set cache to fallback so we don't keep trying to parse.
553
+ configCache.set('SYNC_DYNAMIC_IMPORT_CONFIG', fallback);
554
+ syncDynamicImportConfig = fallback;
555
+ }
556
+ }
557
+
558
+ config.invalidateOnEnvChange('SYNC_DYNAMIC_IMPORT_CONFIG');
559
+
560
+ const tokensConfig = getFeatureFlag('coreTokensAndCompiledCssInJsTransform')
561
+ ? await loadTokensConfig(config, options)
562
+ : undefined;
320
563
 
564
+ const compiledCssInJsConfig = getFeatureFlag(
565
+ 'coreTokensAndCompiledCssInJsTransform',
566
+ )
567
+ ? await loadCompiledCssInJsConfig(config, options)
568
+ : undefined;
569
+
570
+ if (conf && conf.contents) {
571
+ addReactDisplayName =
572
+ conf.contents?.addReactDisplayName ?? addReactDisplayName;
321
573
  magicComments = conf.contents?.magicComments ?? magicComments;
574
+ // @ts-expect-error TS2322
322
575
  inlineEnvironment = conf.contents?.inlineEnvironment ?? inlineEnvironment;
323
576
  inlineFS = conf.contents?.inlineFS ?? inlineFS;
324
577
  inlineConstants =
@@ -329,15 +582,29 @@ export default (new Transformer({
329
582
  isJSX,
330
583
  automaticJSXRuntime,
331
584
  jsxImportSource,
332
- pragma,
333
- pragmaFrag,
585
+ pragma: jsxPragma,
586
+ pragmaFrag: jsxPragmaFrag,
334
587
  inlineEnvironment,
335
588
  inlineFS,
336
589
  inlineConstants,
590
+ addReactDisplayName,
337
591
  reactRefresh,
338
592
  decorators,
339
593
  useDefineForClassFields,
340
594
  magicComments,
595
+ globalAliasingConfig,
596
+ enableSsrTypeofReplacement,
597
+ enableLazyLoading,
598
+ enableDeadReturnsRemoval,
599
+ enableUnusedBindingsRemoval,
600
+ enableStaticPrevaluation,
601
+ enableReactHooksRemoval,
602
+ syncDynamicImportConfig,
603
+ enableReactAsyncImportLift,
604
+ reactAsyncLiftByDefault,
605
+ reactAsyncLiftReportLevel,
606
+ tokensConfig,
607
+ compiledCssInJsConfig,
341
608
  };
342
609
  },
343
610
  async transform({asset, config, options, logger}) {
@@ -368,6 +635,7 @@ export default (new Transformer({
368
635
  for (let browser of browsers) {
369
636
  let [name, version] = browser.split(' ');
370
637
  if (BROWSER_MAPPING.hasOwnProperty(name)) {
638
+ // @ts-expect-error TS7053
371
639
  name = BROWSER_MAPPING[name];
372
640
  if (!name) {
373
641
  continue;
@@ -377,12 +645,15 @@ export default (new Transformer({
377
645
  let [major, minor = '0', patch = '0'] = version
378
646
  .split('-')[0]
379
647
  .split('.');
648
+ // @ts-expect-error TS2345
380
649
  if (isNaN(major) || isNaN(minor) || isNaN(patch)) {
381
650
  continue;
382
651
  }
383
652
  let semverVersion = `${major}.${minor}.${patch}`;
384
653
 
654
+ // @ts-expect-error TS2345
385
655
  if (targets[name] == null || semver.gt(targets[name], semverVersion)) {
656
+ // @ts-expect-error TS7053
386
657
  targets[name] = semverVersion;
387
658
  }
388
659
  }
@@ -422,24 +693,49 @@ export default (new Transformer({
422
693
  if (asset.type === 'ts') {
423
694
  isJSX = false;
424
695
  } else if (!isJSX) {
696
+ // @ts-expect-error TS7053
425
697
  isJSX = Boolean(JSX_EXTENSIONS[asset.type]);
426
698
  }
427
699
  }
428
700
 
429
- let macroAssets = [];
701
+ let macroAssets: Array<{
702
+ content: string;
703
+ // @ts-expect-error TS2552
704
+ map: undefined | NodeSourceMap;
705
+ type: string;
706
+ uniqueKey: string;
707
+ }> = [];
430
708
  let {
709
+ // @ts-expect-error TS2339
431
710
  dependencies,
711
+ // @ts-expect-error TS2339
432
712
  code: compiledCode,
713
+ // @ts-expect-error TS2339
433
714
  map,
715
+ // @ts-expect-error TS2339
434
716
  shebang,
717
+ // @ts-expect-error TS2339
435
718
  hoist_result,
719
+ // @ts-expect-error TS2339
436
720
  symbol_result,
721
+ // @ts-expect-error TS2339
722
+ is_empty_or_empty_export,
723
+ // @ts-expect-error TS2339
437
724
  needs_esm_helpers,
725
+ // @ts-expect-error TS2339
438
726
  diagnostics,
727
+ // @ts-expect-error TS2339
439
728
  used_env,
729
+ // @ts-expect-error TS2339
440
730
  has_node_replacements,
731
+ // @ts-expect-error TS2339
441
732
  is_constant_module,
733
+ // @ts-expect-error TS2339
442
734
  conditions,
735
+ // @ts-expect-error TS2339
736
+ magic_comments,
737
+ // @ts-expect-error TS2339
738
+ style_rules,
443
739
  } = await (transformAsync || transform)({
444
740
  filename: asset.filePath,
445
741
  code,
@@ -451,7 +747,7 @@ export default (new Transformer({
451
747
  !asset.env.isNode() && asset.env.sourceType !== 'script',
452
748
  node_replacer: asset.env.isNode(),
453
749
  is_browser: asset.env.isBrowser(),
454
- is_worker: asset.env.isWorker(),
750
+ is_worker: asset.env.isWorker() || asset.env.isTesseract(),
455
751
  env,
456
752
  is_type_script: asset.type === 'ts' || asset.type === 'tsx',
457
753
  is_jsx: isJSX,
@@ -460,12 +756,16 @@ export default (new Transformer({
460
756
  automatic_jsx_runtime: Boolean(config?.automaticJSXRuntime),
461
757
  jsx_import_source: config?.jsxImportSource,
462
758
  is_development: options.mode === 'development',
463
- react_refresh:
759
+ react_refresh: Boolean(
464
760
  asset.env.isBrowser() &&
465
- !asset.env.isLibrary &&
466
- !asset.env.isWorker() &&
467
- !asset.env.isWorklet() &&
468
- Boolean(config?.reactRefresh),
761
+ !asset.env.isLibrary &&
762
+ !asset.env.isWorker() &&
763
+ !asset.env.isTesseract() &&
764
+ !asset.env.isWorklet() &&
765
+ config?.reactRefresh &&
766
+ options.hmrOptions &&
767
+ options.mode === 'development',
768
+ ),
469
769
  decorators: Boolean(config?.decorators),
470
770
  use_define_for_class_fields: Boolean(config?.useDefineForClassFields),
471
771
  targets,
@@ -481,9 +781,37 @@ export default (new Transformer({
481
781
  standalone: asset.query.has('standalone'),
482
782
  inline_constants: config.inlineConstants,
483
783
  conditional_bundling: options.featureFlags.conditionalBundlingApi,
484
- magic_comments: Boolean(config?.magicComments),
784
+ hmr_improvements: options.featureFlags.hmrImprovements,
785
+ add_display_name: Boolean(config.addReactDisplayName),
786
+ exports_rebinding_optimisation:
787
+ options.featureFlags.exportsRebindingOptimisation,
788
+ magic_comments:
789
+ Boolean(config?.magicComments) ||
790
+ getFeatureFlag('supportWebpackChunkName'),
791
+ is_source: asset.isSource,
792
+ nested_promise_import_fix: options.featureFlags.nestedPromiseImportFix,
793
+ global_aliasing_config: config.globalAliasingConfig,
794
+ enable_ssr_typeof_replacement: Boolean(config.enableSsrTypeofReplacement),
795
+ enable_lazy_loading: Boolean(config.enableLazyLoading),
796
+ enable_dead_returns_removal: Boolean(config.enableDeadReturnsRemoval),
797
+ enable_unused_bindings_removal: Boolean(
798
+ config.enableUnusedBindingsRemoval,
799
+ ),
800
+ enable_static_prevaluation: Boolean(config.enableStaticPrevaluation),
801
+ enable_react_hooks_removal: Boolean(config.enableReactHooksRemoval),
802
+ enable_react_async_import_lift: Boolean(
803
+ config.enableReactAsyncImportLift,
804
+ ),
805
+ react_async_lift_by_default: Boolean(config.reactAsyncLiftByDefault),
806
+ react_async_lift_report_level: String(config.reactAsyncLiftReportLevel),
807
+ sync_dynamic_import_config: config.syncDynamicImportConfig,
808
+ enable_tokens_and_compiled_css_in_js_transform: getFeatureFlag(
809
+ 'coreTokensAndCompiledCssInJsTransform',
810
+ ),
811
+ tokens_config: config.tokensConfig,
812
+ compiled_css_in_js_config: config.compiledCssInJsConfig,
485
813
  callMacro: asset.isSource
486
- ? async (err, src, exportName, args, loc) => {
814
+ ? async (err: any, src: any, exportName: any, args: any, loc: any) => {
487
815
  let mod;
488
816
  try {
489
817
  mod = await options.packageManager.require(src, asset.filePath);
@@ -492,7 +820,6 @@ export default (new Transformer({
492
820
  if (
493
821
  exportName === 'default' &&
494
822
  !mod.__esModule &&
495
- // $FlowFixMe
496
823
  Object.prototype.toString.call(config) !== '[object Module]'
497
824
  ) {
498
825
  mod = {default: mod};
@@ -501,7 +828,7 @@ export default (new Transformer({
501
828
  if (!Object.hasOwnProperty.call(mod, exportName)) {
502
829
  throw new Error(`"${src}" does not export "${exportName}".`);
503
830
  }
504
- } catch (err) {
831
+ } catch (err: any) {
505
832
  throw {
506
833
  kind: 1,
507
834
  message: err.message,
@@ -518,7 +845,8 @@ export default (new Transformer({
518
845
  if (asset.env.sourceMap) {
519
846
  // Generate a source map that maps each line of the asset to the original macro call.
520
847
  map = new SourceMap(options.projectRoot);
521
- let mappings = [];
848
+ // @ts-expect-error TS2304
849
+ let mappings: Array<IndexedMapping<string>> = [];
522
850
  let line = 1;
523
851
  for (let i = 0; i <= a.content.length; i++) {
524
852
  if (i === a.content.length || a.content[i] === '\n') {
@@ -541,7 +869,9 @@ export default (new Transformer({
541
869
  if (originalMap) {
542
870
  map.extends(originalMap);
543
871
  } else {
544
- map.setSourceContent(asset.filePath, code.toString());
872
+ if (!getFeatureFlag('omitSourcesContentInMemory')) {
873
+ map.setSourceContent(asset.filePath, code.toString());
874
+ }
545
875
  }
546
876
  }
547
877
 
@@ -557,13 +887,13 @@ export default (new Transformer({
557
887
  specifierType: 'esm',
558
888
  });
559
889
  },
560
- invalidateOnFileChange(filePath) {
890
+ invalidateOnFileChange(filePath: FilePath) {
561
891
  asset.invalidateOnFileChange(filePath);
562
892
  },
563
- invalidateOnFileCreate(invalidation) {
893
+ invalidateOnFileCreate(invalidation: FileCreateInvalidation) {
564
894
  asset.invalidateOnFileCreate(invalidation);
565
895
  },
566
- invalidateOnEnvChange(env) {
896
+ invalidateOnEnvChange(env: string) {
567
897
  asset.invalidateOnEnvChange(env);
568
898
  },
569
899
  invalidateOnStartup() {
@@ -580,7 +910,7 @@ export default (new Transformer({
580
910
  `"${exportName}" in "${src}" is not a function.`,
581
911
  );
582
912
  }
583
- } catch (err) {
913
+ } catch (err: any) {
584
914
  // Remove atlaspack core from stack and build string so Rust can process errors more easily.
585
915
  let stack = (err.stack || '').split('\n').slice(1);
586
916
  let message = err.message;
@@ -600,18 +930,18 @@ export default (new Transformer({
600
930
  });
601
931
 
602
932
  if (getFeatureFlag('conditionalBundlingApi')) {
603
- asset.meta.conditions = conditions.map((c): ConditionMeta => ({
604
- key: c.key,
605
- ifTruePlaceholder: c.if_true_placeholder,
606
- ifFalsePlaceholder: c.if_false_placeholder,
607
- }));
933
+ asset.meta.conditions = conditions;
934
+ }
935
+
936
+ if (style_rules) {
937
+ asset.meta.styleRules = style_rules;
608
938
  }
609
939
 
610
940
  if (is_constant_module) {
611
941
  asset.meta.isConstantModule = true;
612
942
  }
613
943
 
614
- let convertLoc = (loc): SourceLocation => {
944
+ let convertLoc = (loc: any): SourceLocation => {
615
945
  let location = {
616
946
  filePath: asset.filePath,
617
947
  start: {
@@ -626,7 +956,11 @@ export default (new Transformer({
626
956
 
627
957
  // If there is an original source map, use it to remap to the original source location.
628
958
  if (originalMap) {
629
- location = remapSourceLocation(location, originalMap);
959
+ location = remapSourceLocation(
960
+ location,
961
+ originalMap,
962
+ options.projectRoot,
963
+ );
630
964
  }
631
965
 
632
966
  return location;
@@ -634,19 +968,22 @@ export default (new Transformer({
634
968
 
635
969
  if (diagnostics) {
636
970
  let errors = diagnostics.filter(
971
+ // @ts-expect-error TS7006
637
972
  (d) =>
638
973
  d.severity === 'Error' ||
639
974
  (d.severity === 'SourceError' && asset.isSource),
640
975
  );
641
976
  let warnings = diagnostics.filter(
977
+ // @ts-expect-error TS7006
642
978
  (d) =>
643
979
  d.severity === 'Warning' ||
644
980
  (d.severity === 'SourceError' && !asset.isSource),
645
981
  );
646
- let convertDiagnostic = (diagnostic) => {
982
+ let convertDiagnostic = (diagnostic: any) => {
647
983
  let message = diagnostic.message;
648
984
  if (message === 'SCRIPT_ERROR') {
649
- let err = SCRIPT_ERRORS[(asset.env.context: string)];
985
+ // @ts-expect-error TS7053
986
+ let err = SCRIPT_ERRORS[asset.env.context as string];
650
987
  message = err?.message || SCRIPT_ERRORS.browser.message;
651
988
  }
652
989
 
@@ -655,17 +992,21 @@ export default (new Transformer({
655
992
  codeFrames: [
656
993
  {
657
994
  filePath: asset.filePath,
658
- codeHighlights: diagnostic.code_highlights?.map((highlight) =>
659
- convertSourceLocationToHighlight(
660
- convertLoc(highlight.loc),
661
- highlight.message ?? undefined,
662
- ),
995
+ codeHighlights: diagnostic.code_highlights?.map(
996
+ (highlight: any) =>
997
+ convertSourceLocationToHighlight(
998
+ convertLoc(highlight.loc),
999
+ highlight.message ?? undefined,
1000
+ ),
663
1001
  ),
664
1002
  },
665
1003
  ],
666
1004
  hints: diagnostic.hints,
667
1005
  };
668
1006
 
1007
+ if (diagnostic.name) {
1008
+ res.name = diagnostic.name;
1009
+ }
669
1010
  if (diagnostic.documentation_url) {
670
1011
  res.documentationURL = diagnostic.documentation_url;
671
1012
  }
@@ -683,7 +1024,8 @@ export default (new Transformer({
683
1024
  });
684
1025
  }
685
1026
 
686
- let err = SCRIPT_ERRORS[(asset.env.context: string)];
1027
+ // @ts-expect-error TS7053
1028
+ let err = SCRIPT_ERRORS[asset.env.context as string];
687
1029
  if (err) {
688
1030
  if (!res.hints) {
689
1031
  res.hints = [err.hint];
@@ -740,6 +1082,7 @@ export default (new Transformer({
740
1082
  env: {
741
1083
  context: 'web-worker',
742
1084
  sourceType: dep.source_type === 'Module' ? 'module' : 'script',
1085
+ // @ts-expect-error TS2322
743
1086
  outputFormat,
744
1087
  loc,
745
1088
  },
@@ -787,6 +1130,13 @@ export default (new Transformer({
787
1130
  });
788
1131
  } else if (dep.kind === 'File') {
789
1132
  asset.invalidateOnFileChange(dep.specifier);
1133
+ } else if (dep.kind === 'Id') {
1134
+ // Record parcelRequire calls so that the dev packager can add them as dependencies.
1135
+ // This allows the HMR runtime to collect parents across async boundaries (through runtimes).
1136
+ // TODO: ideally this would result as an actual dep in the graph rather than asset.meta.
1137
+ asset.meta.hmrDeps ??= [];
1138
+ invariant(Array.isArray(asset.meta.hmrDeps));
1139
+ asset.meta.hmrDeps.push(dep.specifier);
790
1140
  } else {
791
1141
  let meta: JSONObject = {kind: dep.kind};
792
1142
  if (dep.attributes) {
@@ -850,6 +1200,13 @@ export default (new Transformer({
850
1200
  outputFormat,
851
1201
  loc: convertLoc(dep.loc),
852
1202
  };
1203
+
1204
+ if (getFeatureFlag('supportWebpackChunkName')) {
1205
+ let chunkName = magic_comments[dep.specifier];
1206
+ if (chunkName) {
1207
+ meta.chunkName = chunkName;
1208
+ }
1209
+ }
853
1210
  }
854
1211
 
855
1212
  // Always bundle helpers, even with includeNodeModules: false, except if this is a library.
@@ -874,6 +1231,7 @@ export default (new Transformer({
874
1231
  idx = dep.specifier.indexOf('/', idx + 1);
875
1232
  }
876
1233
  let module = idx >= 0 ? dep.specifier.slice(0, idx) : dep.specifier;
1234
+ // @ts-expect-error TS7053
877
1235
  range = pkg.dependencies[module];
878
1236
  }
879
1237
 
@@ -885,12 +1243,13 @@ export default (new Transformer({
885
1243
  dep.kind === 'DynamicImport'
886
1244
  ? 'lazy'
887
1245
  : dep.kind === 'ConditionalImport'
888
- ? 'conditional'
889
- : 'sync',
1246
+ ? 'conditional'
1247
+ : 'sync',
890
1248
  isOptional: dep.is_optional,
891
1249
  meta,
892
1250
  resolveFrom: isHelper ? __filename : undefined,
893
1251
  range,
1252
+ // @ts-expect-error TS2322
894
1253
  env,
895
1254
  });
896
1255
  }
@@ -904,8 +1263,12 @@ export default (new Transformer({
904
1263
  local,
905
1264
  loc,
906
1265
  is_esm,
1266
+ is_static_binding_safe,
907
1267
  } of hoist_result.exported_symbols) {
908
- asset.symbols.set(exported, local, convertLoc(loc), {isEsm: is_esm});
1268
+ asset.symbols.set(exported, local, convertLoc(loc), {
1269
+ isEsm: is_esm,
1270
+ isStaticBindingSafe: is_static_binding_safe,
1271
+ });
909
1272
  }
910
1273
 
911
1274
  // deps is a map of dependencies that are keyed by placeholder or specifier
@@ -937,7 +1300,24 @@ export default (new Transformer({
937
1300
  let dep = deps.get(source);
938
1301
  if (!dep) continue;
939
1302
  if (local === '*' && imported === '*') {
940
- dep.symbols.set('*', '*', convertLoc(loc), true);
1303
+ // When a module has both `import * as ns from 'x'` and
1304
+ // `export * from 'x'`, they share a single dep (merged by the
1305
+ // core). The namespace import binding ('*' → local, isWeak:false)
1306
+ // set by imported_symbols is strictly more inclusive than the
1307
+ // wildcard re-export ('*' → '*', isWeak:true) for symbol
1308
+ // propagation, so don't overwrite it. Instead, flag the dep so
1309
+ // that symbol propagation still treats it as a wildcard
1310
+ // re-exporter.
1311
+ let existingStar = dep.symbols.get('*');
1312
+ if (
1313
+ getFeatureFlag('fixExportStarNamespaceOverwrite') &&
1314
+ existingStar &&
1315
+ existingStar.local !== '*'
1316
+ ) {
1317
+ dep.meta.hasExportStar = true;
1318
+ } else {
1319
+ dep.symbols.set('*', '*', convertLoc(loc), true);
1320
+ }
941
1321
  } else {
942
1322
  let reExportName =
943
1323
  dep.symbols.get(imported)?.local ??
@@ -1002,6 +1382,9 @@ export default (new Transformer({
1002
1382
  Object.keys(hoist_result.exported_symbols).length === 0) ||
1003
1383
  (hoist_result.should_wrap && !asset.symbols.hasExportSymbol('*'))
1004
1384
  ) {
1385
+ if (is_empty_or_empty_export) {
1386
+ asset.meta.emptyFileStarReexport = true;
1387
+ }
1005
1388
  asset.symbols.set('*', `$${asset.id}$exports`);
1006
1389
  }
1007
1390
 
@@ -1046,7 +1429,20 @@ export default (new Transformer({
1046
1429
  let dep = deps.get(source);
1047
1430
  if (!dep) continue;
1048
1431
  dep.symbols.ensure();
1049
- dep.symbols.set('*', '*', convertLoc(loc), true);
1432
+ // When a module has both `import * as ns from 'x'` and
1433
+ // `export * from 'x'`, they share a single dep. Don't overwrite
1434
+ // the namespace import binding — flag the dep instead so symbol
1435
+ // propagation still treats it as a wildcard re-exporter.
1436
+ let existingStar = dep.symbols.get('*');
1437
+ if (
1438
+ getFeatureFlag('fixExportStarNamespaceOverwrite') &&
1439
+ existingStar &&
1440
+ existingStar.local !== '*'
1441
+ ) {
1442
+ dep.meta.hasExportStar = true;
1443
+ } else {
1444
+ dep.symbols.set('*', '*', convertLoc(loc), true);
1445
+ }
1050
1446
  }
1051
1447
 
1052
1448
  // Add * symbol if there are CJS exports, no imports/exports at all, or the asset is wrapped.
@@ -1104,4 +1500,4 @@ export default (new Transformer({
1104
1500
 
1105
1501
  return [asset, ...macroAssets];
1106
1502
  },
1107
- }): Transformer);
1503
+ }) as Transformer<unknown>;