@atlaspack/transformer-js 10.1.1-dev-d5e4c77df.0 → 10.1.1-dev-a76a48b52.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.
@@ -152,10 +152,16 @@ const CONFIG_SCHEMA = {
152
152
  },
153
153
  unstable_inlineConstants: {
154
154
  type: 'boolean'
155
+ },
156
+ jsx: {
157
+ type: 'object'
155
158
  }
156
159
  },
157
160
  additionalProperties: false
158
161
  };
162
+
163
+ // Mirrors the CONFIG_SCHEMA
164
+
159
165
  const configCache = (0, _buildCache().createBuildCache)();
160
166
  const SCRIPT_ERRORS = {
161
167
  browser: {
@@ -173,60 +179,100 @@ const SCRIPT_ERRORS = {
173
179
  };
174
180
 
175
181
  // NOTE: Make sure this is in sync with the TypeScript definition in the @atlaspack/macros package.
182
+
183
+ async function legacyDetemineJsxConfig(config, options) {
184
+ let packageJson = await config.getPackage();
185
+ let isJSX, jsxPragma, jsxPragmaFrag, jsxImportSource, automaticJSXRuntime, reactRefresh;
186
+ if (config.isSource) {
187
+ var _packageJson$dependen2, _packageJson$devDepen2, _packageJson$peerDepe2, _await$config$getConf;
188
+ let reactLib;
189
+ if (packageJson !== null && packageJson !== void 0 && packageJson.alias && packageJson.alias['react']) {
190
+ // e.g.: `{ alias: { "react": "preact/compat" } }`
191
+ reactLib = 'react';
192
+ } else {
193
+ // Find a dependency that we can map to a JSX pragma
194
+ reactLib = Object.keys(JSX_PRAGMA).find(libName => {
195
+ var _packageJson$dependen, _packageJson$devDepen, _packageJson$peerDepe;
196
+ return (packageJson === null || packageJson === void 0 || (_packageJson$dependen = packageJson.dependencies) === null || _packageJson$dependen === void 0 ? void 0 : _packageJson$dependen[libName]) || (packageJson === null || packageJson === void 0 || (_packageJson$devDepen = packageJson.devDependencies) === null || _packageJson$devDepen === void 0 ? void 0 : _packageJson$devDepen[libName]) || (packageJson === null || packageJson === void 0 || (_packageJson$peerDepe = packageJson.peerDependencies) === null || _packageJson$peerDepe === void 0 ? void 0 : _packageJson$peerDepe[libName]);
197
+ });
198
+ }
199
+ reactRefresh = Boolean((packageJson === null || packageJson === void 0 || (_packageJson$dependen2 = packageJson.dependencies) === null || _packageJson$dependen2 === void 0 ? void 0 : _packageJson$dependen2.react) || (packageJson === null || packageJson === void 0 || (_packageJson$devDepen2 = packageJson.devDependencies) === null || _packageJson$devDepen2 === void 0 ? void 0 : _packageJson$devDepen2.react) || (packageJson === null || packageJson === void 0 || (_packageJson$peerDepe2 = packageJson.peerDependencies) === null || _packageJson$peerDepe2 === void 0 ? void 0 : _packageJson$peerDepe2.react));
200
+ const compilerOptions = (_await$config$getConf = await config.getConfigFrom(options.projectRoot + '/index', ['tsconfig.json', 'jsconfig.json'], {
201
+ readTracking: true
202
+ })) === null || _await$config$getConf === void 0 || (_await$config$getConf = _await$config$getConf.contents) === null || _await$config$getConf === void 0 ? void 0 : _await$config$getConf.compilerOptions;
203
+
204
+ // Use explicitly defined JSX options in tsconfig.json over inferred values from dependencies.
205
+ jsxPragma = (compilerOptions === null || compilerOptions === void 0 ? void 0 : compilerOptions.jsxFactory) || (
206
+ // @ts-expect-error TS7053
207
+ reactLib ? JSX_PRAGMA[reactLib].pragma : undefined);
208
+ jsxPragmaFrag = (compilerOptions === null || compilerOptions === void 0 ? void 0 : compilerOptions.jsxFragmentFactory) || (
209
+ // @ts-expect-error TS7053
210
+ reactLib ? JSX_PRAGMA[reactLib].pragmaFrag : undefined);
211
+ if ((compilerOptions === null || compilerOptions === void 0 ? void 0 : compilerOptions.jsx) === 'react-jsx' || (compilerOptions === null || compilerOptions === void 0 ? void 0 : compilerOptions.jsx) === 'react-jsxdev' || compilerOptions !== null && compilerOptions !== void 0 && compilerOptions.jsxImportSource) {
212
+ jsxImportSource = compilerOptions === null || compilerOptions === void 0 ? void 0 : compilerOptions.jsxImportSource;
213
+ automaticJSXRuntime = true;
214
+ } else if (reactLib) {
215
+ var _JSX_PRAGMA$effective, _packageJson$dependen3, _packageJson$devDepen3, _packageJson$peerDepe3, _semver$minVersion;
216
+ let effectiveReactLib = packageJson !== null && packageJson !== void 0 && packageJson.alias && packageJson.alias['react'] === 'preact/compat' ? 'preact' : reactLib;
217
+ // @ts-expect-error TS7053
218
+ let automaticVersion = (_JSX_PRAGMA$effective = JSX_PRAGMA[effectiveReactLib]) === null || _JSX_PRAGMA$effective === void 0 ? void 0 : _JSX_PRAGMA$effective.automatic;
219
+ let reactLibVersion = (packageJson === null || packageJson === void 0 || (_packageJson$dependen3 = packageJson.dependencies) === null || _packageJson$dependen3 === void 0 ? void 0 : _packageJson$dependen3[effectiveReactLib]) || (packageJson === null || packageJson === void 0 || (_packageJson$devDepen3 = packageJson.devDependencies) === null || _packageJson$devDepen3 === void 0 ? void 0 : _packageJson$devDepen3[effectiveReactLib]) || (packageJson === null || packageJson === void 0 || (_packageJson$peerDepe3 = packageJson.peerDependencies) === null || _packageJson$peerDepe3 === void 0 ? void 0 : _packageJson$peerDepe3[effectiveReactLib]);
220
+ // @ts-expect-error TS2322
221
+ reactLibVersion = reactLibVersion ? _semver().default.validRange(reactLibVersion) : null;
222
+ let minReactLibVersion = reactLibVersion !== null && reactLibVersion !== '*' ? // @ts-expect-error TS2345
223
+ (_semver$minVersion = _semver().default.minVersion(reactLibVersion)) === null || _semver$minVersion === void 0 ? void 0 : _semver$minVersion.toString() : null;
224
+ automaticJSXRuntime = automaticVersion && !(compilerOptions !== null && compilerOptions !== void 0 && compilerOptions.jsxFactory) && minReactLibVersion != null && _semver().default.satisfies(minReactLibVersion, automaticVersion, {
225
+ includePrerelease: true
226
+ });
227
+ if (automaticJSXRuntime) {
228
+ jsxImportSource = reactLib;
229
+ }
230
+ }
231
+ isJSX = Boolean((compilerOptions === null || compilerOptions === void 0 ? void 0 : compilerOptions.jsx) || jsxPragma);
232
+ }
233
+ return {
234
+ isJSX,
235
+ jsxPragma,
236
+ jsxPragmaFrag,
237
+ jsxImportSource,
238
+ automaticJSXRuntime,
239
+ reactRefresh
240
+ };
241
+ }
176
242
  var _default = exports.default = new (_plugin().Transformer)({
177
243
  async loadConfig({
178
244
  config,
179
- options,
180
- logger
245
+ options
181
246
  }) {
247
+ var _conf$contents;
248
+ let conf = await config.getConfigFrom(options.projectRoot + '/index', [], {
249
+ packageKey: '@atlaspack/transformer-js'
250
+ });
251
+ if (conf && conf.contents) {
252
+ _utils().validateSchema.diagnostic(CONFIG_SCHEMA, {
253
+ data: conf.contents,
254
+ source: () => options.inputFS.readFileSync(conf.filePath, 'utf8'),
255
+ filePath: conf.filePath,
256
+ prependKey: `/${(0, _diagnostic().encodeJSONKeyComponent)('@atlaspack/transformer-js')}`
257
+ },
258
+ // FIXME
259
+ '@atlaspack/transformer-js', 'Invalid config for @atlaspack/transformer-js');
260
+ }
182
261
  let packageJson = await config.getPackage();
183
- let isJSX, pragma, pragmaFrag, jsxImportSource, automaticJSXRuntime, reactRefresh, decorators, useDefineForClassFields;
262
+ let decorators, useDefineForClassFields;
263
+ let {
264
+ isJSX,
265
+ jsxPragma,
266
+ jsxPragmaFrag,
267
+ jsxImportSource,
268
+ automaticJSXRuntime,
269
+ reactRefresh
270
+ } = options.featureFlags.newJsxConfig ? (0, _rust().determineJsxConfiguration)(config.searchPath, config.isSource, conf === null || conf === void 0 || (_conf$contents = conf.contents) === null || _conf$contents === void 0 ? void 0 : _conf$contents.jsx, options.projectRoot) : await legacyDetemineJsxConfig(config, options);
184
271
  if (config.isSource) {
185
- var _packageJson$dependen2, _packageJson$devDepen2, _packageJson$peerDepe2, _await$config$getConf;
186
- let reactLib;
187
- if (packageJson !== null && packageJson !== void 0 && packageJson.alias && packageJson.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(libName => {
193
- var _packageJson$dependen, _packageJson$devDepen, _packageJson$peerDepe;
194
- return (packageJson === null || packageJson === void 0 || (_packageJson$dependen = packageJson.dependencies) === null || _packageJson$dependen === void 0 ? void 0 : _packageJson$dependen[libName]) || (packageJson === null || packageJson === void 0 || (_packageJson$devDepen = packageJson.devDependencies) === null || _packageJson$devDepen === void 0 ? void 0 : _packageJson$devDepen[libName]) || (packageJson === null || packageJson === void 0 || (_packageJson$peerDepe = packageJson.peerDependencies) === null || _packageJson$peerDepe === void 0 ? void 0 : _packageJson$peerDepe[libName]);
195
- });
196
- }
197
- reactRefresh = options.hmrOptions && options.mode === 'development' && Boolean((packageJson === null || packageJson === void 0 || (_packageJson$dependen2 = packageJson.dependencies) === null || _packageJson$dependen2 === void 0 ? void 0 : _packageJson$dependen2.react) || (packageJson === null || packageJson === void 0 || (_packageJson$devDepen2 = packageJson.devDependencies) === null || _packageJson$devDepen2 === void 0 ? void 0 : _packageJson$devDepen2.react) || (packageJson === null || packageJson === void 0 || (_packageJson$peerDepe2 = packageJson.peerDependencies) === null || _packageJson$peerDepe2 === void 0 ? void 0 : _packageJson$peerDepe2.react));
198
- const compilerOptions = (_await$config$getConf = await config.getConfigFrom(options.projectRoot + '/index', ['tsconfig.json', 'jsconfig.json'], {
272
+ var _await$config$getConf2;
273
+ const compilerOptions = (_await$config$getConf2 = await config.getConfigFrom(options.projectRoot + '/index', ['tsconfig.json', 'jsconfig.json'], {
199
274
  readTracking: true
200
- })) === null || _await$config$getConf === void 0 || (_await$config$getConf = _await$config$getConf.contents) === null || _await$config$getConf === void 0 ? void 0 : _await$config$getConf.compilerOptions;
201
-
202
- // Use explicitly defined JSX options in tsconfig.json over inferred values from dependencies.
203
- pragma = (compilerOptions === null || compilerOptions === void 0 ? void 0 : compilerOptions.jsxFactory) || (
204
- // @ts-expect-error TS7053
205
- reactLib ? JSX_PRAGMA[reactLib].pragma : undefined);
206
- pragmaFrag = (compilerOptions === null || compilerOptions === void 0 ? void 0 : compilerOptions.jsxFragmentFactory) || (
207
- // @ts-expect-error TS7053
208
- reactLib ? JSX_PRAGMA[reactLib].pragmaFrag : undefined);
209
- if ((compilerOptions === null || compilerOptions === void 0 ? void 0 : compilerOptions.jsx) === 'react-jsx' || (compilerOptions === null || compilerOptions === void 0 ? void 0 : compilerOptions.jsx) === 'react-jsxdev' || compilerOptions !== null && compilerOptions !== void 0 && compilerOptions.jsxImportSource) {
210
- jsxImportSource = compilerOptions === null || compilerOptions === void 0 ? void 0 : compilerOptions.jsxImportSource;
211
- automaticJSXRuntime = true;
212
- } else if (reactLib) {
213
- var _JSX_PRAGMA$effective, _packageJson$dependen3, _packageJson$devDepen3, _packageJson$peerDepe3, _semver$minVersion;
214
- let effectiveReactLib = packageJson !== null && packageJson !== void 0 && packageJson.alias && packageJson.alias['react'] === 'preact/compat' ? 'preact' : reactLib;
215
- // @ts-expect-error TS7053
216
- let automaticVersion = (_JSX_PRAGMA$effective = JSX_PRAGMA[effectiveReactLib]) === null || _JSX_PRAGMA$effective === void 0 ? void 0 : _JSX_PRAGMA$effective.automatic;
217
- let reactLibVersion = (packageJson === null || packageJson === void 0 || (_packageJson$dependen3 = packageJson.dependencies) === null || _packageJson$dependen3 === void 0 ? void 0 : _packageJson$dependen3[effectiveReactLib]) || (packageJson === null || packageJson === void 0 || (_packageJson$devDepen3 = packageJson.devDependencies) === null || _packageJson$devDepen3 === void 0 ? void 0 : _packageJson$devDepen3[effectiveReactLib]) || (packageJson === null || packageJson === void 0 || (_packageJson$peerDepe3 = packageJson.peerDependencies) === null || _packageJson$peerDepe3 === void 0 ? void 0 : _packageJson$peerDepe3[effectiveReactLib]);
218
- // @ts-expect-error TS2322
219
- reactLibVersion = reactLibVersion ? _semver().default.validRange(reactLibVersion) : null;
220
- let minReactLibVersion = reactLibVersion !== null && reactLibVersion !== '*' ? // @ts-expect-error TS2345
221
- (_semver$minVersion = _semver().default.minVersion(reactLibVersion)) === null || _semver$minVersion === void 0 ? void 0 : _semver$minVersion.toString() : null;
222
- automaticJSXRuntime = automaticVersion && !(compilerOptions !== null && compilerOptions !== void 0 && compilerOptions.jsxFactory) && minReactLibVersion != null && _semver().default.satisfies(minReactLibVersion, automaticVersion, {
223
- includePrerelease: true
224
- });
225
- if (automaticJSXRuntime) {
226
- jsxImportSource = reactLib;
227
- }
228
- }
229
- isJSX = Boolean((compilerOptions === null || compilerOptions === void 0 ? void 0 : compilerOptions.jsx) || pragma);
275
+ })) === null || _await$config$getConf2 === void 0 || (_await$config$getConf2 = _await$config$getConf2.contents) === null || _await$config$getConf2 === void 0 ? void 0 : _await$config$getConf2.compilerOptions;
230
276
  decorators = compilerOptions === null || compilerOptions === void 0 ? void 0 : compilerOptions.experimentalDecorators;
231
277
  useDefineForClassFields = compilerOptions === null || compilerOptions === void 0 ? void 0 : compilerOptions.useDefineForClassFields;
232
278
  if (useDefineForClassFields === undefined && (compilerOptions === null || compilerOptions === void 0 ? void 0 : compilerOptions.target) != null) {
@@ -243,9 +289,6 @@ var _default = exports.default = new (_plugin().Transformer)({
243
289
  // Check if we should ignore fs calls
244
290
  // See https://github.com/defunctzombie/node-browser-resolve#skip
245
291
  let ignoreFS = packageJson && packageJson.browser && typeof packageJson.browser === 'object' && packageJson.browser.fs === false;
246
- let conf = await config.getConfigFrom(options.projectRoot + '/index', [], {
247
- packageKey: '@atlaspack/transformer-js'
248
- });
249
292
  let inlineEnvironment = config.isSource;
250
293
  let inlineFS = !ignoreFS;
251
294
  let inlineConstants = false;
@@ -288,34 +331,20 @@ var _default = exports.default = new (_plugin().Transformer)({
288
331
  }
289
332
  config.invalidateOnEnvChange('SYNC_DYNAMIC_IMPORT_CONFIG');
290
333
  if (conf && conf.contents) {
291
- var _conf$contents, _conf$contents2, _conf$contents3, _conf$contents4, _conf$contents5;
292
- _utils().validateSchema.diagnostic(CONFIG_SCHEMA, {
293
- data: conf.contents,
294
- source: () => options.inputFS.readFileSync(conf.filePath, 'utf8'),
295
- filePath: conf.filePath,
296
- prependKey: `/${(0, _diagnostic().encodeJSONKeyComponent)('@atlaspack/transformer-js')}`
297
- },
298
- // FIXME
299
- '@atlaspack/transformer-js', 'Invalid config for @atlaspack/transformer-js');
300
- addReactDisplayName =
301
- // @ts-expect-error TS2339
302
- ((_conf$contents = conf.contents) === null || _conf$contents === void 0 ? void 0 : _conf$contents.addReactDisplayName) ?? addReactDisplayName;
303
- // @ts-expect-error TS2339
304
- magicComments = ((_conf$contents2 = conf.contents) === null || _conf$contents2 === void 0 ? void 0 : _conf$contents2.magicComments) ?? magicComments;
305
- // @ts-expect-error TS2339
306
- inlineEnvironment = ((_conf$contents3 = conf.contents) === null || _conf$contents3 === void 0 ? void 0 : _conf$contents3.inlineEnvironment) ?? inlineEnvironment;
307
- // @ts-expect-error TS2339
308
- inlineFS = ((_conf$contents4 = conf.contents) === null || _conf$contents4 === void 0 ? void 0 : _conf$contents4.inlineFS) ?? inlineFS;
309
- inlineConstants =
310
- // @ts-expect-error TS2339
311
- ((_conf$contents5 = conf.contents) === null || _conf$contents5 === void 0 ? void 0 : _conf$contents5.unstable_inlineConstants) ?? inlineConstants;
334
+ var _conf$contents2, _conf$contents3, _conf$contents4, _conf$contents5, _conf$contents6;
335
+ addReactDisplayName = ((_conf$contents2 = conf.contents) === null || _conf$contents2 === void 0 ? void 0 : _conf$contents2.addReactDisplayName) ?? addReactDisplayName;
336
+ magicComments = ((_conf$contents3 = conf.contents) === null || _conf$contents3 === void 0 ? void 0 : _conf$contents3.magicComments) ?? magicComments;
337
+ // @ts-expect-error TS2322
338
+ inlineEnvironment = ((_conf$contents4 = conf.contents) === null || _conf$contents4 === void 0 ? void 0 : _conf$contents4.inlineEnvironment) ?? inlineEnvironment;
339
+ inlineFS = ((_conf$contents5 = conf.contents) === null || _conf$contents5 === void 0 ? void 0 : _conf$contents5.inlineFS) ?? inlineFS;
340
+ inlineConstants = ((_conf$contents6 = conf.contents) === null || _conf$contents6 === void 0 ? void 0 : _conf$contents6.unstable_inlineConstants) ?? inlineConstants;
312
341
  }
313
342
  return {
314
343
  isJSX,
315
344
  automaticJSXRuntime,
316
345
  jsxImportSource,
317
- pragma,
318
- pragmaFrag,
346
+ pragma: jsxPragma,
347
+ pragmaFrag: jsxPragmaFrag,
319
348
  inlineEnvironment,
320
349
  inlineFS,
321
350
  inlineConstants,
@@ -466,7 +495,7 @@ var _default = exports.default = new (_plugin().Transformer)({
466
495
  automatic_jsx_runtime: Boolean(config === null || config === void 0 ? void 0 : config.automaticJSXRuntime),
467
496
  jsx_import_source: config === null || config === void 0 ? void 0 : config.jsxImportSource,
468
497
  is_development: options.mode === 'development',
469
- react_refresh: asset.env.isBrowser() && !asset.env.isLibrary && !asset.env.isWorker() && !asset.env.isTesseract() && !asset.env.isWorklet() && Boolean(config === null || config === void 0 ? void 0 : config.reactRefresh),
498
+ react_refresh: Boolean(asset.env.isBrowser() && !asset.env.isLibrary && !asset.env.isWorker() && !asset.env.isTesseract() && !asset.env.isWorklet() && (config === null || config === void 0 ? void 0 : config.reactRefresh) && options.hmrOptions && options.mode === 'development'),
470
499
  decorators: Boolean(config === null || config === void 0 ? void 0 : config.decorators),
471
500
  use_define_for_class_fields: Boolean(config === null || config === void 0 ? void 0 : config.useDefineForClassFields),
472
501
  targets,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaspack/transformer-js",
3
- "version": "10.1.1-dev-d5e4c77df.0",
3
+ "version": "10.1.1-dev-a76a48b52.0",
4
4
  "license": "(MIT OR Apache-2.0)",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -24,14 +24,14 @@
24
24
  "src"
25
25
  ],
26
26
  "dependencies": {
27
- "@atlaspack/build-cache": "2.13.7-dev-d5e4c77df.0",
28
- "@atlaspack/diagnostic": "2.14.5-dev-d5e4c77df.0",
29
- "@atlaspack/feature-flags": "2.27.3-dev-d5e4c77df.0",
30
- "@atlaspack/plugin": "2.14.42-dev-d5e4c77df.0",
31
- "@atlaspack/rust": "3.13.1-dev-d5e4c77df.0",
32
- "@atlaspack/source-map": "3.1.3-dev-d5e4c77df.0",
33
- "@atlaspack/utils": "3.2.3-dev-d5e4c77df.0",
34
- "@atlaspack/workers": "2.14.42-dev-d5e4c77df.0",
27
+ "@atlaspack/build-cache": "2.13.7-dev-a76a48b52.0",
28
+ "@atlaspack/diagnostic": "2.14.5-dev-a76a48b52.0",
29
+ "@atlaspack/feature-flags": "2.27.3-dev-a76a48b52.0",
30
+ "@atlaspack/plugin": "2.14.42-dev-a76a48b52.0",
31
+ "@atlaspack/rust": "3.13.1-dev-a76a48b52.0",
32
+ "@atlaspack/source-map": "3.1.3-dev-a76a48b52.0",
33
+ "@atlaspack/utils": "3.2.3-dev-a76a48b52.0",
34
+ "@atlaspack/workers": "2.14.42-dev-a76a48b52.0",
35
35
  "@swc/helpers": "^0.5.15",
36
36
  "browserslist": "^4.6.6",
37
37
  "nullthrows": "^1.1.1",
@@ -42,5 +42,5 @@
42
42
  "@atlaspack/core": "2.29.1"
43
43
  },
44
44
  "type": "commonjs",
45
- "gitHead": "d5e4c77df7fca42afe20b7d46e9c77583978ba74"
45
+ "gitHead": "a76a48b520292ce37f17315cbafebc46417aed27"
46
46
  }
@@ -4,13 +4,19 @@ import type {
4
4
  SourceLocation,
5
5
  FilePath,
6
6
  FileCreateInvalidation,
7
+ Config,
8
+ PluginOptions,
7
9
  } from '@atlaspack/types';
8
10
  import {createBuildCache} from '@atlaspack/build-cache';
9
11
  import type {SchemaEntity} from '@atlaspack/utils';
10
12
  import type {Diagnostic} from '@atlaspack/diagnostic';
11
13
  import SourceMap from '@atlaspack/source-map';
12
14
  import {Transformer} from '@atlaspack/plugin';
13
- import {transform, transformAsync} from '@atlaspack/rust';
15
+ import {
16
+ transform,
17
+ transformAsync,
18
+ determineJsxConfiguration,
19
+ } from '@atlaspack/rust';
14
20
  import invariant from 'assert';
15
21
  import browserslist from 'browserslist';
16
22
  import semver from 'semver';
@@ -117,10 +123,24 @@ const CONFIG_SCHEMA: SchemaEntity = {
117
123
  unstable_inlineConstants: {
118
124
  type: 'boolean',
119
125
  },
126
+ jsx: {
127
+ type: 'object',
128
+ },
120
129
  },
121
130
  additionalProperties: false,
122
131
  };
123
132
 
133
+ // Mirrors the CONFIG_SCHEMA
134
+ interface JsTransformerConfig {
135
+ inlineFS?: boolean;
136
+ inlineEnvironment?: boolean | string[];
137
+ addReactDisplayName?: boolean;
138
+ magicComments?: boolean;
139
+ unstable_inlineConstants?: boolean;
140
+ // This is exclusively used in Rust so not worth typing
141
+ jsx: any;
142
+ }
143
+
124
144
  const configCache = createBuildCache();
125
145
 
126
146
  const SCRIPT_ERRORS = {
@@ -174,41 +194,167 @@ type MacroContext = {
174
194
  invalidateOnBuild(): void;
175
195
  };
176
196
 
197
+ interface JsxConfig {
198
+ isJSX: boolean | undefined;
199
+ jsxPragma: string | undefined;
200
+ jsxPragmaFrag: string | undefined;
201
+ jsxImportSource: string | undefined;
202
+ automaticJSXRuntime: boolean | undefined;
203
+ reactRefresh: boolean | null | undefined;
204
+ }
205
+
206
+ async function legacyDetemineJsxConfig(
207
+ config: Config,
208
+ options: PluginOptions,
209
+ ): Promise<JsxConfig> {
210
+ let packageJson = await config.getPackage();
211
+ let isJSX,
212
+ jsxPragma,
213
+ jsxPragmaFrag,
214
+ jsxImportSource,
215
+ automaticJSXRuntime,
216
+ reactRefresh;
217
+
218
+ if (config.isSource) {
219
+ let reactLib;
220
+ if (packageJson?.alias && packageJson.alias['react']) {
221
+ // e.g.: `{ alias: { "react": "preact/compat" } }`
222
+ reactLib = 'react';
223
+ } else {
224
+ // Find a dependency that we can map to a JSX pragma
225
+ reactLib = Object.keys(JSX_PRAGMA).find(
226
+ (libName) =>
227
+ packageJson?.dependencies?.[libName] ||
228
+ packageJson?.devDependencies?.[libName] ||
229
+ packageJson?.peerDependencies?.[libName],
230
+ );
231
+ }
232
+
233
+ reactRefresh = Boolean(
234
+ packageJson?.dependencies?.react ||
235
+ packageJson?.devDependencies?.react ||
236
+ packageJson?.peerDependencies?.react,
237
+ );
238
+
239
+ const compilerOptions: TSConfig['compilerOptions'] = (
240
+ await config.getConfigFrom<TSConfig>(
241
+ options.projectRoot + '/index',
242
+ ['tsconfig.json', 'jsconfig.json'],
243
+ {
244
+ readTracking: true,
245
+ },
246
+ )
247
+ )?.contents?.compilerOptions;
248
+
249
+ // Use explicitly defined JSX options in tsconfig.json over inferred values from dependencies.
250
+ jsxPragma =
251
+ compilerOptions?.jsxFactory ||
252
+ // @ts-expect-error TS7053
253
+ (reactLib ? JSX_PRAGMA[reactLib].pragma : undefined);
254
+ jsxPragmaFrag =
255
+ compilerOptions?.jsxFragmentFactory ||
256
+ // @ts-expect-error TS7053
257
+ (reactLib ? JSX_PRAGMA[reactLib].pragmaFrag : undefined);
258
+
259
+ if (
260
+ compilerOptions?.jsx === 'react-jsx' ||
261
+ compilerOptions?.jsx === 'react-jsxdev' ||
262
+ compilerOptions?.jsxImportSource
263
+ ) {
264
+ jsxImportSource = compilerOptions?.jsxImportSource;
265
+ automaticJSXRuntime = true;
266
+ } else if (reactLib) {
267
+ let effectiveReactLib =
268
+ packageJson?.alias && packageJson.alias['react'] === 'preact/compat'
269
+ ? 'preact'
270
+ : reactLib;
271
+ // @ts-expect-error TS7053
272
+ let automaticVersion = JSX_PRAGMA[effectiveReactLib]?.automatic;
273
+ let reactLibVersion =
274
+ packageJson?.dependencies?.[effectiveReactLib] ||
275
+ packageJson?.devDependencies?.[effectiveReactLib] ||
276
+ packageJson?.peerDependencies?.[effectiveReactLib];
277
+ // @ts-expect-error TS2322
278
+ reactLibVersion = reactLibVersion
279
+ ? semver.validRange(reactLibVersion)
280
+ : null;
281
+ let minReactLibVersion =
282
+ reactLibVersion !== null && reactLibVersion !== '*'
283
+ ? // @ts-expect-error TS2345
284
+ semver.minVersion(reactLibVersion)?.toString()
285
+ : null;
286
+
287
+ automaticJSXRuntime =
288
+ automaticVersion &&
289
+ !compilerOptions?.jsxFactory &&
290
+ minReactLibVersion != null &&
291
+ semver.satisfies(minReactLibVersion, automaticVersion, {
292
+ includePrerelease: true,
293
+ });
294
+
295
+ if (automaticJSXRuntime) {
296
+ jsxImportSource = reactLib;
297
+ }
298
+ }
299
+
300
+ isJSX = Boolean(compilerOptions?.jsx || jsxPragma);
301
+ }
302
+
303
+ return {
304
+ isJSX,
305
+ jsxPragma,
306
+ jsxPragmaFrag,
307
+ jsxImportSource,
308
+ automaticJSXRuntime,
309
+ reactRefresh,
310
+ };
311
+ }
312
+
177
313
  export default new Transformer({
178
- async loadConfig({config, options, logger}) {
314
+ async loadConfig({config, options}) {
315
+ let conf = await config.getConfigFrom<JsTransformerConfig>(
316
+ options.projectRoot + '/index',
317
+ [],
318
+ {
319
+ packageKey: '@atlaspack/transformer-js',
320
+ },
321
+ );
322
+
323
+ if (conf && conf.contents) {
324
+ validateSchema.diagnostic(
325
+ CONFIG_SCHEMA,
326
+ {
327
+ data: conf.contents,
328
+ source: () => options.inputFS.readFileSync(conf.filePath, 'utf8'),
329
+ filePath: conf.filePath,
330
+ prependKey: `/${encodeJSONKeyComponent('@atlaspack/transformer-js')}`,
331
+ },
332
+ // FIXME
333
+ '@atlaspack/transformer-js',
334
+ 'Invalid config for @atlaspack/transformer-js',
335
+ );
336
+ }
337
+
179
338
  let packageJson = await config.getPackage();
180
- let isJSX,
181
- pragma,
182
- pragmaFrag,
339
+ let decorators, useDefineForClassFields;
340
+
341
+ let {
342
+ isJSX,
343
+ jsxPragma,
344
+ jsxPragmaFrag,
183
345
  jsxImportSource,
184
346
  automaticJSXRuntime,
185
347
  reactRefresh,
186
- decorators,
187
- useDefineForClassFields;
188
- if (config.isSource) {
189
- let reactLib;
190
- if (packageJson?.alias && packageJson.alias['react']) {
191
- // e.g.: `{ alias: { "react": "preact/compat" } }`
192
- reactLib = 'react';
193
- } else {
194
- // Find a dependency that we can map to a JSX pragma
195
- reactLib = Object.keys(JSX_PRAGMA).find(
196
- (libName) =>
197
- packageJson?.dependencies?.[libName] ||
198
- packageJson?.devDependencies?.[libName] ||
199
- packageJson?.peerDependencies?.[libName],
200
- );
201
- }
202
-
203
- reactRefresh =
204
- options.hmrOptions &&
205
- options.mode === 'development' &&
206
- Boolean(
207
- packageJson?.dependencies?.react ||
208
- packageJson?.devDependencies?.react ||
209
- packageJson?.peerDependencies?.react,
210
- );
348
+ } = options.featureFlags.newJsxConfig
349
+ ? (determineJsxConfiguration(
350
+ config.searchPath,
351
+ config.isSource,
352
+ conf?.contents?.jsx,
353
+ options.projectRoot,
354
+ ) as JsxConfig)
355
+ : await legacyDetemineJsxConfig(config, options);
211
356
 
357
+ if (config.isSource) {
212
358
  const compilerOptions: TSConfig['compilerOptions'] = (
213
359
  await config.getConfigFrom<TSConfig>(
214
360
  options.projectRoot + '/index',
@@ -219,58 +365,6 @@ export default new Transformer({
219
365
  )
220
366
  )?.contents?.compilerOptions;
221
367
 
222
- // Use explicitly defined JSX options in tsconfig.json over inferred values from dependencies.
223
- pragma =
224
- compilerOptions?.jsxFactory ||
225
- // @ts-expect-error TS7053
226
- (reactLib ? JSX_PRAGMA[reactLib].pragma : undefined);
227
- pragmaFrag =
228
- compilerOptions?.jsxFragmentFactory ||
229
- // @ts-expect-error TS7053
230
- (reactLib ? JSX_PRAGMA[reactLib].pragmaFrag : undefined);
231
-
232
- if (
233
- compilerOptions?.jsx === 'react-jsx' ||
234
- compilerOptions?.jsx === 'react-jsxdev' ||
235
- compilerOptions?.jsxImportSource
236
- ) {
237
- jsxImportSource = compilerOptions?.jsxImportSource;
238
- automaticJSXRuntime = true;
239
- } else if (reactLib) {
240
- let effectiveReactLib =
241
- packageJson?.alias && packageJson.alias['react'] === 'preact/compat'
242
- ? 'preact'
243
- : reactLib;
244
- // @ts-expect-error TS7053
245
- let automaticVersion = JSX_PRAGMA[effectiveReactLib]?.automatic;
246
- let reactLibVersion =
247
- packageJson?.dependencies?.[effectiveReactLib] ||
248
- packageJson?.devDependencies?.[effectiveReactLib] ||
249
- packageJson?.peerDependencies?.[effectiveReactLib];
250
- // @ts-expect-error TS2322
251
- reactLibVersion = reactLibVersion
252
- ? semver.validRange(reactLibVersion)
253
- : null;
254
- let minReactLibVersion =
255
- reactLibVersion !== null && reactLibVersion !== '*'
256
- ? // @ts-expect-error TS2345
257
- semver.minVersion(reactLibVersion)?.toString()
258
- : null;
259
-
260
- automaticJSXRuntime =
261
- automaticVersion &&
262
- !compilerOptions?.jsxFactory &&
263
- minReactLibVersion != null &&
264
- semver.satisfies(minReactLibVersion, automaticVersion, {
265
- includePrerelease: true,
266
- });
267
-
268
- if (automaticJSXRuntime) {
269
- jsxImportSource = reactLib;
270
- }
271
- }
272
-
273
- isJSX = Boolean(compilerOptions?.jsx || pragma);
274
368
  decorators = compilerOptions?.experimentalDecorators;
275
369
  useDefineForClassFields = compilerOptions?.useDefineForClassFields;
276
370
  if (
@@ -295,10 +389,6 @@ export default new Transformer({
295
389
  typeof packageJson.browser === 'object' &&
296
390
  packageJson.browser.fs === false;
297
391
 
298
- let conf = await config.getConfigFrom(options.projectRoot + '/index', [], {
299
- packageKey: '@atlaspack/transformer-js',
300
- });
301
-
302
392
  let inlineEnvironment = config.isSource;
303
393
  let inlineFS = !ignoreFS;
304
394
  let inlineConstants = false;
@@ -367,30 +457,13 @@ export default new Transformer({
367
457
  config.invalidateOnEnvChange('SYNC_DYNAMIC_IMPORT_CONFIG');
368
458
 
369
459
  if (conf && conf.contents) {
370
- validateSchema.diagnostic(
371
- CONFIG_SCHEMA,
372
- {
373
- data: conf.contents,
374
- source: () => options.inputFS.readFileSync(conf.filePath, 'utf8'),
375
- filePath: conf.filePath,
376
- prependKey: `/${encodeJSONKeyComponent('@atlaspack/transformer-js')}`,
377
- },
378
- // FIXME
379
- '@atlaspack/transformer-js',
380
- 'Invalid config for @atlaspack/transformer-js',
381
- );
382
-
383
460
  addReactDisplayName =
384
- // @ts-expect-error TS2339
385
461
  conf.contents?.addReactDisplayName ?? addReactDisplayName;
386
- // @ts-expect-error TS2339
387
462
  magicComments = conf.contents?.magicComments ?? magicComments;
388
- // @ts-expect-error TS2339
463
+ // @ts-expect-error TS2322
389
464
  inlineEnvironment = conf.contents?.inlineEnvironment ?? inlineEnvironment;
390
- // @ts-expect-error TS2339
391
465
  inlineFS = conf.contents?.inlineFS ?? inlineFS;
392
466
  inlineConstants =
393
- // @ts-expect-error TS2339
394
467
  conf.contents?.unstable_inlineConstants ?? inlineConstants;
395
468
  }
396
469
 
@@ -398,8 +471,8 @@ export default new Transformer({
398
471
  isJSX,
399
472
  automaticJSXRuntime,
400
473
  jsxImportSource,
401
- pragma,
402
- pragmaFrag,
474
+ pragma: jsxPragma,
475
+ pragmaFrag: jsxPragmaFrag,
403
476
  inlineEnvironment,
404
477
  inlineFS,
405
478
  inlineConstants,
@@ -568,13 +641,16 @@ export default new Transformer({
568
641
  automatic_jsx_runtime: Boolean(config?.automaticJSXRuntime),
569
642
  jsx_import_source: config?.jsxImportSource,
570
643
  is_development: options.mode === 'development',
571
- react_refresh:
644
+ react_refresh: Boolean(
572
645
  asset.env.isBrowser() &&
573
- !asset.env.isLibrary &&
574
- !asset.env.isWorker() &&
575
- !asset.env.isTesseract() &&
576
- !asset.env.isWorklet() &&
577
- Boolean(config?.reactRefresh),
646
+ !asset.env.isLibrary &&
647
+ !asset.env.isWorker() &&
648
+ !asset.env.isTesseract() &&
649
+ !asset.env.isWorklet() &&
650
+ config?.reactRefresh &&
651
+ options.hmrOptions &&
652
+ options.mode === 'development',
653
+ ),
578
654
  decorators: Boolean(config?.decorators),
579
655
  use_define_for_class_fields: Boolean(config?.useDefineForClassFields),
580
656
  targets,