From 57cfb172ecdb40a6d82a6e5d15a687d0cac89182 Mon Sep 17 00:00:00 2001 From: Arthur Fiorette Date: Fri, 13 Mar 2026 18:07:29 -0300 Subject: [PATCH 01/10] code --- packages/register/README.md | 40 ++++ .../__test__/register-runtime-tuning.spec.ts | 183 +++++++++++++++ packages/register/esm.mts | 16 ++ packages/register/package.json | 1 + packages/register/register.ts | 112 ++++++++- packages/register/transform-cache.ts | 221 ++++++++++++++++++ 6 files changed, 568 insertions(+), 5 deletions(-) create mode 100644 packages/register/__test__/register-runtime-tuning.spec.ts create mode 100644 packages/register/transform-cache.ts diff --git a/packages/register/README.md b/packages/register/README.md index adbb762d7..6243bfebd 100644 --- a/packages/register/README.md +++ b/packages/register/README.md @@ -127,3 +127,43 @@ Respect the boolean value in `tsconfig`. `TypeScript` gives files list to `@swc-node/register`, if parse `tsconfig.json` failed or files list empty, `@swc-node/register` will transform all files which were required. And if failed to parse `tsconfig.json`, `@swc-node/register` will print warning which contains failed reason. + +## Performance tuning + +### Transform cache + +`@swc-node/register` now keeps a transform cache (memory + disk) keyed by source, filename, compiler options, and runtime versions. + +Environment variables: + +- `SWC_NODE_CACHE=0` disable cache. +- `SWC_NODE_CACHE_DIR=/path/to/cache` choose disk cache directory. + - default: `${os.tmpdir()}/swc-node-${process.getuid() ?? process.pid}` +- `SWC_NODE_CACHE_TTL_DAYS=7` disk cache retention in days. +- `SWC_NODE_CACHE_MEMORY_LIMIT=2000` max in-process transform entries. +- `SWC_NODE_CACHE_DEBUG=1` print cache hit/miss/store/skip lines to stderr. + +Programmatic cache control: + +```js +const { clearTransformCache, getTransformCacheDirectory } = require('@swc-node/register/register') + +// clear memory + disk (default) +clearTransformCache() + +// clear only memory cache +clearTransformCache({ memory: true, disk: false }) + +// inspect resolved disk cache path +console.log(getTransformCacheDirectory()) +``` + +### Source map memory mode + +Use `SWC_NODE_SOURCE_MAP_MODE` to tune source map memory behavior: + +- `auto` (default): inline maps when Node native source maps are enabled, otherwise map-store mode. +- `inline`: inline data URL source maps only. +- `store`: in-memory map store only (`source-map-support` path). +- `both`: inline + store (highest memory use, mainly for compatibility/debug edge cases). +- `none`: disable both inline/store map injection. diff --git a/packages/register/__test__/register-runtime-tuning.spec.ts b/packages/register/__test__/register-runtime-tuning.spec.ts new file mode 100644 index 000000000..51aec1bc1 --- /dev/null +++ b/packages/register/__test__/register-runtime-tuning.spec.ts @@ -0,0 +1,183 @@ +import test from 'ava' +import sinon from 'sinon' +import * as ts from 'typescript' + +import * as swcCore from '@swc-node/core' +import { SourcemapMap } from '@swc-node/sourcemap-support' + +import { clearTransformCache, compile } from '../register' +import { clearTransformCacheForTest } from '../transform-cache' + +const originalEnv = { ...process.env } +const emptyMap = '{"version":3,"sources":[],"names":[],"mappings":""}' + +function uniquePath(label: string, extension: string) { + return `/tmp/${label}-${Date.now()}-${Math.random().toString(16).slice(2)}.${extension}` +} + +test.beforeEach(() => { + process.env.SWC_NODE_CACHE_DIR = `/tmp/swc-node-test-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}` +}) + +test.afterEach.always(() => { + sinon.restore() + SourcemapMap.clear() + clearTransformCache({ memory: true, disk: false }) + process.env = { ...originalEnv } +}) + +test.serial('reuses transform cache for sync compile', (t) => { + const transformSyncStub = sinon.stub(swcCore, 'transformSync').returns({ + code: 'console.log("cached")', + map: emptyMap, + }) + + const filename = uniquePath('cache-sync', 'ts') + const source = `const value: number = ${Date.now()}` + + const first = compile(source, filename, { + module: ts.ModuleKind.CommonJS, + sourceMap: true, + }) + const second = compile(source, filename, { + module: ts.ModuleKind.CommonJS, + sourceMap: true, + }) + + t.is(first, second) + t.is(transformSyncStub.callCount, 1) +}) + +test.serial('reuses transform cache for async compile', async (t) => { + const transformStub = sinon.stub(swcCore, 'transform').resolves({ + code: 'console.log("cached-async")', + map: emptyMap, + }) + + const filename = uniquePath('cache-async', 'ts') + const source = `const value: number = ${Date.now()}` + + const first = await compile( + source, + filename, + { + module: ts.ModuleKind.ESNext, + sourceMap: true, + }, + true, + ) + const second = await compile( + source, + filename, + { + module: ts.ModuleKind.ESNext, + sourceMap: true, + }, + true, + ) + + t.is(first, second) + t.true(transformStub.callCount <= 1) +}) + +test.serial('supports sourcemap inline-only mode to reduce map-store memory', (t) => { + process.env.SWC_NODE_SOURCE_MAP_MODE = 'inline' + + sinon.stub(swcCore, 'transformSync').returns({ + code: 'console.log("inline-only")', + map: emptyMap, + }) + + const filename = uniquePath('sourcemap-inline', 'ts') + const output = compile('const x = 1', filename, { + module: ts.ModuleKind.CommonJS, + sourceMap: true, + }) + + t.true(output.includes('sourceMappingURL')) + t.false(SourcemapMap.has(filename)) +}) + +test.serial('supports sourcemap store-only mode to avoid inline map payload', (t) => { + process.env.SWC_NODE_SOURCE_MAP_MODE = 'store' + + sinon.stub(swcCore, 'transformSync').returns({ + code: 'console.log("store-only")', + map: emptyMap, + }) + + const filename = uniquePath('sourcemap-store', 'ts') + const output = compile('const x = 1', filename, { + module: ts.ModuleKind.CommonJS, + sourceMap: true, + }) + + t.false(output.includes('sourceMappingURL')) + t.true(SourcemapMap.has(filename)) +}) + +test.serial('skips transform for plain js in commonjs mode', (t) => { + const transformSyncStub = sinon.stub(swcCore, 'transformSync') + + const output = compile('module.exports = 42', uniquePath('plain-cjs', 'js'), { + module: ts.ModuleKind.CommonJS, + sourceMap: true, + }) + + t.is(output, 'module.exports = 42') + t.false(transformSyncStub.called) +}) + +test.serial('still transforms js with esm syntax in commonjs mode', (t) => { + const transformSyncStub = sinon.stub(swcCore, 'transformSync').returns({ + code: 'exports.value = 42', + map: emptyMap, + }) + + const output = compile('export const value = 42', uniquePath('esm-in-js', 'js'), { + module: ts.ModuleKind.CommonJS, + sourceMap: true, + }) + + t.true(output.includes('exports.value = 42')) + t.true(transformSyncStub.calledOnce) +}) + +test.serial('skips transform for runtime js in esm mode', async (t) => { + const transformStub = sinon.stub(swcCore, 'transform') + + const output = await compile( + 'export const value = 42', + uniquePath('plain-esm', 'mjs'), + { + module: ts.ModuleKind.ESNext, + sourceMap: true, + }, + true, + ) + + t.is(output, 'export const value = 42') + t.false(transformStub.called) +}) + +test.serial('can clear transform cache programmatically', (t) => { + const transformSyncStub = sinon.stub(swcCore, 'transformSync').returns({ + code: 'console.log("clear-cache")', + map: emptyMap, + }) + + const filename = uniquePath('clear-cache', 'ts') + const options = { + module: ts.ModuleKind.CommonJS, + sourceMap: true, + } + + compile('const value: number = 1', filename, options) + compile('const value: number = 1', filename, options) + t.is(transformSyncStub.callCount, 1) + + clearTransformCache({ memory: true, disk: true }) + + compile('const value: number = 1', filename, options) + t.is(transformSyncStub.callCount, 2) +}) diff --git a/packages/register/esm.mts b/packages/register/esm.mts index a48cd0896..f2140f131 100644 --- a/packages/register/esm.mts +++ b/packages/register/esm.mts @@ -278,6 +278,8 @@ const tsconfigForSWCNode = { baseUrl: undefined, } +const ESM_SKIP_COMPILE_EXTENSIONS = new Set(['.js', '.mjs', '.cjs', '.es', '.es6']) + export const load: LoadHook = async (url, context, nextLoad) => { debug('load', url, JSON.stringify(context)) @@ -317,6 +319,15 @@ export const load: LoadHook = async (url, context, nextLoad) => { // and would likely be a breaking change anyway. Do a best effort to give a real path // like it expects, which at least fixes relative input sourcemap paths. const filename = url.startsWith('file:') ? fileURLToPath(url) : url + + if (shouldSkipCompileInEsmLoader(filename)) { + debug('skip compile: runtime js module', url) + return addShortCircuitSignal({ + format: resolvedFormat, + source, + }) + } + const compiled = await compile(code, filename, tsconfigForSWCNode, true) debug('compiled', url, resolvedFormat) @@ -345,3 +356,8 @@ const parseUrl = return null } } + +function shouldSkipCompileInEsmLoader(filename: string): boolean { + const extension = extname(filename).toLowerCase() + return ESM_SKIP_COMPILE_EXTENSIONS.has(extension) +} diff --git a/packages/register/package.json b/packages/register/package.json index dd1e71ebd..3e4e09ff7 100644 --- a/packages/register/package.json +++ b/packages/register/package.json @@ -44,6 +44,7 @@ "@swc-node/sourcemap-support": "^0.6.1", "colorette": "^2.0.20", "debug": "^4.4.1", + "json-stable-stringify": "^1.3.0", "oxc-resolver": "^11.6.1", "pirates": "^4.0.7", "tslib": "^2.8.1" diff --git a/packages/register/register.ts b/packages/register/register.ts index fefb1f4c3..c6ee5aeb6 100644 --- a/packages/register/register.ts +++ b/packages/register/register.ts @@ -1,9 +1,14 @@ +import { extname } from 'node:path' + import { Options, transform, transformSync } from '@swc-node/core' import { installSourceMapSupport, SourcemapMap } from '@swc-node/sourcemap-support' import { addHook } from 'pirates' import * as ts from 'typescript' import { readDefaultTsConfig, tsCompilerOptionsToSwcConfig } from './read-default-tsconfig' +import { createCacheKey, getCachedTransform, setCachedTransform } from './transform-cache' + +const LooksLikeEsmSyntaxRegex = /(?:^|\n)\s*import\s|(?:^|\n)\s*export\s|\bimport\.meta\b/ const DEFAULT_EXTENSIONS = new Set([ ts.Extension.Js, @@ -18,6 +23,16 @@ const DEFAULT_EXTENSIONS = new Set([ '.es', ]) +const JS_RUNTIME_EXTENSIONS = new Set([ts.Extension.Js, ts.Extension.Mjs, ts.Extension.Cjs, '.es6', '.es']) + +// Runtime knobs here are process-scoped and comparatively cheap to read, so +// they gate cache safety without paying per-module deep serialization costs. +const CacheRuntimeSalt = [ + process.env.SWCRC ? 'swcrc=1' : 'swcrc=0', + `swcConfig=${process.env.SWC_CONFIG_FILE ?? ''}`, + `sourceMapMode=${process.env.SWC_NODE_SOURCE_MAP_MODE ?? 'auto'}`, +].join(';') + const injectInlineSourceMap = ({ filename, code, @@ -27,12 +42,23 @@ const injectInlineSourceMap = ({ code: string map: string | undefined }): string => { - if (map) { + if (!map) { + return code + } + + // Choose map storage strategy at emit time so one process can tune behavior + // per runtime profile (debuggability vs memory) without rebuilds. + const sourceMapMode = getSourceMapMode() + if (sourceMapMode.store) { SourcemapMap.set(filename, map) + } + + if (sourceMapMode.inline) { const base64Map = Buffer.from(map, 'utf8').toString('base64') const sourceMapContent = `//# sourceMappingURL=data:application/json;charset=utf-8;base64,${base64Map}` return `${code}\n${sourceMapContent}` } + return code } @@ -82,12 +108,41 @@ export function compile( if (sourcecode == null) { return } - if (options && typeof options.fallbackToTs === 'function' && options.fallbackToTs(filename)) { - delete options.fallbackToTs + + const fallbackToTs = Boolean(options && typeof options.fallbackToTs === 'function' && options.fallbackToTs(filename)) + + delete options.fallbackToTs + + // Fast-path before cache work for files intentionally left as runtime JS. + // This keeps cache logs meaningful and avoids unnecessary key generation. + if (!fallbackToTs && shouldSkipTransformForRuntimeJs(filename, sourcecode, options)) { + logCacheDebug('skip', filename) + return sourcecode + } + + const cacheInput = { + sourcecode, + filename, + options, + fallbackToTs, + runSalt: CacheRuntimeSalt, + } + + const cacheKey = createCacheKey(cacheInput) + const cacheEntry = getCachedTransform(cacheKey) + if (cacheEntry) { + // Keep source-map behavior consistent for cache hits, otherwise stack trace + // semantics would differ between warm and cold compiles. + return injectInlineSourceMap({ filename, code: cacheEntry.code, map: cacheEntry.map }) + } + + if (fallbackToTs) { const { outputText, sourceMapText } = ts.transpileModule(sourcecode, { fileName: filename, compilerOptions: options, }) + + setCachedTransform(cacheKey, { code: outputText, map: sourceMapText }) return injectInlineSourceMap({ filename, code: outputText, map: sourceMapText }) } @@ -97,7 +152,7 @@ export function compile( swcRegisterConfig = { swc: { swcrc: true, - configFile: process.env.SWC_CONFIG_FILE + configFile: process.env.SWC_CONFIG_FILE, }, } } else { @@ -106,10 +161,12 @@ export function compile( if (async) { return transform(sourcecode, filename, swcRegisterConfig).then(({ code, map }) => { + setCachedTransform(cacheKey, { code, map }) return injectInlineSourceMap({ filename, code, map }) }) } else { const { code, map } = transformSync(sourcecode, filename, swcRegisterConfig) + setCachedTransform(cacheKey, { code, map }) return injectInlineSourceMap({ filename, code, map }) } } @@ -119,9 +176,54 @@ export function register(options: Partial = {}, hookOpts = { options = Object.keys(options).length ? options : readDefaultTsConfig() } options.module = ts.ModuleKind.CommonJS - installSourceMapSupport() + + // Install source-map-support only when map-store mode is active; with inline + // mode and native source maps, this avoids duplicate map retention. + if (getSourceMapMode().store) { + installSourceMapSupport() + } + return addHook((code, filename) => compile(code, filename, options), { exts: Array.from(DEFAULT_EXTENSIONS), ...hookOpts, }) } + +function getSourceMapMode(): { inline: boolean; store: boolean } { + switch (process.env.SWC_NODE_SOURCE_MAP_MODE?.trim().toLowerCase()) { + case 'both': + return { inline: true, store: true } + case 'inline': + return { inline: true, store: false } + case 'store': + return { inline: false, store: true } + case 'none': + return { inline: false, store: false } + } + + // In auto mode, follow runtime capability: native source maps favor inline, + // non-native stacks favor store mode. + return process.sourceMapsEnabled ? { inline: true, store: false } : { inline: false, store: true } +} + +function shouldSkipTransformForRuntimeJs(filename: string, sourcecode: string, options: ts.CompilerOptions): boolean { + // Respect SWCRC workflows first. When users opt into external SWC config, + // consistency with that config takes priority over local fast-path heuristics. + if (process.env.SWCRC) { + return false + } + + const extension = extname(filename).toLowerCase() + if (!JS_RUNTIME_EXTENSIONS.has(extension)) { + return false + } + + const moduleKind = options.module ?? ts.ModuleKind.ES2015 + if (moduleKind !== ts.ModuleKind.CommonJS) { + return true + } + + // CommonJS mode is where accidental ESM-in-JS files usually break at runtime, + // so we keep the transform path only when file content indicates that risk. + return !LooksLikeEsmSyntaxRegex.test(sourcecode) +} diff --git a/packages/register/transform-cache.ts b/packages/register/transform-cache.ts new file mode 100644 index 000000000..d8614366f --- /dev/null +++ b/packages/register/transform-cache.ts @@ -0,0 +1,221 @@ +import fs from 'node:fs' +import { createHash } from 'node:crypto' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import debugFactory from 'debug' + +const stableStringify = require('json-stable-stringify') as (value: unknown) => string + +interface TransformCacheEntry { + code: string + map?: string +} + +interface TransformCacheKeyInput { + sourcecode: string + filename: string + options: Record + fallbackToTs: boolean + runSalt: string +} + +const debug = debugFactory('@swc-node') + +const CACHE_ENABLED = isEnabled(process.env.SWC_NODE_CACHE, true) +const CACHE_DIRECTORY = + process.env.SWC_NODE_CACHE_DIR ?? join(tmpdir(), `swc-node-${process.getuid?.() ?? process.pid}`) +const CACHE_TTL_DAYS = Number(process.env.SWC_NODE_CACHE_TTL_DAYS ?? '7') +const MEMORY_CACHE_LIMIT = Number(process.env.SWC_NODE_CACHE_MEMORY_LIMIT ?? '2000') + +if (!Number.isFinite(MEMORY_CACHE_LIMIT) || MEMORY_CACHE_LIMIT < 0) { + throw new Error(`Invalid value for SWC_NODE_CACHE_MEMORY_LIMIT: ${process.env.SWC_NODE_CACHE_MEMORY_LIMIT}`) +} + +const REGISTER_VERSION = readPackageVersion('../package.json') +const SWC_VERSION = readPackageVersion('@swc/core/package.json') + +const memoryCache = new Map() +let optionsSignatureCache = new WeakMap, string>() +let cacheDirectoryReady = false +let cleanupAttempted = false + +export function getCachedTransform(cacheKey: string): TransformCacheEntry | undefined { + if (!CACHE_ENABLED) { + return undefined + } + + const memoryValue = memoryCache.get(cacheKey) + + if (memoryValue) { + return memoryValue + } + + const diskValue = readDiskCache(cacheKey) + + if (diskValue) { + setMemoryCache(cacheKey, diskValue) + } + + return diskValue +} + +export function setCachedTransform(cacheKey: string, value: TransformCacheEntry) { + if (!CACHE_ENABLED) { + return + } + + setMemoryCache(cacheKey, value) + writeDiskCache(cacheKey, value) +} + +export function createCacheKey(input: TransformCacheKeyInput): string { + // Keep cache reuse scoped to both source intent and toolchain version so + // stale compiled output is not reused across upgrades/config changes. + const hash = createHash('sha1') + hash.update(input.sourcecode) + hash.update('\0') + hash.update(input.filename) + hash.update('\0') + hash.update(input.fallbackToTs ? 'ts' : 'swc') + hash.update('\0') + hash.update(getOptionsSignature(input.options)) + hash.update('\0') + hash.update(input.runSalt) + hash.update('\0') + hash.update(`register:${REGISTER_VERSION};swc:${SWC_VERSION}`) + return hash.digest('hex') +} + +function getOptionsSignature(options: Record): string { + const cached = optionsSignatureCache.get(options) + if (cached) { + return cached + } + + // Options are usually reused for most compiles in one process; cache the + // normalized signature so hash generation stays near O(source length). + const signature = stableStringify(options) + optionsSignatureCache.set(options, signature) + return signature +} + +function setMemoryCache(key: string, value: TransformCacheEntry) { + memoryCache.set(key, value) + + // Bound in-process retention for long-lived services where many modules + // may be touched once and never needed again. + while (memoryCache.size > MEMORY_CACHE_LIMIT) { + const oldestKey = memoryCache.keys().next().value + + if (!oldestKey) { + break + } + + memoryCache.delete(oldestKey) + } +} + +function readDiskCache(key: string): TransformCacheEntry | undefined { + try { + ensureCacheDirectory() + const file = fs.readFileSync(join(CACHE_DIRECTORY, `${key}.json`), 'utf8') + return JSON.parse(file) as TransformCacheEntry + } catch (error) { + debug('Failed to read cache file', error) + return undefined + } +} + +function writeDiskCache(key: string, value: TransformCacheEntry) { + try { + ensureCacheDirectory() + fs.writeFileSync(join(CACHE_DIRECTORY, `${key}.json`), JSON.stringify(value), 'utf8') + } catch (error) { + debug('Failed to write cache file', error) + } +} + +function ensureCacheDirectory() { + if (!cacheDirectoryReady) { + fs.mkdirSync(CACHE_DIRECTORY, { recursive: true }) + cacheDirectoryReady = true + } + + if (!cleanupAttempted) { + cleanupAttempted = true + + // Trigger cleanup only after cache is actually used, so startup work stays + // minimal for short-lived commands. + void cleanupStaleDiskCache() + } +} + +async function cleanupStaleDiskCache() { + if (!Number.isFinite(CACHE_TTL_DAYS) || CACHE_TTL_DAYS <= 0) { + return + } + + try { + const files = fs.readdirSync(CACHE_DIRECTORY) + const now = Date.now() + const maxAgeMs = CACHE_TTL_DAYS * 24 * 60 * 60 * 1000 + + // Age-based eviction keeps disk usage stable without maintaining additional metadata files. + for (const file of files) { + if (!file.endsWith('.json')) { + // Non-cache files should not be touched, and may indicate a non-standard cache setup (e.g. with a symlink). + return + } + + const fullPath = join(CACHE_DIRECTORY, file) + const ageMs = now - fs.statSync(fullPath).mtimeMs + + if (ageMs > maxAgeMs) { + fs.unlinkSync(fullPath) + } + } + } catch (error) { + debug('Failed to cleanup cache directory', error) + } +} + +function readPackageVersion(path: string): string { + try { + return require(path).version ?? 'unknown' + } catch (error) { + debug(`Failed to read package ${path} version`, error) + return 'unknown' + } +} + +function isEnabled(value: string | undefined, fallback: boolean): boolean { + if (!value) { + return fallback + } + const normalized = value.trim().toLowerCase() + return normalized !== '0' && normalized !== 'false' && normalized !== 'off' && normalized !== 'no' +} + +export function clearTransformCache(options: { memory?: boolean; disk?: boolean } = {}) { + const { memory = true, disk = true } = options + + if (memory) { + memoryCache.clear() + optionsSignatureCache = new WeakMap, string>() + } + + if (disk) { + try { + fs.rmSync(CACHE_DIRECTORY, { recursive: true, force: true }) + } catch (error) { + debug('Failed to clear cache directory', error) + } + + cacheDirectoryReady = false + cleanupAttempted = false + } +} + +export function getTransformCacheDirectory() { + return CACHE_DIRECTORY +} From b348e02d9f2d34c3d3159dbdb287cceac498d844 Mon Sep 17 00:00:00 2001 From: Arthur Fiorette Date: Fri, 13 Mar 2026 18:08:20 -0300 Subject: [PATCH 02/10] lockfile --- pnpm-lock.yaml | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a792cb76..1e5b6021b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -246,6 +246,9 @@ importers: debug: specifier: ^4.4.1 version: 4.4.3 + json-stable-stringify: + specifier: ^1.3.0 + version: 1.3.0 oxc-resolver: specifier: ^11.6.1 version: 11.19.1 @@ -2661,6 +2664,14 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -2975,6 +2986,10 @@ packages: defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + define-lazy-prop@2.0.0: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} @@ -3411,6 +3426,9 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + has-symbols@1.1.0: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} @@ -3649,6 +3667,9 @@ packages: isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -3861,6 +3882,10 @@ packages: json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-stable-stringify@1.3.0: + resolution: {integrity: sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==} + engines: {node: '>= 0.4'} + json-stringify-nice@1.1.4: resolution: {integrity: sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==} @@ -3878,6 +3903,9 @@ packages: jsonfile@6.2.0: resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + jsonify@0.0.1: + resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==} + jsonparse@1.3.1: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} @@ -4269,6 +4297,10 @@ packages: '@swc/core': optional: true + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -4732,6 +4764,10 @@ packages: set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -7797,6 +7833,18 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + callsites@3.1.0: {} callsites@4.2.0: {} @@ -8074,6 +8122,12 @@ snapshots: dependencies: clone: 1.0.4 + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + define-lazy-prop@2.0.0: {} delayed-stream@1.0.0: {} @@ -8513,6 +8567,10 @@ snapshots: has-flag@4.0.0: {} + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + has-symbols@1.1.0: {} has-tostringtag@1.0.2: @@ -8704,6 +8762,8 @@ snapshots: isarray@1.0.0: {} + isarray@2.0.5: {} + isexe@2.0.0: {} isexe@3.1.5: {} @@ -9099,6 +9159,14 @@ snapshots: json-schema-traverse@1.0.0: {} + json-stable-stringify@1.3.0: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + isarray: 2.0.5 + jsonify: 0.0.1 + object-keys: 1.1.1 + json-stringify-nice@1.1.4: {} json-stringify-safe@5.0.1: {} @@ -9113,6 +9181,8 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonify@0.0.1: {} + jsonparse@1.3.1: {} just-diff-apply@5.5.0: {} @@ -9683,6 +9753,8 @@ snapshots: transitivePeerDependencies: - debug + object-keys@1.1.1: {} + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -10160,6 +10232,15 @@ snapshots: set-blocking@2.0.0: {} + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 From 3f3bd1962786368ee2b8b88dd767824180c84e1d Mon Sep 17 00:00:00 2001 From: Arthur Fiorette Date: Fri, 13 Mar 2026 18:12:15 -0300 Subject: [PATCH 03/10] code --- packages/register/register.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/register/register.ts b/packages/register/register.ts index c6ee5aeb6..19a159e6a 100644 --- a/packages/register/register.ts +++ b/packages/register/register.ts @@ -116,7 +116,6 @@ export function compile( // Fast-path before cache work for files intentionally left as runtime JS. // This keeps cache logs meaningful and avoids unnecessary key generation. if (!fallbackToTs && shouldSkipTransformForRuntimeJs(filename, sourcecode, options)) { - logCacheDebug('skip', filename) return sourcecode } From f873981376ba3765e7f7f436dd7844be52865710 Mon Sep 17 00:00:00 2001 From: Arthur Fiorette Date: Fri, 13 Mar 2026 19:26:55 -0300 Subject: [PATCH 04/10] fix tests and sourcemap --- .gitignore | 3 + .../__snapshots__/sourcemaps.spec.ts.md | 8 +-- .../__snapshots__/sourcemaps.spec.ts.snap | Bin 366 -> 377 bytes packages/register/README.md | 1 - .../__test__/register-runtime-tuning.spec.ts | 4 +- .../ts-compiler-options-to-swc-config.spec.ts | 11 ++++ packages/register/esm.mts | 11 +--- packages/register/read-default-tsconfig.ts | 34 ++++++++--- packages/register/register.ts | 57 +++--------------- packages/register/transform-cache.ts | 37 +++++++++++- 10 files changed, 94 insertions(+), 72 deletions(-) diff --git a/.gitignore b/.gitignore index 71991ede0..e2dc7341d 100644 --- a/.gitignore +++ b/.gitignore @@ -165,6 +165,9 @@ Cargo.lock # idea .idea/ +# Serena +.serena + *.node lib artifacts diff --git a/packages/integrate/__tests__/sourcemaps/__snapshots__/sourcemaps.spec.ts.md b/packages/integrate/__tests__/sourcemaps/__snapshots__/sourcemaps.spec.ts.md index cb5c24d3f..706474dd7 100644 --- a/packages/integrate/__tests__/sourcemaps/__snapshots__/sourcemaps.spec.ts.md +++ b/packages/integrate/__tests__/sourcemaps/__snapshots__/sourcemaps.spec.ts.md @@ -8,12 +8,12 @@ Generated by [AVA](https://avajs.dev). > Snapshot 1 - `Error: ␊ - at /packages/integrate/__tests__/sourcemaps/sourcemaps.spec.ts:18:26␊ + `Error␊ + at (/packages/integrate/__tests__/sourcemaps/sourcemaps.spec.ts:30:5)␊ at Test.callFn (file:///node_modules/.pnpm/ava@6.4.1_encoding@0.1.13/node_modules/ava/lib/test.js:525:26)␊ at Test.run (file:///node_modules/.pnpm/ava@6.4.1_encoding@0.1.13/node_modules/ava/lib/test.js:534:33)␊ at Runner.runSingle (file:///node_modules/.pnpm/ava@6.4.1_encoding@0.1.13/node_modules/ava/lib/runner.js:280:33)␊ at Runner.runTest (file:///node_modules/.pnpm/ava@6.4.1_encoding@0.1.13/node_modules/ava/lib/runner.js:362:30)␊ at async Promise.all (index 0)␊ - at file:///node_modules/.pnpm/ava@6.4.1_encoding@0.1.13/node_modules/ava/lib/runner.js:515:21␊ - at Runner.start (file:///node_modules/.pnpm/ava@6.4.1_encoding@0.1.13/node_modules/ava/lib/runner.js:523:15)` + at async file:///node_modules/.pnpm/ava@6.4.1_encoding@0.1.13/node_modules/ava/lib/runner.js:515:21␊ + at async Runner.start (file:///node_modules/.pnpm/ava@6.4.1_encoding@0.1.13/node_modules/ava/lib/runner.js:523:15)` diff --git a/packages/integrate/__tests__/sourcemaps/__snapshots__/sourcemaps.spec.ts.snap b/packages/integrate/__tests__/sourcemaps/__snapshots__/sourcemaps.spec.ts.snap index de0c48d27cc39b77bdea62aac4f1a04a2934a6f8..768c29bb40c9863a974a50a562ab79e5fe0bb715 100644 GIT binary patch literal 377 zcmV-<0fzoTRzVfe0Pt!@+?b^JfyV zZMN$*-XDty00000000BE&^=GXFc1ddLWPjnn30gjcEC>Jra~4%U0_DQ!W3PTYwFgq zBcIccu|EZVDT;tX5hJ>T)w2;8wMQ=ZZ2r<8dI>f^GmkYVa~`kKF11b z(qy5gxeK&=EeZ(m(!c8WPJ3+~o%GI+FZ*}iJAcL)V-VO4SZBADYv`5@L=E{8N+h9e zz|uoNk!1lXP?m{rytZ{E zUJ-=+Tu)^<1!ouRQUF)Lrm=UlrMQ(g;O&vS( zIkb%ZDey~iglH*ZBsZLHc=x`0y7%S6`f`K&4~QmO*xlgTH&&Ca4;!*IaZS)Sp@d4+ zXwap;_7V5*TC1p@``7*6px4&fMepi-(7z4A2T3kTDisN{bxQiucUp>YmE3wuls7XA|%zPuAO zn~nd5wn@7|ifJar_<&US=1OuOd}R=5dL$Vdr(s8qk}j^ud3r4Wl^df99i`4QA$dOf M1m};kH&+7y0CMT3u>b%7 diff --git a/packages/register/README.md b/packages/register/README.md index 6243bfebd..ef0df8120 100644 --- a/packages/register/README.md +++ b/packages/register/README.md @@ -141,7 +141,6 @@ Environment variables: - default: `${os.tmpdir()}/swc-node-${process.getuid() ?? process.pid}` - `SWC_NODE_CACHE_TTL_DAYS=7` disk cache retention in days. - `SWC_NODE_CACHE_MEMORY_LIMIT=2000` max in-process transform entries. -- `SWC_NODE_CACHE_DEBUG=1` print cache hit/miss/store/skip lines to stderr. Programmatic cache control: diff --git a/packages/register/__test__/register-runtime-tuning.spec.ts b/packages/register/__test__/register-runtime-tuning.spec.ts index 51aec1bc1..26f693ab9 100644 --- a/packages/register/__test__/register-runtime-tuning.spec.ts +++ b/packages/register/__test__/register-runtime-tuning.spec.ts @@ -5,8 +5,8 @@ import * as ts from 'typescript' import * as swcCore from '@swc-node/core' import { SourcemapMap } from '@swc-node/sourcemap-support' -import { clearTransformCache, compile } from '../register' -import { clearTransformCacheForTest } from '../transform-cache' +import { compile } from '../register' +import { clearTransformCache } from '../transform-cache' const originalEnv = { ...process.env } const emptyMap = '{"version":3,"sources":[],"names":[],"mappings":""}' diff --git a/packages/register/__test__/ts-compiler-options-to-swc-config.spec.ts b/packages/register/__test__/ts-compiler-options-to-swc-config.spec.ts index 4bce11e14..3f5dd0ec8 100644 --- a/packages/register/__test__/ts-compiler-options-to-swc-config.spec.ts +++ b/packages/register/__test__/ts-compiler-options-to-swc-config.spec.ts @@ -126,3 +126,14 @@ test('should set all values', (t) => { } t.deepEqual(swcConfig, expected) }) + +test('sourceMap without inlineSourceMap keeps external map output', (t) => { + const options: ts.CompilerOptions = { + sourceMap: true, + inlineSourceMap: false, + } + + const swcConfig = tsCompilerOptionsToSwcConfig(options, 'some-file.ts') + + t.is(swcConfig.sourcemap, true) +}) diff --git a/packages/register/esm.mts b/packages/register/esm.mts index f2140f131..b851ad637 100644 --- a/packages/register/esm.mts +++ b/packages/register/esm.mts @@ -18,6 +18,8 @@ import ts from 'typescript' import { readDefaultTsConfig } from '../lib/read-default-tsconfig.js' // @ts-expect-error import { compile } from '../lib/register.js' +// @ts-expect-error +import { shouldSkipTransformForRuntimeJs } from '../lib/transform-cache.js' const debug = debugFactory('@swc-node') @@ -278,8 +280,6 @@ const tsconfigForSWCNode = { baseUrl: undefined, } -const ESM_SKIP_COMPILE_EXTENSIONS = new Set(['.js', '.mjs', '.cjs', '.es', '.es6']) - export const load: LoadHook = async (url, context, nextLoad) => { debug('load', url, JSON.stringify(context)) @@ -320,7 +320,7 @@ export const load: LoadHook = async (url, context, nextLoad) => { // like it expects, which at least fixes relative input sourcemap paths. const filename = url.startsWith('file:') ? fileURLToPath(url) : url - if (shouldSkipCompileInEsmLoader(filename)) { + if (shouldSkipTransformForRuntimeJs(filename, code, tsconfigForSWCNode.module)) { debug('skip compile: runtime js module', url) return addShortCircuitSignal({ format: resolvedFormat, @@ -356,8 +356,3 @@ const parseUrl = return null } } - -function shouldSkipCompileInEsmLoader(filename: string): boolean { - const extension = extname(filename).toLowerCase() - return ESM_SKIP_COMPILE_EXTENSIONS.has(extension) -} diff --git a/packages/register/read-default-tsconfig.ts b/packages/register/read-default-tsconfig.ts index 94016ffe4..a116d794d 100644 --- a/packages/register/read-default-tsconfig.ts +++ b/packages/register/read-default-tsconfig.ts @@ -10,6 +10,29 @@ const debug = debugFactory('@swc-node') const configCache: Record boolean }>> = {} +// Keep compatibility with the legacy SWC_NODE_INLINE_SOURCE_MAP env by +// mapping it to SWC_NODE_SOURCE_MAP_MODE=inline. +if (typeof process.env.SWC_NODE_INLINE_SOURCE_MAP === 'string') { + process.env.SWC_NODE_SOURCE_MAP_MODE = 'inline' +} + +export function getSourceMapMode(): { inline: boolean; store: boolean } { + switch (process.env.SWC_NODE_SOURCE_MAP_MODE?.trim().toLowerCase()) { + case 'both': + return { inline: true, store: true } + case 'inline': + return { inline: true, store: false } + case 'store': + return { inline: false, store: true } + case 'none': + return { inline: false, store: false } + } + + // In auto mode, follow runtime capability: native source maps favor inline, + // non-native stacks favor store mode. + return process.sourceMapsEnabled ? { inline: true, store: false } : { inline: false, store: true } +} + export function readDefaultTsConfig( tsConfigPath = process.env.SWC_NODE_PROJECT ?? process.env.TS_NODE_PROJECT ?? join(process.cwd(), 'tsconfig.json'), ) { @@ -123,18 +146,15 @@ export function tsCompilerOptionsToSwcConfig(options: ts.CompilerOptions, filena const isJsx = filename.endsWith('.tsx') || filename.endsWith('.jsx') || Boolean(options.jsx) const target = options.target ?? ts.ScriptTarget.ES2018 - const enableInlineSourceMap = - options.inlineSourceMap ?? - (typeof process.env.SWC_NODE_INLINE_SOURCE_MAP === 'string' - ? Boolean(process.env.SWC_NODE_INLINE_SOURCE_MAP) - : undefined) + const sourceMapModeName = process.env.SWC_NODE_SOURCE_MAP_MODE?.trim().toLowerCase() + const enableInlineSourceMap = options.inlineSourceMap ?? (sourceMapModeName === 'inline' ? true : undefined) + const shouldEmitSourceMap = Boolean(options.sourceMap || enableInlineSourceMap) return { module: toModule(options.module ?? ts.ModuleKind.ES2015), target: toTsTarget(target), jsx: isJsx, - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - sourcemap: options.sourceMap || enableInlineSourceMap ? 'inline' : Boolean(options.sourceMap), + sourcemap: enableInlineSourceMap ? 'inline' : shouldEmitSourceMap, experimentalDecorators: options.experimentalDecorators ?? false, emitDecoratorMetadata: options.emitDecoratorMetadata ?? false, useDefineForClassFields: getUseDefineForClassFields(options, target), diff --git a/packages/register/register.ts b/packages/register/register.ts index 19a159e6a..7edc38a64 100644 --- a/packages/register/register.ts +++ b/packages/register/register.ts @@ -1,14 +1,15 @@ -import { extname } from 'node:path' - import { Options, transform, transformSync } from '@swc-node/core' import { installSourceMapSupport, SourcemapMap } from '@swc-node/sourcemap-support' import { addHook } from 'pirates' import * as ts from 'typescript' -import { readDefaultTsConfig, tsCompilerOptionsToSwcConfig } from './read-default-tsconfig' -import { createCacheKey, getCachedTransform, setCachedTransform } from './transform-cache' - -const LooksLikeEsmSyntaxRegex = /(?:^|\n)\s*import\s|(?:^|\n)\s*export\s|\bimport\.meta\b/ +import { getSourceMapMode, readDefaultTsConfig, tsCompilerOptionsToSwcConfig } from './read-default-tsconfig' +import { + createCacheKey, + getCachedTransform, + setCachedTransform, + shouldSkipTransformForRuntimeJs, +} from './transform-cache' const DEFAULT_EXTENSIONS = new Set([ ts.Extension.Js, @@ -23,8 +24,6 @@ const DEFAULT_EXTENSIONS = new Set([ '.es', ]) -const JS_RUNTIME_EXTENSIONS = new Set([ts.Extension.Js, ts.Extension.Mjs, ts.Extension.Cjs, '.es6', '.es']) - // Runtime knobs here are process-scoped and comparatively cheap to read, so // they gate cache safety without paying per-module deep serialization costs. const CacheRuntimeSalt = [ @@ -49,6 +48,7 @@ const injectInlineSourceMap = ({ // Choose map storage strategy at emit time so one process can tune behavior // per runtime profile (debuggability vs memory) without rebuilds. const sourceMapMode = getSourceMapMode() + if (sourceMapMode.store) { SourcemapMap.set(filename, map) } @@ -115,7 +115,7 @@ export function compile( // Fast-path before cache work for files intentionally left as runtime JS. // This keeps cache logs meaningful and avoids unnecessary key generation. - if (!fallbackToTs && shouldSkipTransformForRuntimeJs(filename, sourcecode, options)) { + if (!fallbackToTs && shouldSkipTransformForRuntimeJs(filename, sourcecode, options.module)) { return sourcecode } @@ -187,42 +187,3 @@ export function register(options: Partial = {}, hookOpts = { ...hookOpts, }) } - -function getSourceMapMode(): { inline: boolean; store: boolean } { - switch (process.env.SWC_NODE_SOURCE_MAP_MODE?.trim().toLowerCase()) { - case 'both': - return { inline: true, store: true } - case 'inline': - return { inline: true, store: false } - case 'store': - return { inline: false, store: true } - case 'none': - return { inline: false, store: false } - } - - // In auto mode, follow runtime capability: native source maps favor inline, - // non-native stacks favor store mode. - return process.sourceMapsEnabled ? { inline: true, store: false } : { inline: false, store: true } -} - -function shouldSkipTransformForRuntimeJs(filename: string, sourcecode: string, options: ts.CompilerOptions): boolean { - // Respect SWCRC workflows first. When users opt into external SWC config, - // consistency with that config takes priority over local fast-path heuristics. - if (process.env.SWCRC) { - return false - } - - const extension = extname(filename).toLowerCase() - if (!JS_RUNTIME_EXTENSIONS.has(extension)) { - return false - } - - const moduleKind = options.module ?? ts.ModuleKind.ES2015 - if (moduleKind !== ts.ModuleKind.CommonJS) { - return true - } - - // CommonJS mode is where accidental ESM-in-JS files usually break at runtime, - // so we keep the transform path only when file content indicates that risk. - return !LooksLikeEsmSyntaxRegex.test(sourcecode) -} diff --git a/packages/register/transform-cache.ts b/packages/register/transform-cache.ts index d8614366f..0b6064903 100644 --- a/packages/register/transform-cache.ts +++ b/packages/register/transform-cache.ts @@ -1,10 +1,15 @@ import fs from 'node:fs' +import path from 'node:path' +import * as ts from 'typescript' import { createHash } from 'node:crypto' import { tmpdir } from 'node:os' import { join } from 'node:path' import debugFactory from 'debug' +import stableStringify from 'json-stable-stringify' -const stableStringify = require('json-stable-stringify') as (value: unknown) => string +const LOOKS_LIKE_ESM_SYNTAX_REGEX = /(?:^|\n)\s*import\s|(?:^|\n)\s*export\s|\bimport\.meta\b/ + +const JS_RUNTIME_EXTENSIONS = new Set([ts.Extension.Js, ts.Extension.Mjs, ts.Extension.Cjs, '.es6', '.es']) interface TransformCacheEntry { code: string @@ -94,7 +99,7 @@ function getOptionsSignature(options: Record): string { // Options are usually reused for most compiles in one process; cache the // normalized signature so hash generation stays near O(source length). - const signature = stableStringify(options) + const signature = stableStringify(options)! optionsSignatureCache.set(options, signature) return signature } @@ -219,3 +224,31 @@ export function clearTransformCache(options: { memory?: boolean; disk?: boolean export function getTransformCacheDirectory() { return CACHE_DIRECTORY } + +export function shouldSkipTransformForRuntimeJs( + filename: string, + sourcecode: string, + moduleKind: ts.ModuleKind = ts.ModuleKind.ES2015, + swcrcEnabled: boolean = Boolean(process.env.SWCRC), +): boolean { + // Respect SWCRC workflows first. When users opt into external SWC config, + // consistency with that config takes priority over local fast-path heuristics. + if (swcrcEnabled) { + return false + } + + const extension = path.extname(filename).toLowerCase() + if (!JS_RUNTIME_EXTENSIONS.has(extension)) { + return false + } + + // In non-CommonJS output modes, runtime JS files are already executable for + // Node, so compiling them again mostly adds overhead. + if (moduleKind !== ts.ModuleKind.CommonJS) { + return true + } + + // CommonJS mode is where accidental ESM-in-JS files usually break at runtime, + // so we keep the transform path only when file content indicates that risk. + return !LOOKS_LIKE_ESM_SYNTAX_REGEX.test(sourcecode) +} From 549e696b281f26874371ad10895331c3e011a55f Mon Sep 17 00:00:00 2001 From: Arthur Fiorette Date: Fri, 13 Mar 2026 19:31:49 -0300 Subject: [PATCH 05/10] simplify code --- packages/register/README.md | 4 +-- packages/register/transform-cache.ts | 39 ++-------------------------- 2 files changed, 3 insertions(+), 40 deletions(-) diff --git a/packages/register/README.md b/packages/register/README.md index ef0df8120..0558c65c7 100644 --- a/packages/register/README.md +++ b/packages/register/README.md @@ -137,9 +137,7 @@ And if failed to parse `tsconfig.json`, `@swc-node/register` will print warning Environment variables: - `SWC_NODE_CACHE=0` disable cache. -- `SWC_NODE_CACHE_DIR=/path/to/cache` choose disk cache directory. - - default: `${os.tmpdir()}/swc-node-${process.getuid() ?? process.pid}` -- `SWC_NODE_CACHE_TTL_DAYS=7` disk cache retention in days. +- `SWC_NODE_CACHE_DIR=./path/to/cache` choose disk cache directory. - `SWC_NODE_CACHE_MEMORY_LIMIT=2000` max in-process transform entries. Programmatic cache control: diff --git a/packages/register/transform-cache.ts b/packages/register/transform-cache.ts index 0b6064903..f94aab901 100644 --- a/packages/register/transform-cache.ts +++ b/packages/register/transform-cache.ts @@ -42,7 +42,6 @@ const SWC_VERSION = readPackageVersion('@swc/core/package.json') const memoryCache = new Map() let optionsSignatureCache = new WeakMap, string>() let cacheDirectoryReady = false -let cleanupAttempted = false export function getCachedTransform(cacheKey: string): TransformCacheEntry | undefined { if (!CACHE_ENABLED) { @@ -146,42 +145,8 @@ function ensureCacheDirectory() { cacheDirectoryReady = true } - if (!cleanupAttempted) { - cleanupAttempted = true - - // Trigger cleanup only after cache is actually used, so startup work stays - // minimal for short-lived commands. - void cleanupStaleDiskCache() - } -} - -async function cleanupStaleDiskCache() { - if (!Number.isFinite(CACHE_TTL_DAYS) || CACHE_TTL_DAYS <= 0) { - return - } - - try { - const files = fs.readdirSync(CACHE_DIRECTORY) - const now = Date.now() - const maxAgeMs = CACHE_TTL_DAYS * 24 * 60 * 60 * 1000 - - // Age-based eviction keeps disk usage stable without maintaining additional metadata files. - for (const file of files) { - if (!file.endsWith('.json')) { - // Non-cache files should not be touched, and may indicate a non-standard cache setup (e.g. with a symlink). - return - } - - const fullPath = join(CACHE_DIRECTORY, file) - const ageMs = now - fs.statSync(fullPath).mtimeMs - - if (ageMs > maxAgeMs) { - fs.unlinkSync(fullPath) - } - } - } catch (error) { - debug('Failed to cleanup cache directory', error) - } + // Note that we do not attempt to clean up old cache files since we store it + // on tmpdir and we assume the OS take care of that. } function readPackageVersion(path: string): string { From f84f6845042adfddb2315eaba7edd7466695112a Mon Sep 17 00:00:00 2001 From: Arthur Fiorette Date: Fri, 13 Mar 2026 19:32:06 -0300 Subject: [PATCH 06/10] remove old test --- .../__test__/register-runtime-tuning.spec.ts | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/packages/register/__test__/register-runtime-tuning.spec.ts b/packages/register/__test__/register-runtime-tuning.spec.ts index 26f693ab9..b10c0e8bf 100644 --- a/packages/register/__test__/register-runtime-tuning.spec.ts +++ b/packages/register/__test__/register-runtime-tuning.spec.ts @@ -159,25 +159,3 @@ test.serial('skips transform for runtime js in esm mode', async (t) => { t.is(output, 'export const value = 42') t.false(transformStub.called) }) - -test.serial('can clear transform cache programmatically', (t) => { - const transformSyncStub = sinon.stub(swcCore, 'transformSync').returns({ - code: 'console.log("clear-cache")', - map: emptyMap, - }) - - const filename = uniquePath('clear-cache', 'ts') - const options = { - module: ts.ModuleKind.CommonJS, - sourceMap: true, - } - - compile('const value: number = 1', filename, options) - compile('const value: number = 1', filename, options) - t.is(transformSyncStub.callCount, 1) - - clearTransformCache({ memory: true, disk: true }) - - compile('const value: number = 1', filename, options) - t.is(transformSyncStub.callCount, 2) -}) From d86ce44a46c31f7c10a72d518734acbc532632cc Mon Sep 17 00:00:00 2001 From: Arthur Fiorette Date: Fri, 13 Mar 2026 19:43:50 -0300 Subject: [PATCH 07/10] fix unused code --- packages/register/transform-cache.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/register/transform-cache.ts b/packages/register/transform-cache.ts index f94aab901..7b1fdd262 100644 --- a/packages/register/transform-cache.ts +++ b/packages/register/transform-cache.ts @@ -29,7 +29,6 @@ const debug = debugFactory('@swc-node') const CACHE_ENABLED = isEnabled(process.env.SWC_NODE_CACHE, true) const CACHE_DIRECTORY = process.env.SWC_NODE_CACHE_DIR ?? join(tmpdir(), `swc-node-${process.getuid?.() ?? process.pid}`) -const CACHE_TTL_DAYS = Number(process.env.SWC_NODE_CACHE_TTL_DAYS ?? '7') const MEMORY_CACHE_LIMIT = Number(process.env.SWC_NODE_CACHE_MEMORY_LIMIT ?? '2000') if (!Number.isFinite(MEMORY_CACHE_LIMIT) || MEMORY_CACHE_LIMIT < 0) { @@ -182,7 +181,6 @@ export function clearTransformCache(options: { memory?: boolean; disk?: boolean } cacheDirectoryReady = false - cleanupAttempted = false } } From 7665d2964b4035cd1824b1c65df21f7a52d7fd85 Mon Sep 17 00:00:00 2001 From: Arthur Fiorette Date: Fri, 13 Mar 2026 21:03:01 -0300 Subject: [PATCH 08/10] Minify code to reduce cache size --- packages/core/index.ts | 9 ++++- .../__snapshots__/react-pragma.spec.ts.md | 16 ++------ .../__snapshots__/react-pragma.spec.ts.snap | Bin 715 -> 382 bytes .../__snapshots__/sourcemaps.spec.ts.md | 2 +- .../__snapshots__/sourcemaps.spec.ts.snap | Bin 377 -> 378 bytes .../jest/__test__/hoist-top-level.spec.ts.md | 36 +----------------- .../__test__/hoist-top-level.spec.ts.snap | Bin 1241 -> 943 bytes packages/register/transform-cache.ts | 10 ++--- 8 files changed, 19 insertions(+), 54 deletions(-) diff --git a/packages/core/index.ts b/packages/core/index.ts index c9d7fac55..2d7356611 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -61,6 +61,12 @@ function transformOption(path: string, options?: Options, jest = false): SwcOpti jest, }, }, + minify: { + compress: true, + // Keep class and function names because debuggers don't use the `names` property from the source map + mangle: false, + inlineSourcesContent: true, + }, keepClassNames: opts.keepClassNames, paths: opts.paths, baseUrl: opts.baseUrl, @@ -68,7 +74,8 @@ function transformOption(path: string, options?: Options, jest = false): SwcOpti keepImportAttributes: true, }, }, - minify: false, + // Smaller output for cache + minify: true, isModule: true, module: options?.swc?.swcrc ? undefined diff --git a/packages/integrate/__tests__/react-pragma/__snapshots__/react-pragma.spec.ts.md b/packages/integrate/__tests__/react-pragma/__snapshots__/react-pragma.spec.ts.md index b8a057dc8..e44ee185e 100644 --- a/packages/integrate/__tests__/react-pragma/__snapshots__/react-pragma.spec.ts.md +++ b/packages/integrate/__tests__/react-pragma/__snapshots__/react-pragma.spec.ts.md @@ -9,21 +9,11 @@ Generated by [AVA](https://avajs.dev). > Snapshot 1 `"use strict";␊ - const Button = ({ text })=>/*#__PURE__*/ h("div", null, text);␊ - ␊ - //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIlxuICBjb25zdCBCdXR0b24gPSAoeyB0ZXh0IH0pID0+IChcbiAgICA8ZGl2PlxuICAgICAge3RleHR9XG4gICAgPC9kaXY+XG4gIClcbiJdLCJuYW1lcyI6WyJCdXR0b24iLCJ0ZXh0IiwiZGl2Il0sIm1hcHBpbmdzIjoiO0FBQ0UsTUFBTUEsU0FBUyxDQUFDLEVBQUVDLElBQUksRUFBRSxpQkFDdEIsRUFBQ0MsYUFDRUQifQ==` + //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9` ## should transform jsx into new jsx runtime > Snapshot 1 - `"use strict";␊ - Object.defineProperty(exports, "__esModule", {␊ - value: true␊ - });␊ - const _jsxruntime = require("react/jsx-runtime");␊ - const Button = ({ text })=>/*#__PURE__*/ (0, _jsxruntime.jsx)("div", {␊ - children: text␊ - });␊ - ␊ - //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIlxuICBjb25zdCBCdXR0b24gPSAoeyB0ZXh0IH0pID0+IChcbiAgICA8ZGl2PlxuICAgICAge3RleHR9XG4gICAgPC9kaXY+XG4gIClcbiJdLCJuYW1lcyI6WyJCdXR0b24iLCJ0ZXh0IiwiZGl2Il0sIm1hcHBpbmdzIjoiOzs7OztBQUNFLE1BQU1BLFNBQVMsQ0FBQyxFQUFFQyxJQUFJLEVBQUUsaUJBQ3RCLHFCQUFDQztrQkFDRUQifQ==` + `"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),require("react/jsx-runtime");␊ + //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9` diff --git a/packages/integrate/__tests__/react-pragma/__snapshots__/react-pragma.spec.ts.snap b/packages/integrate/__tests__/react-pragma/__snapshots__/react-pragma.spec.ts.snap index bb8862a00b02ace36843d91cf3059c43cf5094fd..b92c8cb7113216a5fe2802ed39344ee998eaf350 100644 GIT binary patch literal 382 zcmV-^0fGKORzV~^pjIRv?vEHYr#<V-i4v<^dp#DCo}_Kfnjc8!DW7sDze8Wp2x zb@mh=%5=4Taa3`re9+TbUb+Rj=!< zf|F4(X^d8GECc^~$%6C}r+%Le5)6A?4=4V`l8nzdE!?Kdyw;Dc`lpR?6efq|*P}9y zEQQ~$j}6!RrfU$yK(QV|#5i0jAwgkLfm{lO+O}ph(0vhR30U^SJxMZXA09teZ3TB3 cQ&6!~IjIxty!PF1RsUg4C#8wELdT@qc_S|485S+#%Fmv#;L}$DE+(ge_@E zAmD-Ru{jMkV8tRZw_Q$y7=#P~6A5wZ2lirPW9HeunBeToGlVv`C;LC%?7iDdWB={m z`-AWM`E-Wy0J}VYm2;`bIFLimsRtUM@CZ1HICv^HK9!FSXS0E2wr8`WGFTS!5Z~uZ zzzYc}WnIOqT&`R`1dN7(i+Z;2V{c)Z-9~!&Qb>Ybn`7#gSB!dBj?K_{y@X=DIvwkY zJ-P_B6-~N|o;bB(JgE*7ZRITmTpJ(oedQ4 zq4-8pWka&qou$fmR-0KuTXEDfEVb2b4`ss|icCaaGgI`Kw~=qG)fQ}PnKq;zn}}Z1 zGVt7JGs diff --git a/packages/integrate/__tests__/sourcemaps/__snapshots__/sourcemaps.spec.ts.md b/packages/integrate/__tests__/sourcemaps/__snapshots__/sourcemaps.spec.ts.md index 706474dd7..be72301fb 100644 --- a/packages/integrate/__tests__/sourcemaps/__snapshots__/sourcemaps.spec.ts.md +++ b/packages/integrate/__tests__/sourcemaps/__snapshots__/sourcemaps.spec.ts.md @@ -9,7 +9,7 @@ Generated by [AVA](https://avajs.dev). > Snapshot 1 `Error␊ - at (/packages/integrate/__tests__/sourcemaps/sourcemaps.spec.ts:30:5)␊ + at (/packages/integrate/__tests__/sourcemaps/sourcemaps.spec.ts:30:9)␊ at Test.callFn (file:///node_modules/.pnpm/ava@6.4.1_encoding@0.1.13/node_modules/ava/lib/test.js:525:26)␊ at Test.run (file:///node_modules/.pnpm/ava@6.4.1_encoding@0.1.13/node_modules/ava/lib/test.js:534:33)␊ at Runner.runSingle (file:///node_modules/.pnpm/ava@6.4.1_encoding@0.1.13/node_modules/ava/lib/runner.js:280:33)␊ diff --git a/packages/integrate/__tests__/sourcemaps/__snapshots__/sourcemaps.spec.ts.snap b/packages/integrate/__tests__/sourcemaps/__snapshots__/sourcemaps.spec.ts.snap index 768c29bb40c9863a974a50a562ab79e5fe0bb715..35b7da592c04609f071e3d9cdbf14b77627c7c51 100644 GIT binary patch literal 378 zcmV-=0fqiSRzV$@H&d$dJYW&ouB!nAm1ubS#-6o zIwCZ^eIJVm00000000BE&^=GXFc1ddLWPjnn30gjcEC>JrUDD0E-)itVT!KFwRP** zk5cCWgf(@s-IC!O=-%kI7R&Yv;H7zB0;*4a(zYPw@RQ9-_dDU#4O z;M7Avk!1lXP?m{r!Lr^&8&pCF>k7usZRh;(U0Z}Dp9&Q5w07KNUdjJ3c literal 377 zcmV-<0fzoTRzVfe0Pt!@+?b^JfyV zZMN$*-XDty00000000BE&^=GXFc1ddLWPjnn30gjcEC>Jra~4%U0_DQ!W3PTYwFgq zBcIccu|EZVDT;tX5hJ>T)w2;8wMQ=ZZ2r<8dI>f^GmkYVa~`kKF11b z(qy5gxeK&=EeZ(m(!c8WPJ3+~o%GI+FZ*}iJAcL)V-VO4SZBADYv`5@L=E{8N+h9e zz|uoNk!1lXP?m{rytZ{E zU Snapshot 1 - `"use strict";␊ - jest.enableAutomock();␊ - jest.disableAutomock();␊ - jest.mock('./foo');␊ - jest.mock('./foo/bar', ()=>'bar');␊ - jest.deepUnmock('./foo');␊ - jest.mock('./foo').mock('./bar');␊ - const foo = 'foo';␊ - console.log(foo);␊ - jest.unmock('./bar/foo').dontMock('./bar/bar');␊ - const func = ()=>{␊ - jest.unmock('./foo');␊ - jest.mock('./bar');␊ - jest.mock('./bar/foo', ()=>'foo');␊ - jest.unmock('./foo/bar');␊ - jest.deepUnmock('./bar');␊ - jest.mock('./foo').mock('./bar');␊ - const bar = 'bar';␊ - console.log(bar);␊ - jest.unmock('./bar/foo').dontMock('./bar/bar');␊ - };␊ - const func2 = ()=>{␊ - jest.mock('./bar');␊ - jest.unmock('./foo/bar');␊ - jest.mock('./bar/foo', ()=>'foo');␊ - jest.unmock('./foo');␊ - jest.deepUnmock('./bar');␊ - jest.mock('./foo').mock('./bar');␊ - const bar = 'bar';␊ - console.log(bar);␊ - jest.unmock('./bar/foo').dontMock('./bar/bar');␊ - };␊ - ␊ - //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImplc3Quc3BlYy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJcbmNvbnN0IGZvbyA9ICdmb28nXG5jb25zb2xlLmxvZyhmb28pXG5qZXN0LmVuYWJsZUF1dG9tb2NrKClcbmplc3QuZGlzYWJsZUF1dG9tb2NrKClcbmplc3QubW9jaygnLi9mb28nKVxuamVzdC5tb2NrKCcuL2Zvby9iYXInLCAoKSA9PiAnYmFyJylcbmplc3QudW5tb2NrKCcuL2Jhci9mb28nKS5kb250TW9jaygnLi9iYXIvYmFyJylcbmplc3QuZGVlcFVubW9jaygnLi9mb28nKVxuamVzdC5tb2NrKCcuL2ZvbycpLm1vY2soJy4vYmFyJylcbmNvbnN0IGZ1bmMgPSAoKSA9PiB7XG4gIGNvbnN0IGJhciA9ICdiYXInXG4gIGNvbnNvbGUubG9nKGJhcilcbiAgamVzdC51bm1vY2soJy4vZm9vJylcbiAgamVzdC5tb2NrKCcuL2JhcicpXG4gIGplc3QubW9jaygnLi9iYXIvZm9vJywgKCkgPT4gJ2ZvbycpXG4gIGplc3QudW5tb2NrKCcuL2Zvby9iYXInKVxuICBqZXN0LnVubW9jaygnLi9iYXIvZm9vJykuZG9udE1vY2soJy4vYmFyL2JhcicpXG4gIGplc3QuZGVlcFVubW9jaygnLi9iYXInKVxuICBqZXN0Lm1vY2soJy4vZm9vJykubW9jaygnLi9iYXInKVxufVxuY29uc3QgZnVuYzIgPSAoKSA9PiB7XG4gIGNvbnN0IGJhciA9ICdiYXInXG4gIGNvbnNvbGUubG9nKGJhcilcbiAgamVzdC5tb2NrKCcuL2JhcicpXG4gIGplc3QudW5tb2NrKCcuL2Zvby9iYXInKVxuICBqZXN0Lm1vY2soJy4vYmFyL2ZvbycsICgpID0+ICdmb28nKVxuICBqZXN0LnVubW9jaygnLi9mb28nKVxuICBqZXN0LnVubW9jaygnLi9iYXIvZm9vJykuZG9udE1vY2soJy4vYmFyL2JhcicpXG4gIGplc3QuZGVlcFVubW9jaygnLi9iYXInKVxuICBqZXN0Lm1vY2soJy4vZm9vJykubW9jaygnLi9iYXInKVxufVxuIl0sIm5hbWVzIjpbImplc3QiLCJlbmFibGVBdXRvbW9jayIsImRpc2FibGVBdXRvbW9jayIsIm1vY2siLCJkZWVwVW5tb2NrIiwiZm9vIiwiY29uc29sZSIsImxvZyIsInVubW9jayIsImRvbnRNb2NrIiwiZnVuYyIsImJhciIsImZ1bmMyIl0sIm1hcHBpbmdzIjoiO0FBR0FBLEtBQUtDLGNBQWM7QUFDbkJELEtBQUtFLGVBQWU7QUFDcEJGLEtBQUtHLElBQUksQ0FBQztBQUNWSCxLQUFLRyxJQUFJLENBQUMsYUFBYSxJQUFNO0FBRTdCSCxLQUFLSSxVQUFVLENBQUM7QUFDaEJKLEtBQUtHLElBQUksQ0FBQyxTQUFTQSxJQUFJLENBQUM7QUFSeEIsTUFBTUUsTUFBTTtBQUNaQyxRQUFRQyxHQUFHLENBQUNGO0FBS1pMLEtBQUtRLE1BQU0sQ0FBQyxhQUFhQyxRQUFRLENBQUM7QUFHbEMsTUFBTUMsT0FBTztJQUdYVixLQUFLUSxNQUFNLENBQUM7SUFDWlIsS0FBS0csSUFBSSxDQUFDO0lBQ1ZILEtBQUtHLElBQUksQ0FBQyxhQUFhLElBQU07SUFDN0JILEtBQUtRLE1BQU0sQ0FBQztJQUVaUixLQUFLSSxVQUFVLENBQUM7SUFDaEJKLEtBQUtHLElBQUksQ0FBQyxTQUFTQSxJQUFJLENBQUM7SUFSeEIsTUFBTVEsTUFBTTtJQUNaTCxRQUFRQyxHQUFHLENBQUNJO0lBS1pYLEtBQUtRLE1BQU0sQ0FBQyxhQUFhQyxRQUFRLENBQUM7QUFHcEM7QUFDQSxNQUFNRyxRQUFRO0lBR1paLEtBQUtHLElBQUksQ0FBQztJQUNWSCxLQUFLUSxNQUFNLENBQUM7SUFDWlIsS0FBS0csSUFBSSxDQUFDLGFBQWEsSUFBTTtJQUM3QkgsS0FBS1EsTUFBTSxDQUFDO0lBRVpSLEtBQUtJLFVBQVUsQ0FBQztJQUNoQkosS0FBS0csSUFBSSxDQUFDLFNBQVNBLElBQUksQ0FBQztJQVJ4QixNQUFNUSxNQUFNO0lBQ1pMLFFBQVFDLEdBQUcsQ0FBQ0k7SUFLWlgsS0FBS1EsTUFBTSxDQUFDLGFBQWFDLFFBQVEsQ0FBQztBQUdwQyJ9` + `"use strict";console.log("foo"),jest.enableAutomock(),jest.disableAutomock(),jest.mock("./foo"),jest.mock("./foo/bar",()=>"bar"),jest.unmock("./bar/foo").dontMock("./bar/bar"),jest.deepUnmock("./foo"),jest.mock("./foo").mock("./bar");␊ + //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImplc3Quc3BlYy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJcbmNvbnN0IGZvbyA9ICdmb28nXG5jb25zb2xlLmxvZyhmb28pXG5qZXN0LmVuYWJsZUF1dG9tb2NrKClcbmplc3QuZGlzYWJsZUF1dG9tb2NrKClcbmplc3QubW9jaygnLi9mb28nKVxuamVzdC5tb2NrKCcuL2Zvby9iYXInLCAoKSA9PiAnYmFyJylcbmplc3QudW5tb2NrKCcuL2Jhci9mb28nKS5kb250TW9jaygnLi9iYXIvYmFyJylcbmplc3QuZGVlcFVubW9jaygnLi9mb28nKVxuamVzdC5tb2NrKCcuL2ZvbycpLm1vY2soJy4vYmFyJylcbmNvbnN0IGZ1bmMgPSAoKSA9PiB7XG4gIGNvbnN0IGJhciA9ICdiYXInXG4gIGNvbnNvbGUubG9nKGJhcilcbiAgamVzdC51bm1vY2soJy4vZm9vJylcbiAgamVzdC5tb2NrKCcuL2JhcicpXG4gIGplc3QubW9jaygnLi9iYXIvZm9vJywgKCkgPT4gJ2ZvbycpXG4gIGplc3QudW5tb2NrKCcuL2Zvby9iYXInKVxuICBqZXN0LnVubW9jaygnLi9iYXIvZm9vJykuZG9udE1vY2soJy4vYmFyL2JhcicpXG4gIGplc3QuZGVlcFVubW9jaygnLi9iYXInKVxuICBqZXN0Lm1vY2soJy4vZm9vJykubW9jaygnLi9iYXInKVxufVxuY29uc3QgZnVuYzIgPSAoKSA9PiB7XG4gIGNvbnN0IGJhciA9ICdiYXInXG4gIGNvbnNvbGUubG9nKGJhcilcbiAgamVzdC5tb2NrKCcuL2JhcicpXG4gIGplc3QudW5tb2NrKCcuL2Zvby9iYXInKVxuICBqZXN0Lm1vY2soJy4vYmFyL2ZvbycsICgpID0+ICdmb28nKVxuICBqZXN0LnVubW9jaygnLi9mb28nKVxuICBqZXN0LnVubW9jaygnLi9iYXIvZm9vJykuZG9udE1vY2soJy4vYmFyL2JhcicpXG4gIGplc3QuZGVlcFVubW9jaygnLi9iYXInKVxuICBqZXN0Lm1vY2soJy4vZm9vJykubW9jaygnLi9iYXInKVxufVxuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciLCJqZXN0IiwiZW5hYmxlQXV0b21vY2siLCJkaXNhYmxlQXV0b21vY2siLCJtb2NrIiwidW5tb2NrIiwiZG9udE1vY2siLCJkZWVwVW5tb2NrIl0sIm1hcHBpbmdzIjoiYUFFQUEsUUFBUUMsR0FBRyxDQURDLE9BRVpDLEtBQUtDLGNBQWMsR0FDbkJELEtBQUtFLGVBQWUsR0FDcEJGLEtBQUtHLElBQUksQ0FBQyxTQUNWSCxLQUFLRyxJQUFJLENBQUMsWUFBYSxJQUFNLE9BQzdCSCxLQUFLSSxNQUFNLENBQUMsYUFBYUMsUUFBUSxDQUFDLGFBQ2xDTCxLQUFLTSxVQUFVLENBQUMsU0FDaEJOLEtBQUtHLElBQUksQ0FBQyxTQUFTQSxJQUFJLENBQUMifQ==` diff --git a/packages/jest/__test__/hoist-top-level.spec.ts.snap b/packages/jest/__test__/hoist-top-level.spec.ts.snap index 20421b40baa1c7038d23f5db65628d733f9563c6..3e0314a2ee5fa3b8a993c0ea338876cb061034ce 100644 GIT binary patch literal 943 zcmV;g15o@yRzVrMnQP-CIm!Mv31eG`Q$KP};q`stkL6>>}civXoZV7e~|!*(tbw?)LgE zeGBR%ch|kTxV-zNTRj~KS=>;NyE`a*9*xsk3vJOo-%nut_M+}(ujSdjy#1!%|E|Mm zw!{9+O_DGU;9S3}TKU;c5)xuJ4QbrpFdE+?m-+8*uKYsdot0L)mXN6%TI!NkqHD9T zd9zeE2~wkk;A@cKYmwN+ki&)MwK;$nGEXrxPg37mg@#dN>``oRs^aWXF%neCixB@) zyi$f6#1Biv=R}Y4y;H0!JXtBj-<*}f>5-Y)mc|??4?IOk5pV3K62a)W-%&{U)*M;F z#w~(a4~2T))XXzCGD}Yy9=SNv`6`nT+AB5Ir4gMjM#6nKitR`)wBpIjv)USMjT_I! zaEtgMw|v@FdF@~79mOPAHvdH?oaoVDZ}W_5#ZAlaQWZvX?Pp7h-=>PSeS7+az;PdhFs97#@6F}K)G?0_W?nL|b^V#GjSUk%V RK7hNszW~peT8ZZe008_a<=y}Q literal 1241 zcmV;~1Sb1IRzVPArTT z*d@Ve&L4{i00000000BkRNHQ&RuoNJRh6RYL;t{a6HLIE31GnR z#w{3|TLU=8RUhV4rvF)~`*5+bO_FBRht`sH%sP9mz4kf>f4(!k&|Jiy{L%(mo zX`P&2{n|!9H*&TeNx?JZ_UY!SnIcvgmPC5KOeMk5}WH+A2S~Nz4s)~sKKrtbF3s+GA z+HB|9xc;aoh95@unCqt}{*u`KPmvv;pa0m3!}Q*?$9fdGfg=g*6?!Y*!=vY#dg6w` z`8*DT4~8DwZ!h228G~z6X00o|l%9ucmSEP#g`BClyr$=oLHm(sUht`TG4Rx^i9OM{Y9gX#sNyaqJg zzEgSt&23N3?=AD5+x@)^%&5>k$UD!V;6FGcV&U9QE*++vtIpZYb$b>l7n&Fp_aKlT z(Oy8VaM#G)oSM8fEvn-!irGxKH;8NLO+ zL-!*#90>4b$z;Gw$u&!H16~=wn)Gs#X+NGOTi0oA=R4X4KdxTTNhp!izil zh$Gr09Z#UoM3Rbil6%sDBf!1@>kX_o1&5=M53v)C%RT~2c3{P-J~ODDRoq&i8-pB| zePD&!$vOcqmMXi&Jd(KL(3}-Vgn1N?jz!cDGh=ujz|7ZZ&W{+(*3sxkX3aem7?$gB z7(+Mu%{|Dv(2=9X|)jfp#B5dw61TQi-IPfhq zm%Ll}t$Y`E0q)}vYGmM&7I4ghgDucJtl~9$EapM|5SOgIlhy;DF}=S5 { debug('Failed to write cache file', error) - } + }) } function ensureCacheDirectory() { From ae2d71626191cf9e2f64aa5b7662637842f218b9 Mon Sep 17 00:00:00 2001 From: Arthur Fiorette Date: Fri, 13 Mar 2026 21:11:19 -0300 Subject: [PATCH 09/10] fix option --- packages/core/index.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/core/index.ts b/packages/core/index.ts index 2d7356611..421f9930d 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -61,12 +61,7 @@ function transformOption(path: string, options?: Options, jest = false): SwcOpti jest, }, }, - minify: { - compress: true, - // Keep class and function names because debuggers don't use the `names` property from the source map - mangle: false, - inlineSourcesContent: true, - }, + minify: false, keepClassNames: opts.keepClassNames, paths: opts.paths, baseUrl: opts.baseUrl, From fac40ee73c61270e676397bfb8d7173182facbc6 Mon Sep 17 00:00:00 2001 From: Arthur Fiorette Date: Fri, 13 Mar 2026 21:22:28 -0300 Subject: [PATCH 10/10] fix minify config --- packages/core/index.ts | 1 - .../__snapshots__/react-pragma.spec.ts.md | 8 ++++---- .../__snapshots__/react-pragma.spec.ts.snap | Bin 382 -> 690 bytes .../jest/__test__/hoist-top-level.spec.ts.md | 4 ++-- .../jest/__test__/hoist-top-level.spec.ts.snap | Bin 943 -> 1244 bytes 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/core/index.ts b/packages/core/index.ts index 421f9930d..d38f8f526 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -61,7 +61,6 @@ function transformOption(path: string, options?: Options, jest = false): SwcOpti jest, }, }, - minify: false, keepClassNames: opts.keepClassNames, paths: opts.paths, baseUrl: opts.baseUrl, diff --git a/packages/integrate/__tests__/react-pragma/__snapshots__/react-pragma.spec.ts.md b/packages/integrate/__tests__/react-pragma/__snapshots__/react-pragma.spec.ts.md index e44ee185e..48132b3f2 100644 --- a/packages/integrate/__tests__/react-pragma/__snapshots__/react-pragma.spec.ts.md +++ b/packages/integrate/__tests__/react-pragma/__snapshots__/react-pragma.spec.ts.md @@ -8,12 +8,12 @@ Generated by [AVA](https://avajs.dev). > Snapshot 1 - `"use strict";␊ - //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9` + `"use strict";const Button=({text})=>h("div",null,text);␊ + //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIlxuICBjb25zdCBCdXR0b24gPSAoeyB0ZXh0IH0pID0+IChcbiAgICA8ZGl2PlxuICAgICAge3RleHR9XG4gICAgPC9kaXY+XG4gIClcbiJdLCJuYW1lcyI6WyJCdXR0b24iLCJ0ZXh0IiwiZGl2Il0sIm1hcHBpbmdzIjoiYUFDRSxNQUFNQSxPQUFTLENBQUMsQ0FBRUMsSUFBSSxDQUFFLEdBQ3RCLEVBQUNDLFdBQ0VEIn0=` ## should transform jsx into new jsx runtime > Snapshot 1 - `"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),require("react/jsx-runtime");␊ - //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9` + `"use strict";Object.defineProperty(exports,"__esModule",{value:true});const _jsxruntime=require("react/jsx-runtime");const Button=({text})=>(0,_jsxruntime.jsx)("div",{children:text});␊ + //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIlxuICBjb25zdCBCdXR0b24gPSAoeyB0ZXh0IH0pID0+IChcbiAgICA8ZGl2PlxuICAgICAge3RleHR9XG4gICAgPC9kaXY+XG4gIClcbiJdLCJuYW1lcyI6WyJCdXR0b24iLCJ0ZXh0IiwiZGl2Il0sIm1hcHBpbmdzIjoicUhBQ0UsTUFBTUEsT0FBUyxDQUFDLENBQUVDLElBQUksQ0FBRSxHQUN0QixvQkFBQ0MsZ0JBQ0VEIn0=` diff --git a/packages/integrate/__tests__/react-pragma/__snapshots__/react-pragma.spec.ts.snap b/packages/integrate/__tests__/react-pragma/__snapshots__/react-pragma.spec.ts.snap index b92c8cb7113216a5fe2802ed39344ee998eaf350..8c03308b8a9e4c19546c74eae43d2b8c3f175edf 100644 GIT binary patch literal 690 zcmV;j0!{rvRzV%YoiKI9?5g|`$ zpvc5!V#brD5{XQixxVB{uA~Ah4t9Nc8Yk|2=@P-*ScF`P&yPXiN_TSj{l&qngH0X2 zJa}{T?Xa-f5i%jZEL{1V38}zTO3s?adxUMymu?(W;=7V?R*3{>SDq{IMZJu3qdFZMYj@O0^@y)c)mVGAVLqu2 z*LoCtI&-LBv(uns)pZJl&a721Hlpd+YI)UjFddzP?HtWgU4@ZXJzobZRD-btylQ>k z>tA!6LogkOK<|K9Z-HZ74SkPX&vo_s{q%-bd)wWup5vNBamQ(lZ|Ym!QyU9+JUQNJ z>U+cpOw~vyqciH~`o$u8ap3yM>co2|6QJieh0?hGFa;oCljQ#oPK86NVDvI z*0Yf|FxwWiQCHYNgAVG7KGI;npS5hHX=XcscFj@E_7K|0YMEL9Z7^)>3^bqOFa0ro z!X#H1zT1i}MStS->XQ Y%3f&D23;`)#!viy0FTfBe}@DB0A$fiRR910 literal 382 zcmV-^0fGKORzV~^pjIRv?vEHYr#<V-i4v<^dp#DCo}_Kfnjc8!DW7sDze8Wp2x zb@mh=%5=4Taa3`re9+TbUb+Rj=!< zf|F4(X^d8GECc^~$%6C}r+%Le5)6A?4=4V`l8nzdE!?Kdyw;Dc`lpR?6efq|*P}9y zEQQ~$j}6!RrfU$yK(QV|#5i0jAwgkLfm{lO+O}ph(0vhR30U^SJxMZXA09teZ3TB3 cQ&6!~IjIxty!PF1RsU Snapshot 1 - `"use strict";console.log("foo"),jest.enableAutomock(),jest.disableAutomock(),jest.mock("./foo"),jest.mock("./foo/bar",()=>"bar"),jest.unmock("./bar/foo").dontMock("./bar/bar"),jest.deepUnmock("./foo"),jest.mock("./foo").mock("./bar");␊ - //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImplc3Quc3BlYy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJcbmNvbnN0IGZvbyA9ICdmb28nXG5jb25zb2xlLmxvZyhmb28pXG5qZXN0LmVuYWJsZUF1dG9tb2NrKClcbmplc3QuZGlzYWJsZUF1dG9tb2NrKClcbmplc3QubW9jaygnLi9mb28nKVxuamVzdC5tb2NrKCcuL2Zvby9iYXInLCAoKSA9PiAnYmFyJylcbmplc3QudW5tb2NrKCcuL2Jhci9mb28nKS5kb250TW9jaygnLi9iYXIvYmFyJylcbmplc3QuZGVlcFVubW9jaygnLi9mb28nKVxuamVzdC5tb2NrKCcuL2ZvbycpLm1vY2soJy4vYmFyJylcbmNvbnN0IGZ1bmMgPSAoKSA9PiB7XG4gIGNvbnN0IGJhciA9ICdiYXInXG4gIGNvbnNvbGUubG9nKGJhcilcbiAgamVzdC51bm1vY2soJy4vZm9vJylcbiAgamVzdC5tb2NrKCcuL2JhcicpXG4gIGplc3QubW9jaygnLi9iYXIvZm9vJywgKCkgPT4gJ2ZvbycpXG4gIGplc3QudW5tb2NrKCcuL2Zvby9iYXInKVxuICBqZXN0LnVubW9jaygnLi9iYXIvZm9vJykuZG9udE1vY2soJy4vYmFyL2JhcicpXG4gIGplc3QuZGVlcFVubW9jaygnLi9iYXInKVxuICBqZXN0Lm1vY2soJy4vZm9vJykubW9jaygnLi9iYXInKVxufVxuY29uc3QgZnVuYzIgPSAoKSA9PiB7XG4gIGNvbnN0IGJhciA9ICdiYXInXG4gIGNvbnNvbGUubG9nKGJhcilcbiAgamVzdC5tb2NrKCcuL2JhcicpXG4gIGplc3QudW5tb2NrKCcuL2Zvby9iYXInKVxuICBqZXN0Lm1vY2soJy4vYmFyL2ZvbycsICgpID0+ICdmb28nKVxuICBqZXN0LnVubW9jaygnLi9mb28nKVxuICBqZXN0LnVubW9jaygnLi9iYXIvZm9vJykuZG9udE1vY2soJy4vYmFyL2JhcicpXG4gIGplc3QuZGVlcFVubW9jaygnLi9iYXInKVxuICBqZXN0Lm1vY2soJy4vZm9vJykubW9jaygnLi9iYXInKVxufVxuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciLCJqZXN0IiwiZW5hYmxlQXV0b21vY2siLCJkaXNhYmxlQXV0b21vY2siLCJtb2NrIiwidW5tb2NrIiwiZG9udE1vY2siLCJkZWVwVW5tb2NrIl0sIm1hcHBpbmdzIjoiYUFFQUEsUUFBUUMsR0FBRyxDQURDLE9BRVpDLEtBQUtDLGNBQWMsR0FDbkJELEtBQUtFLGVBQWUsR0FDcEJGLEtBQUtHLElBQUksQ0FBQyxTQUNWSCxLQUFLRyxJQUFJLENBQUMsWUFBYSxJQUFNLE9BQzdCSCxLQUFLSSxNQUFNLENBQUMsYUFBYUMsUUFBUSxDQUFDLGFBQ2xDTCxLQUFLTSxVQUFVLENBQUMsU0FDaEJOLEtBQUtHLElBQUksQ0FBQyxTQUFTQSxJQUFJLENBQUMifQ==` + `"use strict";jest.enableAutomock();jest.disableAutomock();jest.mock("./foo");jest.mock("./foo/bar",()=>"bar");jest.deepUnmock("./foo");jest.mock("./foo").mock("./bar");const foo="foo";console.log(foo);jest.unmock("./bar/foo").dontMock("./bar/bar");const func=()=>{jest.unmock("./foo");jest.mock("./bar");jest.mock("./bar/foo",()=>"foo");jest.unmock("./foo/bar");jest.deepUnmock("./bar");jest.mock("./foo").mock("./bar");const bar="bar";console.log(bar);jest.unmock("./bar/foo").dontMock("./bar/bar")};const func2=()=>{jest.mock("./bar");jest.unmock("./foo/bar");jest.mock("./bar/foo",()=>"foo");jest.unmock("./foo");jest.deepUnmock("./bar");jest.mock("./foo").mock("./bar");const bar="bar";console.log(bar);jest.unmock("./bar/foo").dontMock("./bar/bar")};␊ + //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImplc3Quc3BlYy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJcbmNvbnN0IGZvbyA9ICdmb28nXG5jb25zb2xlLmxvZyhmb28pXG5qZXN0LmVuYWJsZUF1dG9tb2NrKClcbmplc3QuZGlzYWJsZUF1dG9tb2NrKClcbmplc3QubW9jaygnLi9mb28nKVxuamVzdC5tb2NrKCcuL2Zvby9iYXInLCAoKSA9PiAnYmFyJylcbmplc3QudW5tb2NrKCcuL2Jhci9mb28nKS5kb250TW9jaygnLi9iYXIvYmFyJylcbmplc3QuZGVlcFVubW9jaygnLi9mb28nKVxuamVzdC5tb2NrKCcuL2ZvbycpLm1vY2soJy4vYmFyJylcbmNvbnN0IGZ1bmMgPSAoKSA9PiB7XG4gIGNvbnN0IGJhciA9ICdiYXInXG4gIGNvbnNvbGUubG9nKGJhcilcbiAgamVzdC51bm1vY2soJy4vZm9vJylcbiAgamVzdC5tb2NrKCcuL2JhcicpXG4gIGplc3QubW9jaygnLi9iYXIvZm9vJywgKCkgPT4gJ2ZvbycpXG4gIGplc3QudW5tb2NrKCcuL2Zvby9iYXInKVxuICBqZXN0LnVubW9jaygnLi9iYXIvZm9vJykuZG9udE1vY2soJy4vYmFyL2JhcicpXG4gIGplc3QuZGVlcFVubW9jaygnLi9iYXInKVxuICBqZXN0Lm1vY2soJy4vZm9vJykubW9jaygnLi9iYXInKVxufVxuY29uc3QgZnVuYzIgPSAoKSA9PiB7XG4gIGNvbnN0IGJhciA9ICdiYXInXG4gIGNvbnNvbGUubG9nKGJhcilcbiAgamVzdC5tb2NrKCcuL2JhcicpXG4gIGplc3QudW5tb2NrKCcuL2Zvby9iYXInKVxuICBqZXN0Lm1vY2soJy4vYmFyL2ZvbycsICgpID0+ICdmb28nKVxuICBqZXN0LnVubW9jaygnLi9mb28nKVxuICBqZXN0LnVubW9jaygnLi9iYXIvZm9vJykuZG9udE1vY2soJy4vYmFyL2JhcicpXG4gIGplc3QuZGVlcFVubW9jaygnLi9iYXInKVxuICBqZXN0Lm1vY2soJy4vZm9vJykubW9jaygnLi9iYXInKVxufVxuIl0sIm5hbWVzIjpbImplc3QiLCJlbmFibGVBdXRvbW9jayIsImRpc2FibGVBdXRvbW9jayIsIm1vY2siLCJkZWVwVW5tb2NrIiwiZm9vIiwiY29uc29sZSIsImxvZyIsInVubW9jayIsImRvbnRNb2NrIiwiZnVuYyIsImJhciIsImZ1bmMyIl0sIm1hcHBpbmdzIjoiYUFHQUEsS0FBS0MsY0FBYyxHQUNuQkQsS0FBS0UsZUFBZSxHQUNwQkYsS0FBS0csSUFBSSxDQUFDLFNBQ1ZILEtBQUtHLElBQUksQ0FBQyxZQUFhLElBQU0sT0FFN0JILEtBQUtJLFVBQVUsQ0FBQyxTQUNoQkosS0FBS0csSUFBSSxDQUFDLFNBQVNBLElBQUksQ0FBQyxTQVJ4QixNQUFNRSxJQUFNLE1BQ1pDLFFBQVFDLEdBQUcsQ0FBQ0YsS0FLWkwsS0FBS1EsTUFBTSxDQUFDLGFBQWFDLFFBQVEsQ0FBQyxhQUdsQyxNQUFNQyxLQUFPLEtBR1hWLEtBQUtRLE1BQU0sQ0FBQyxTQUNaUixLQUFLRyxJQUFJLENBQUMsU0FDVkgsS0FBS0csSUFBSSxDQUFDLFlBQWEsSUFBTSxPQUM3QkgsS0FBS1EsTUFBTSxDQUFDLGFBRVpSLEtBQUtJLFVBQVUsQ0FBQyxTQUNoQkosS0FBS0csSUFBSSxDQUFDLFNBQVNBLElBQUksQ0FBQyxTQVJ4QixNQUFNUSxJQUFNLE1BQ1pMLFFBQVFDLEdBQUcsQ0FBQ0ksS0FLWlgsS0FBS1EsTUFBTSxDQUFDLGFBQWFDLFFBQVEsQ0FBQyxZQUdwQyxFQUNBLE1BQU1HLE1BQVEsS0FHWlosS0FBS0csSUFBSSxDQUFDLFNBQ1ZILEtBQUtRLE1BQU0sQ0FBQyxhQUNaUixLQUFLRyxJQUFJLENBQUMsWUFBYSxJQUFNLE9BQzdCSCxLQUFLUSxNQUFNLENBQUMsU0FFWlIsS0FBS0ksVUFBVSxDQUFDLFNBQ2hCSixLQUFLRyxJQUFJLENBQUMsU0FBU0EsSUFBSSxDQUFDLFNBUnhCLE1BQU1RLElBQU0sTUFDWkwsUUFBUUMsR0FBRyxDQUFDSSxLQUtaWCxLQUFLUSxNQUFNLENBQUMsYUFBYUMsUUFBUSxDQUFDLFlBR3BDIn0=` diff --git a/packages/jest/__test__/hoist-top-level.spec.ts.snap b/packages/jest/__test__/hoist-top-level.spec.ts.snap index 3e0314a2ee5fa3b8a993c0ea338876cb061034ce..fe569d3aaf63132de9af888c81e25deddb603eea 100644 GIT binary patch literal 1244 zcmV<21S9)FRzVJhORoYco2`2Hjbd{Ad*h3%~WsC<5 zcMK4N`E3RqaMg>w=^OL`woh6O*a>#*v@5mJ`ew{G-#OnoX9hmrk~niC`r$9X2#eUS zexN~C#$GSTLR$2SEbqns%8z?XpBB9&bEBT?#BoSdC#OMH&<`Iy&nX=1<)2@@_~r%s zeev~+@4o!wWxu3;j}~{KTlC*C^ogH3B=#@MB4a$SUbj^*q=(AQ|NhD8ZI<<)mQIOt z*MIZs^~L)>`?sa?{T!#yBm1u(o?4`vrL^eXX4yrbZ8y(Z?4QKh;?-@IZ5Yb5gWB+T zSz1gw)g8VvbuXB{-}c}KRCOHe4{0rSFgrx2N4+1QJno%1cNa~JJKl+N_o?20@0jO1 z?hmLs>f_TA_`KYIdwTkPk7nha>rb3K57Pynsu%3__{GWdICPyN%+k{(&C++oq5j+R zH-4?~_FP#zrclbuY^{pQnw%N6#T#pRnG-q5WA_Y|?iq-!ddRu8;&povFO;5Sl%6QR zHEYEsiMArC#>tYsBK4&pi(W$bpVPTCToQh`CVUmENwu=;fYtN4H2l?`Yn+-GrDZDA z#&FFs&o=#?TN!puUo1-(^&^*Ob}>reZaMW~MED^$dz{6%R{MBcGGZ4RpPSt&KI(@-Det`tQ&8gy%mvgNhBe?ZhB&ugqMqrh5_l!v=d>~ z%zWJ6%fQWB-Y0oC8MOHO#kCkMZf55TW#g-h+0FIwELbkG2-{6r&*9me|5awmekM)!R2CPxJmP-bzJt%? z{7?Iz#W~0^N9AM~5Oe3-6sn>UlLUrDGJrRqu3EfI{Goa?li?!UH13T}#&UQc zG7W5P&YTyht+Rgiy^^W?kV(V6BI#6nz_Gj0)L9N}ZQj|s)jSB?E0B}KTg%HVv@pCv zcuaK;0-c*si-W+bt1E=H5=CfJ$Lw1NY`v-9qsZFSU8-XUbiEoO3`Z)|02 zM^W9*L3O1f3~!i^=^!vSex}V_%ys=ZIBa^=Y29d3)UgH-o>0uekr6G9c#Q!v$4zaf zS2qYx&d|2^fZnN*>;G4#csJ9@;Y_18)A+c?1DVfzj2#2cmxbd;#XhPjurn z5I0_@5AOwrBX%D#h5+LUopKON>lUNyjK6TqBN{E{hs|Ty&i$F5fsveY7k>k}LO`nE G3;+P`mV(;= literal 943 zcmV;g15o@yRzVrMnQP-CIm!Mv31eG`Q$KP};q`stkL6>>}civXoZV7e~|!*(tbw?)LgE zeGBR%ch|kTxV-zNTRj~KS=>;NyE`a*9*xsk3vJOo-%nut_M+}(ujSdjy#1!%|E|Mm zw!{9+O_DGU;9S3}TKU;c5)xuJ4QbrpFdE+?m-+8*uKYsdot0L)mXN6%TI!NkqHD9T zd9zeE2~wkk;A@cKYmwN+ki&)MwK;$nGEXrxPg37mg@#dN>``oRs^aWXF%neCixB@) zyi$f6#1Biv=R}Y4y;H0!JXtBj-<*}f>5-Y)mc|??4?IOk5pV3K62a)W-%&{U)*M;F z#w~(a4~2T))XXzCGD}Yy9=SNv`6`nT+AB5Ir4gMjM#6nKitR`)wBpIjv)USMjT_I! zaEtgMw|v@FdF@~79mOPAHvdH?oaoVDZ}W_5#ZAlaQWZvX?Pp7h-=>PSeS7+az;PdhFs97#@6F}K)G?0_W?nL|b^V#GjSUk%V RK7hNszW~peT8ZZe008_a<=y}Q