From 350ba1055f15769abdb3aff801ecbf8ed3dde5f8 Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Fri, 16 Dec 2022 15:59:08 +0800 Subject: [PATCH 01/13] feat --- packages/babel-core/package.json | 3 +- .../src/config/files/configuration.ts | 20 ++- .../src/config/files/module-types.ts | 69 ++++++--- .../babel-core/src/config/files/plugins.ts | 4 +- packages/babel-core/test/config-ts.js | 70 +++++++++ .../invalid-cts-register/babel.config.cts | 2 + .../simple-cts-with-ts-node/babel.config.cts | 2 + .../config-ts/simple-cts/babel.config.cts | 2 + yarn.lock | 146 +++++++++++++++++- 9 files changed, 288 insertions(+), 30 deletions(-) create mode 100644 packages/babel-core/test/config-ts.js create mode 100644 packages/babel-core/test/fixtures/config-ts/invalid-cts-register/babel.config.cts create mode 100644 packages/babel-core/test/fixtures/config-ts/simple-cts-with-ts-node/babel.config.cts create mode 100644 packages/babel-core/test/fixtures/config-ts/simple-cts/babel.config.cts diff --git a/packages/babel-core/package.json b/packages/babel-core/package.json index 4baf42a83075..83ae6a7fce3e 100644 --- a/packages/babel-core/package.json +++ b/packages/babel-core/package.json @@ -74,7 +74,8 @@ "@types/gensync": "^1.0.0", "@types/resolve": "^1.3.2", "@types/semver": "^5.4.0", - "rimraf": "^3.0.0" + "rimraf": "^3.0.0", + "ts-node": "^10.9.1" }, "conditions": { "BABEL_8_BREAKING": [ diff --git a/packages/babel-core/src/config/files/configuration.ts b/packages/babel-core/src/config/files/configuration.ts index d74eca86a733..c6c8370405c9 100644 --- a/packages/babel-core/src/config/files/configuration.ts +++ b/packages/babel-core/src/config/files/configuration.ts @@ -9,7 +9,7 @@ import type { CacheConfigurator } from "../caching"; import { makeConfigAPI } from "../helpers/config-api"; import type { ConfigAPI } from "../helpers/config-api"; import { makeStaticFileCache } from "./utils"; -import loadCjsOrMjsDefault from "./module-types"; +import loadCodeDefault from "./module-types"; import pathPatternToRegex from "../pattern-to-regex"; import type { FilePackageData, RelativeConfig, ConfigFile } from "./types"; import type { CallerMetadata } from "../validation/options"; @@ -28,6 +28,7 @@ export const ROOT_CONFIG_FILENAMES = [ "babel.config.cjs", "babel.config.mjs", "babel.config.json", + "babel.config.cts", ]; const RELATIVE_CONFIG_FILENAMES = [ ".babelrc", @@ -35,13 +36,14 @@ const RELATIVE_CONFIG_FILENAMES = [ ".babelrc.cjs", ".babelrc.mjs", ".babelrc.json", + ".babelrc.cts", ]; const BABELIGNORE_FILENAME = ".babelignore"; const LOADING_CONFIGS = new Set(); -const readConfigJS = makeStrongCache(function* readConfigJS( +const readConfigCode = makeStrongCache(function* readConfigCode( filepath: string, cache: CacheConfigurator<{ envName: string; @@ -70,7 +72,7 @@ const readConfigJS = makeStrongCache(function* readConfigJS( let options: unknown; try { LOADING_CONFIGS.add(filepath); - options = yield* loadCjsOrMjsDefault( + options = yield* loadCodeDefault( filepath, "You appear to be using a native ECMAScript module configuration " + "file, which is only supported when running Babel asynchronously.", @@ -313,9 +315,15 @@ function readConfig( caller: CallerMetadata | undefined, ): Handler { const ext = path.extname(filepath); - return ext === ".js" || ext === ".cjs" || ext === ".mjs" - ? readConfigJS(filepath, { envName, caller }) - : readConfigJSON5(filepath); + switch (ext) { + case ".js": + case ".cjs": + case ".mjs": + case ".cts": + return readConfigCode(filepath, { envName, caller }); + default: + return readConfigJSON5(filepath); + } } export function* resolveShowConfigPath( diff --git a/packages/babel-core/src/config/files/module-types.ts b/packages/babel-core/src/config/files/module-types.ts index ab662927fda0..5202ead5b91a 100644 --- a/packages/babel-core/src/config/files/module-types.ts +++ b/packages/babel-core/src/config/files/module-types.ts @@ -3,11 +3,15 @@ import type { Handler } from "gensync"; import path from "path"; import { pathToFileURL } from "url"; import { createRequire } from "module"; +import fs from "fs"; import semver from "semver"; import { endHiddenCallStack } from "../../errors/rewrite-stack-trace"; import ConfigError from "../../errors/config-error"; +import { transformSync } from "../../transform"; +import type { InputOptions } from ".."; + const require = createRequire(import.meta.url); let import_: ((specifier: string | URL) => any) | undefined; @@ -23,38 +27,64 @@ export const supportsESM = semver.satisfies( "^12.17 || >=13.2", ); -export default function* loadCjsOrMjsDefault( +export default function* loadCodeDefault( filepath: string, asyncError: string, // TODO(Babel 8): Remove this fallbackToTranspiledModule: boolean = false, ): Handler { - switch (guessJSModuleType(filepath)) { - case "cjs": + switch (path.extname(filepath)) { + case ".cjs": return loadCjsDefault(filepath, fallbackToTranspiledModule); - case "unknown": + case ".mjs": + break; + case ".cts": + return loadCtsDefault(filepath); + default: try { return loadCjsDefault(filepath, fallbackToTranspiledModule); } catch (e) { if (e.code !== "ERR_REQUIRE_ESM") throw e; } - // fall through - case "mjs": - if (yield* isAsync()) { - return yield* waitFor(loadMjsDefault(filepath)); - } - throw new ConfigError(asyncError, filepath); } + if (yield* isAsync()) { + return yield* waitFor(loadMjsDefault(filepath)); + } + throw new ConfigError(asyncError, filepath); } -function guessJSModuleType(filename: string): "cjs" | "mjs" | "unknown" { - switch (path.extname(filename)) { - case ".cjs": - return "cjs"; - case ".mjs": - return "mjs"; - default: - return "unknown"; +function loadCtsDefault(filepath: string) { + const ext = ".cts"; + const hasTsSupport = !!( + require.extensions[".ts"] || + require.extensions[".cts"] || + require.extensions[".mts"] + ); + if (!hasTsSupport) { + const code = fs.readFileSync(filepath, "utf8"); + const opts: InputOptions = { + babelrc: false, + configFile: false, + filename: path.basename(filepath), + sourceType: "script", + sourceMaps: "inline", + presets: ["@babel/preset-typescript"], + }; + const result = transformSync(code, opts); + require.extensions[ext] = function (m, filename) { + if (filename === filepath) { + // @ts-expect-error Undocumented API + return m._compile(result.code, filename); + } + return require.extensions[".js"](m, filename); + }; + } + try { + return endHiddenCallStack(require)(filepath); + } finally { + if (!hasTsSupport) { + delete require.extensions[ext]; + } } } @@ -69,8 +99,7 @@ function loadCjsDefault(filepath: string, fallbackToTranspiledModule: boolean) { async function loadMjsDefault(filepath: string) { if (!import_) { throw new ConfigError( - "Internal error: Native ECMAScript modules aren't supported" + - " by this platform.\n", + "Internal error: Native ECMAScript modules aren't supported by this platform.\n", filepath, ); } diff --git a/packages/babel-core/src/config/files/plugins.ts b/packages/babel-core/src/config/files/plugins.ts index ae9a70f230ca..9a7b4b64411e 100644 --- a/packages/babel-core/src/config/files/plugins.ts +++ b/packages/babel-core/src/config/files/plugins.ts @@ -6,7 +6,7 @@ import buildDebug from "debug"; import path from "path"; import gensync, { type Handler } from "gensync"; import { isAsync } from "../../gensync-utils/async"; -import loadCjsOrMjsDefault, { supportsESM } from "./module-types"; +import loadCodeDefault, { supportsESM } from "./module-types"; import { fileURLToPath, pathToFileURL } from "url"; import importMetaResolve from "./import-meta-resolve"; @@ -217,7 +217,7 @@ function* requireModule(type: string, name: string): Handler { if (!process.env.BABEL_8_BREAKING) { LOADING_MODULES.add(name); } - return yield* loadCjsOrMjsDefault( + return yield* loadCodeDefault( name, `You appear to be using a native ECMAScript module ${type}, ` + "which is only supported when running Babel asynchronously.", diff --git a/packages/babel-core/test/config-ts.js b/packages/babel-core/test/config-ts.js new file mode 100644 index 000000000000..50675dd35f0f --- /dev/null +++ b/packages/babel-core/test/config-ts.js @@ -0,0 +1,70 @@ +import { loadPartialConfigSync } from "../lib/index.js"; +import path from "path"; +import { fileURLToPath } from "url"; +import { createRequire } from "module"; +import { register } from "ts-node"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const require = createRequire(import.meta.url); + +describe("@babel/core config with ts", () => { + it("should work with simple .cts", () => { + const config = loadPartialConfigSync({ + configFile: path.join( + __dirname, + "fixtures/config-ts/simple-cts/babel.config.cts", + ), + }); + + expect(config.options.targets).toMatchInlineSnapshot(` + Object { + "node": "12.0.0", + } + `); + }); + + it("should throw with invalid .ts register", () => { + require.extensions[".ts"] = () => { + throw new Error("Not support .ts."); + }; + expect(() => { + loadPartialConfigSync({ + configFile: path.join( + __dirname, + "fixtures/config-ts/invalid-cts-register/babel.config.cts", + ), + }); + }).toThrowErrorMatchingInlineSnapshot(`"Unexpected identifier 'config'"`); + delete require.extensions[".ts"]; + }); + + it("should work with ts-node", () => { + const service = register({ + experimentalResolver: true, + compilerOptions: { + module: "CommonJS", + }, + }); + service.enabled(true); + + require(path.join( + __dirname, + "fixtures/config-ts/simple-cts-with-ts-node/babel.config.cts", + )); + + const config = loadPartialConfigSync({ + configFile: path.join( + __dirname, + "fixtures/config-ts/simple-cts-with-ts-node/babel.config.cts", + ), + }); + + service.enabled(false); + + expect(config.options.targets).toMatchInlineSnapshot(` + Object { + "node": "12.0.0", + } + `); + }); +}); diff --git a/packages/babel-core/test/fixtures/config-ts/invalid-cts-register/babel.config.cts b/packages/babel-core/test/fixtures/config-ts/invalid-cts-register/babel.config.cts new file mode 100644 index 000000000000..9817b4f090cd --- /dev/null +++ b/packages/babel-core/test/fixtures/config-ts/invalid-cts-register/babel.config.cts @@ -0,0 +1,2 @@ +type config = any; +module.exports = { targets: "node 12.0.0" } as config; diff --git a/packages/babel-core/test/fixtures/config-ts/simple-cts-with-ts-node/babel.config.cts b/packages/babel-core/test/fixtures/config-ts/simple-cts-with-ts-node/babel.config.cts new file mode 100644 index 000000000000..9817b4f090cd --- /dev/null +++ b/packages/babel-core/test/fixtures/config-ts/simple-cts-with-ts-node/babel.config.cts @@ -0,0 +1,2 @@ +type config = any; +module.exports = { targets: "node 12.0.0" } as config; diff --git a/packages/babel-core/test/fixtures/config-ts/simple-cts/babel.config.cts b/packages/babel-core/test/fixtures/config-ts/simple-cts/babel.config.cts new file mode 100644 index 000000000000..9817b4f090cd --- /dev/null +++ b/packages/babel-core/test/fixtures/config-ts/simple-cts/babel.config.cts @@ -0,0 +1,2 @@ +type config = any; +module.exports = { targets: "node 12.0.0" } as config; diff --git a/yarn.lock b/yarn.lock index 38d0d3bad13d..8dca4e9201a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -369,6 +369,7 @@ __metadata: json5: ^2.2.2 rimraf: ^3.0.0 semver: "condition:BABEL_8_BREAKING ? ^7.3.4 : ^6.3.0" + ts-node: ^10.9.1 languageName: unknown linkType: soft @@ -3851,6 +3852,15 @@ __metadata: languageName: node linkType: hard +"@cspotcode/source-map-support@npm:^0.8.0": + version: 0.8.1 + resolution: "@cspotcode/source-map-support@npm:0.8.1" + dependencies: + "@jridgewell/trace-mapping": 0.3.9 + checksum: 5718f267085ed8edb3e7ef210137241775e607ee18b77d95aa5bd7514f47f5019aa2d82d96b3bf342ef7aa890a346fa1044532ff7cc3009e7d24fce3ce6200fa + languageName: node + linkType: hard + "@discoveryjs/json-ext@npm:^0.5.0": version: 0.5.2 resolution: "@discoveryjs/json-ext@npm:0.5.2" @@ -4162,7 +4172,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/resolve-uri@npm:3.1.0": +"@jridgewell/resolve-uri@npm:3.1.0, @jridgewell/resolve-uri@npm:^3.0.3": version: 3.1.0 resolution: "@jridgewell/resolve-uri@npm:3.1.0" checksum: b5ceaaf9a110fcb2780d1d8f8d4a0bfd216702f31c988d8042e5f8fbe353c55d9b0f55a1733afdc64806f8e79c485d2464680ac48a0d9fcadb9548ee6b81d267 @@ -4193,6 +4203,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/trace-mapping@npm:0.3.9": + version: 0.3.9 + resolution: "@jridgewell/trace-mapping@npm:0.3.9" + dependencies: + "@jridgewell/resolve-uri": ^3.0.3 + "@jridgewell/sourcemap-codec": ^1.4.10 + checksum: d89597752fd88d3f3480845691a05a44bd21faac18e2185b6f436c3b0fd0c5a859fbbd9aaa92050c4052caf325ad3e10e2e1d1b64327517471b7d51babc0ddef + languageName: node + linkType: hard + "@jridgewell/trace-mapping@npm:^0.3.0, @jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.14, @jridgewell/trace-mapping@npm:^0.3.15, @jridgewell/trace-mapping@npm:^0.3.8, @jridgewell/trace-mapping@npm:^0.3.9": version: 0.3.17 resolution: "@jridgewell/trace-mapping@npm:0.3.17" @@ -4395,6 +4415,34 @@ __metadata: languageName: node linkType: hard +"@tsconfig/node10@npm:^1.0.7": + version: 1.0.9 + resolution: "@tsconfig/node10@npm:1.0.9" + checksum: a33ae4dc2a621c0678ac8ac4bceb8e512ae75dac65417a2ad9b022d9b5411e863c4c198b6ba9ef659e14b9fb609bbec680841a2e84c1172df7a5ffcf076539df + languageName: node + linkType: hard + +"@tsconfig/node12@npm:^1.0.7": + version: 1.0.11 + resolution: "@tsconfig/node12@npm:1.0.11" + checksum: 5ce29a41b13e7897a58b8e2df11269c5395999e588b9a467386f99d1d26f6c77d1af2719e407621412520ea30517d718d5192a32403b8dfcc163bf33e40a338a + languageName: node + linkType: hard + +"@tsconfig/node14@npm:^1.0.0": + version: 1.0.3 + resolution: "@tsconfig/node14@npm:1.0.3" + checksum: 19275fe80c4c8d0ad0abed6a96dbf00642e88b220b090418609c4376e1cef81bf16237bf170ad1b341452feddb8115d8dd2e5acdfdea1b27422071163dc9ba9d + languageName: node + linkType: hard + +"@tsconfig/node16@npm:^1.0.2": + version: 1.0.3 + resolution: "@tsconfig/node16@npm:1.0.3" + checksum: 3a8b657dd047495b7ad23437d6afd20297ce90380ff0bdee93fc7d39a900dbd8d9e26e53ff6b465e7967ce2adf0b218782590ce9013285121e6a5928fbd6819f + languageName: node + linkType: hard + "@types/babel__core@link:./nope::locator=babel%40workspace%3A.": version: 0.0.0-use.local resolution: "@types/babel__core@link:./nope::locator=babel%40workspace%3A." @@ -5225,6 +5273,13 @@ __metadata: languageName: node linkType: hard +"acorn-walk@npm:^8.1.1": + version: 8.2.0 + resolution: "acorn-walk@npm:8.2.0" + checksum: 1715e76c01dd7b2d4ca472f9c58968516a4899378a63ad5b6c2d668bba8da21a71976c14ec5f5b75f887b6317c4ae0b897ab141c831d741dc76024d8745f1ad1 + languageName: node + linkType: hard + "acorn@npm:^4.0.3": version: 4.0.13 resolution: "acorn@npm:4.0.13" @@ -5261,6 +5316,15 @@ __metadata: languageName: node linkType: hard +"acorn@npm:^8.4.1": + version: 8.8.1 + resolution: "acorn@npm:8.8.1" + bin: + acorn: bin/acorn + checksum: 4079b67283b94935157698831967642f24a075c52ce3feaaaafe095776dfbe15d86a1b33b1e53860fc0d062ed6c83f4284a5c87c85b9ad51853a01173da6097f + languageName: node + linkType: hard + "acorn@npm:^8.5.0, acorn@npm:^8.7.0, acorn@npm:^8.7.1, acorn@npm:^8.8.0": version: 8.8.0 resolution: "acorn@npm:8.8.0" @@ -5494,6 +5558,13 @@ __metadata: languageName: node linkType: hard +"arg@npm:^4.1.0": + version: 4.1.3 + resolution: "arg@npm:4.1.3" + checksum: 544af8dd3f60546d3e4aff084d451b96961d2267d668670199692f8d054f0415d86fc5497d0e641e91546f0aa920e7c29e5250e99fc89f5552a34b5d93b77f43 + languageName: node + linkType: hard + "argparse@npm:^1.0.7": version: 1.0.10 resolution: "argparse@npm:1.0.10" @@ -7133,6 +7204,13 @@ __metadata: languageName: node linkType: hard +"create-require@npm:^1.1.0": + version: 1.1.1 + resolution: "create-require@npm:1.1.1" + checksum: a9a1503d4390d8b59ad86f4607de7870b39cad43d929813599a23714831e81c520bddf61bcdd1f8e30f05fd3a2b71ae8538e946eb2786dc65c2bbc520f692eff + languageName: node + linkType: hard + "cross-spawn@npm:^5.0.1": version: 5.1.0 resolution: "cross-spawn@npm:5.1.0" @@ -7412,6 +7490,13 @@ __metadata: languageName: node linkType: hard +"diff@npm:^4.0.1": + version: 4.0.2 + resolution: "diff@npm:4.0.2" + checksum: f2c09b0ce4e6b301c221addd83bf3f454c0bc00caa3dd837cf6c127d6edf7223aa2bbe3b688feea110b7f262adbfc845b757c44c8a9f8c0c5b15d8fa9ce9d20d + languageName: node + linkType: hard + "diffie-hellman@npm:^5.0.0": version: 5.0.3 resolution: "diffie-hellman@npm:5.0.3" @@ -11270,6 +11355,13 @@ fsevents@^1.2.7: languageName: node linkType: hard +"make-error@npm:^1.1.1": + version: 1.3.6 + resolution: "make-error@npm:1.3.6" + checksum: b86e5e0e25f7f777b77fabd8e2cbf15737972869d852a22b7e73c17623928fccb826d8e46b9951501d3f20e51ad74ba8c59ed584f610526a48f8ccf88aaec402 + languageName: node + linkType: hard + "make-iterator@npm:^1.0.0": version: 1.0.1 resolution: "make-iterator@npm:1.0.1" @@ -14619,6 +14711,44 @@ fsevents@^1.2.7: languageName: node linkType: hard +"ts-node@npm:^10.9.1": + version: 10.9.1 + resolution: "ts-node@npm:10.9.1" + dependencies: + "@cspotcode/source-map-support": ^0.8.0 + "@tsconfig/node10": ^1.0.7 + "@tsconfig/node12": ^1.0.7 + "@tsconfig/node14": ^1.0.0 + "@tsconfig/node16": ^1.0.2 + acorn: ^8.4.1 + acorn-walk: ^8.1.1 + arg: ^4.1.0 + create-require: ^1.1.0 + diff: ^4.0.1 + make-error: ^1.1.1 + v8-compile-cache-lib: ^3.0.1 + yn: 3.1.1 + peerDependencies: + "@swc/core": ">=1.2.50" + "@swc/wasm": ">=1.2.50" + "@types/node": "*" + typescript: ">=2.7" + peerDependenciesMeta: + "@swc/core": + optional: true + "@swc/wasm": + optional: true + bin: + ts-node: dist/bin.js + ts-node-cwd: dist/bin-cwd.js + ts-node-esm: dist/bin-esm.js + ts-node-script: dist/bin-script.js + ts-node-transpile-only: dist/bin-transpile.js + ts-script: dist/bin-script-deprecated.js + checksum: 090adff1302ab20bd3486e6b4799e90f97726ed39e02b39e566f8ab674fd5bd5f727f43615debbfc580d33c6d9d1c6b1b3ce7d8e3cca3e20530a145ffa232c35 + languageName: node + linkType: hard + "tsconfig-paths@npm:^3.14.1": version: 3.14.1 resolution: "tsconfig-paths@npm:3.14.1" @@ -15055,6 +15185,13 @@ fsevents@^1.2.7: languageName: node linkType: hard +"v8-compile-cache-lib@npm:^3.0.1": + version: 3.0.1 + resolution: "v8-compile-cache-lib@npm:3.0.1" + checksum: 78089ad549e21bcdbfca10c08850022b22024cdcc2da9b168bcf5a73a6ed7bf01a9cebb9eac28e03cd23a684d81e0502797e88f3ccd27a32aeab1cfc44c39da0 + languageName: node + linkType: hard + "v8-compile-cache@npm:^2.0.3": version: 2.2.0 resolution: "v8-compile-cache@npm:2.2.0" @@ -15700,6 +15837,13 @@ fsevents@^1.2.7: languageName: node linkType: hard +"yn@npm:3.1.1": + version: 3.1.1 + resolution: "yn@npm:3.1.1" + checksum: 2c487b0e149e746ef48cda9f8bad10fc83693cd69d7f9dcd8be4214e985de33a29c9e24f3c0d6bcf2288427040a8947406ab27f7af67ee9456e6b84854f02dd6 + languageName: node + linkType: hard + "yocto-queue@npm:^0.1.0": version: 0.1.0 resolution: "yocto-queue@npm:0.1.0" From 40b5f2b1e6b414d68119661f0b07523ca66ec011 Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Fri, 16 Dec 2022 16:11:00 +0800 Subject: [PATCH 02/13] yarn dedupe --- yarn.lock | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8dca4e9201a2..99516d1cc6bc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5316,7 +5316,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.4.1": +"acorn@npm:^8.4.1, acorn@npm:^8.5.0, acorn@npm:^8.7.0, acorn@npm:^8.7.1, acorn@npm:^8.8.0": version: 8.8.1 resolution: "acorn@npm:8.8.1" bin: @@ -5325,15 +5325,6 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.5.0, acorn@npm:^8.7.0, acorn@npm:^8.7.1, acorn@npm:^8.8.0": - version: 8.8.0 - resolution: "acorn@npm:8.8.0" - bin: - acorn: bin/acorn - checksum: 7270ca82b242eafe5687a11fea6e088c960af712683756abf0791b68855ea9cace3057bd5e998ffcef50c944810c1e0ca1da526d02b32110e13c722aa959afdc - languageName: node - linkType: hard - "aggregate-error@npm:^3.0.0": version: 3.0.1 resolution: "aggregate-error@npm:3.0.1" From 25d0facbe22486fa75e8975c1ea17e350719ce49 Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Fri, 16 Dec 2022 16:21:19 +0800 Subject: [PATCH 03/13] fix test --- packages/babel-core/test/config-ts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/babel-core/test/config-ts.js b/packages/babel-core/test/config-ts.js index 50675dd35f0f..d7643802bba2 100644 --- a/packages/babel-core/test/config-ts.js +++ b/packages/babel-core/test/config-ts.js @@ -34,7 +34,7 @@ describe("@babel/core config with ts", () => { "fixtures/config-ts/invalid-cts-register/babel.config.cts", ), }); - }).toThrowErrorMatchingInlineSnapshot(`"Unexpected identifier 'config'"`); + }).toThrow(/Unexpected identifier.*/); delete require.extensions[".ts"]; }); From 0aae8bd05c02958e685fdb4cb151ee83c860c61b Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Thu, 22 Dec 2022 23:04:42 +0800 Subject: [PATCH 04/13] review --- packages/babel-core/package.json | 8 ++++++++ packages/babel-core/src/config/files/module-types.ts | 12 +++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/babel-core/package.json b/packages/babel-core/package.json index 83ae6a7fce3e..3ee9edb032b6 100644 --- a/packages/babel-core/package.json +++ b/packages/babel-core/package.json @@ -77,6 +77,14 @@ "rimraf": "^3.0.0", "ts-node": "^10.9.1" }, + "peerDependencies": { + "@babel/preset-typescript": "^7.0.0" + }, + "peerDependenciesMeta": { + "@babel/preset-typescript": { + "optional": true + } + }, "conditions": { "BABEL_8_BREAKING": [ null, diff --git a/packages/babel-core/src/config/files/module-types.ts b/packages/babel-core/src/config/files/module-types.ts index 5202ead5b91a..909ac44637d8 100644 --- a/packages/babel-core/src/config/files/module-types.ts +++ b/packages/babel-core/src/config/files/module-types.ts @@ -68,7 +68,17 @@ function loadCtsDefault(filepath: string) { filename: path.basename(filepath), sourceType: "script", sourceMaps: "inline", - presets: ["@babel/preset-typescript"], + presets: [ + [ + "@babel/preset-typescript", + { + allowDeclareFields: true, + disallowAmbiguousJSXLike: true, + onlyRemoveTypeImports: true, + optimizeConstEnums: true, + }, + ], + ], }; const result = transformSync(code, opts); require.extensions[ext] = function (m, filename) { From 8459ad76d186aac80b6138018d7bb3e462a00e1b Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Tue, 3 Jan 2023 23:28:59 +0800 Subject: [PATCH 05/13] yarn.lock --- yarn.lock | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/yarn.lock b/yarn.lock index 99516d1cc6bc..48a4c81efe89 100644 --- a/yarn.lock +++ b/yarn.lock @@ -370,6 +370,11 @@ __metadata: rimraf: ^3.0.0 semver: "condition:BABEL_8_BREAKING ? ^7.3.4 : ^6.3.0" ts-node: ^10.9.1 + peerDependencies: + "@babel/preset-typescript": ^7.0.0 + peerDependenciesMeta: + "@babel/preset-typescript": + optional: true languageName: unknown linkType: soft From e3955153573c150729d994aa9b3fa2376ba06a78 Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Wed, 4 Jan 2023 00:35:25 +0800 Subject: [PATCH 06/13] fix --- packages/babel-core/src/config/files/module-types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/babel-core/src/config/files/module-types.ts b/packages/babel-core/src/config/files/module-types.ts index 909ac44637d8..d9a43822eba7 100644 --- a/packages/babel-core/src/config/files/module-types.ts +++ b/packages/babel-core/src/config/files/module-types.ts @@ -74,6 +74,7 @@ function loadCtsDefault(filepath: string) { { allowDeclareFields: true, disallowAmbiguousJSXLike: true, + allExtensions: true, onlyRemoveTypeImports: true, optimizeConstEnums: true, }, From 8a719760e1ff68616e9ac48ca2a927e190a83f50 Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Wed, 4 Jan 2023 19:24:05 +0800 Subject: [PATCH 07/13] fix --- .../src/config/files/module-types.ts | 21 ++++++--- packages/babel-core/test/config-ts.js | 46 ++++++++++--------- 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/packages/babel-core/src/config/files/module-types.ts b/packages/babel-core/src/config/files/module-types.ts index d9a43822eba7..dae2dd3360c0 100644 --- a/packages/babel-core/src/config/files/module-types.ts +++ b/packages/babel-core/src/config/files/module-types.ts @@ -71,13 +71,20 @@ function loadCtsDefault(filepath: string) { presets: [ [ "@babel/preset-typescript", - { - allowDeclareFields: true, - disallowAmbiguousJSXLike: true, - allExtensions: true, - onlyRemoveTypeImports: true, - optimizeConstEnums: true, - }, + process.env.BABEL_8_BREAKING + ? { + disallowAmbiguousJSXLike: true, + allExtensions: true, + onlyRemoveTypeImports: true, + optimizeConstEnums: true, + } + : { + allowDeclareFields: true, + disallowAmbiguousJSXLike: true, + allExtensions: true, + onlyRemoveTypeImports: true, + optimizeConstEnums: true, + }, ], ], }; diff --git a/packages/babel-core/test/config-ts.js b/packages/babel-core/test/config-ts.js index d7643802bba2..f22c574ec308 100644 --- a/packages/babel-core/test/config-ts.js +++ b/packages/babel-core/test/config-ts.js @@ -2,7 +2,7 @@ import { loadPartialConfigSync } from "../lib/index.js"; import path from "path"; import { fileURLToPath } from "url"; import { createRequire } from "module"; -import { register } from "ts-node"; +import semver from "semver"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const require = createRequire(import.meta.url); @@ -38,33 +38,35 @@ describe("@babel/core config with ts", () => { delete require.extensions[".ts"]; }); - it("should work with ts-node", () => { - const service = register({ - experimentalResolver: true, - compilerOptions: { - module: "CommonJS", - }, - }); - service.enabled(true); + semver.gte(process.version, "12.0.0") + ? it + : it.skip("should work with ts-node", async () => { + const service = import("ts-node").register({ + experimentalResolver: true, + compilerOptions: { + module: "CommonJS", + }, + }); + service.enabled(true); - require(path.join( - __dirname, - "fixtures/config-ts/simple-cts-with-ts-node/babel.config.cts", - )); + require(path.join( + __dirname, + "fixtures/config-ts/simple-cts-with-ts-node/babel.config.cts", + )); - const config = loadPartialConfigSync({ - configFile: path.join( - __dirname, - "fixtures/config-ts/simple-cts-with-ts-node/babel.config.cts", - ), - }); + const config = loadPartialConfigSync({ + configFile: path.join( + __dirname, + "fixtures/config-ts/simple-cts-with-ts-node/babel.config.cts", + ), + }); - service.enabled(false); + service.enabled(false); - expect(config.options.targets).toMatchInlineSnapshot(` + expect(config.options.targets).toMatchInlineSnapshot(` Object { "node": "12.0.0", } `); - }); + }); }); From e90dd4735f0768169b11eda349230b61df5ab48c Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Fri, 13 Jan 2023 00:38:41 +0800 Subject: [PATCH 08/13] fix test --- packages/babel-core/test/config-ts.js | 66 +++++++++++++++------------ 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/packages/babel-core/test/config-ts.js b/packages/babel-core/test/config-ts.js index f22c574ec308..77d389d32982 100644 --- a/packages/babel-core/test/config-ts.js +++ b/packages/babel-core/test/config-ts.js @@ -7,41 +7,51 @@ import semver from "semver"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const require = createRequire(import.meta.url); -describe("@babel/core config with ts", () => { - it("should work with simple .cts", () => { - const config = loadPartialConfigSync({ - configFile: path.join( - __dirname, - "fixtures/config-ts/simple-cts/babel.config.cts", - ), - }); +// We skip older versions of node testing for two reasons. +// 1. ts-node does not support the old version of node. +// 2. In the old version of node, jest has been registered in `require.extensions`, which will cause babel to disable the transforming as expected. - expect(config.options.targets).toMatchInlineSnapshot(` +describe("@babel/core config with ts [dummy]", () => { + it("dummy", () => { + expect(1).toBe(1); + }); +}); + +semver.gte(process.version, "12.0.0") + ? describe + : describe.skip("@babel/core config with ts", () => { + it("should work with simple .cts", () => { + const config = loadPartialConfigSync({ + configFile: path.join( + __dirname, + "fixtures/config-ts/simple-cts/babel.config.cts", + ), + }); + + expect(config.options.targets).toMatchInlineSnapshot(` Object { "node": "12.0.0", } `); - }); + }); - it("should throw with invalid .ts register", () => { - require.extensions[".ts"] = () => { - throw new Error("Not support .ts."); - }; - expect(() => { - loadPartialConfigSync({ - configFile: path.join( - __dirname, - "fixtures/config-ts/invalid-cts-register/babel.config.cts", - ), + it("should throw with invalid .ts register", () => { + require.extensions[".ts"] = () => { + throw new Error("Not support .ts."); + }; + expect(() => { + loadPartialConfigSync({ + configFile: path.join( + __dirname, + "fixtures/config-ts/invalid-cts-register/babel.config.cts", + ), + }); + }).toThrow(/Unexpected identifier.*/); + delete require.extensions[".ts"]; }); - }).toThrow(/Unexpected identifier.*/); - delete require.extensions[".ts"]; - }); - semver.gte(process.version, "12.0.0") - ? it - : it.skip("should work with ts-node", async () => { - const service = import("ts-node").register({ + it("should work with ts-node", async () => { + const service = eval("import('ts-node')").register({ experimentalResolver: true, compilerOptions: { module: "CommonJS", @@ -69,4 +79,4 @@ describe("@babel/core config with ts", () => { } `); }); -}); + }); From f7689265f2d1630d4faee16d67e22737646872f5 Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Thu, 9 Feb 2023 01:14:18 +0800 Subject: [PATCH 09/13] review --- .../src/config/files/module-types.ts | 61 ++++++++------ .../babel-core/src/errors/config-error.ts | 4 +- .../src/errors/rewrite-stack-trace.ts | 22 +++--- packages/babel-core/test/config-ts.js | 79 +++++++++++-------- 4 files changed, 94 insertions(+), 72 deletions(-) diff --git a/packages/babel-core/src/config/files/module-types.ts b/packages/babel-core/src/config/files/module-types.ts index dae2dd3360c0..3e7ae2353baa 100644 --- a/packages/babel-core/src/config/files/module-types.ts +++ b/packages/babel-core/src/config/files/module-types.ts @@ -3,14 +3,13 @@ import type { Handler } from "gensync"; import path from "path"; import { pathToFileURL } from "url"; import { createRequire } from "module"; -import fs from "fs"; import semver from "semver"; import { endHiddenCallStack } from "../../errors/rewrite-stack-trace"; import ConfigError from "../../errors/config-error"; -import { transformSync } from "../../transform"; import type { InputOptions } from ".."; +import { transformFileSync } from "../../transform-file"; const require = createRequire(import.meta.url); @@ -60,48 +59,62 @@ function loadCtsDefault(filepath: string) { require.extensions[".cts"] || require.extensions[".mts"] ); + + let handler: NodeJS.RequireExtensions[""]; + if (!hasTsSupport) { - const code = fs.readFileSync(filepath, "utf8"); + const preset = require("@babel/preset-typescript"); + + if (!preset) { + throw new ConfigError( + "You appear to be using a .cts file as Babel configuration, but the `@babel/preset-typescript` package was not found, please install it!", + filepath, + ); + } + const opts: InputOptions = { babelrc: false, configFile: false, - filename: path.basename(filepath), sourceType: "script", sourceMaps: "inline", presets: [ [ - "@babel/preset-typescript", - process.env.BABEL_8_BREAKING - ? { - disallowAmbiguousJSXLike: true, - allExtensions: true, - onlyRemoveTypeImports: true, - optimizeConstEnums: true, - } - : { - allowDeclareFields: true, - disallowAmbiguousJSXLike: true, - allExtensions: true, - onlyRemoveTypeImports: true, - optimizeConstEnums: true, - }, + preset, + { + disallowAmbiguousJSXLike: true, + allExtensions: true, + onlyRemoveTypeImports: true, + optimizeConstEnums: true, + ...(process.env.BABEL_8_BREAKING && { + allowDeclareFields: true, + }), + }, ], ], }; - const result = transformSync(code, opts); - require.extensions[ext] = function (m, filename) { - if (filename === filepath) { + + handler = function (m, filename) { + // If we want to support `.ts`, `.d.ts` must be handled specially. + if (handler && filename.endsWith(ext)) { // @ts-expect-error Undocumented API - return m._compile(result.code, filename); + return m._compile( + transformFileSync(filename, { + ...opts, + filename, + }).code, + filename, + ); } return require.extensions[".js"](m, filename); }; + require.extensions[ext] = handler; } try { return endHiddenCallStack(require)(filepath); } finally { if (!hasTsSupport) { - delete require.extensions[ext]; + if (require.extensions[ext] === handler) delete require.extensions[ext]; + handler = undefined; } } } diff --git a/packages/babel-core/src/errors/config-error.ts b/packages/babel-core/src/errors/config-error.ts index 01c0cb16aaeb..52efcb85079b 100644 --- a/packages/babel-core/src/errors/config-error.ts +++ b/packages/babel-core/src/errors/config-error.ts @@ -1,9 +1,9 @@ -import { injcectVirtualStackFrame, expectedError } from "./rewrite-stack-trace"; +import { injectVirtualStackFrame, expectedError } from "./rewrite-stack-trace"; export default class ConfigError extends Error { constructor(message: string, filename?: string) { super(message); expectedError(this); - if (filename) injcectVirtualStackFrame(this, filename); + if (filename) injectVirtualStackFrame(this, filename); } } diff --git a/packages/babel-core/src/errors/rewrite-stack-trace.ts b/packages/babel-core/src/errors/rewrite-stack-trace.ts index 93fb66e38d1b..e47dc9ea0b90 100644 --- a/packages/babel-core/src/errors/rewrite-stack-trace.ts +++ b/packages/babel-core/src/errors/rewrite-stack-trace.ts @@ -1,5 +1,5 @@ /** - * This file uses the iternal V8 Stack Trace API (https://v8.dev/docs/stack-trace-api) + * This file uses the internal V8 Stack Trace API (https://v8.dev/docs/stack-trace-api) * to provide utilities to rewrite the stack trace. * When this API is not present, all the functions in this file become noops. * @@ -33,10 +33,10 @@ * - If e() throws an error, then its shown call stack will be "e, f" * * Additionally, an error can inject additional "virtual" stack frames using the - * injcectVirtualStackFrame(error, filename) function: those are injected as a + * injectVirtualStackFrame(error, filename) function: those are injected as a * replacement of the hidden frames. - * In the example above, if we called injcectVirtualStackFrame(err, "h") and - * injcectVirtualStackFrame(err, "i") on the expected error thrown by c(), its + * In the example above, if we called injectVirtualStackFrame(err, "h") and + * injectVirtualStackFrame(err, "i") on the expected error thrown by c(), its * shown call stack would have been "h, i, e, f". * This can be useful, for example, to report config validation errors as if they * were directly thrown in the config file. @@ -46,8 +46,8 @@ const ErrorToString = Function.call.bind(Error.prototype.toString); const SUPPORTED = !!Error.captureStackTrace; -const START_HIDNG = "startHiding - secret - don't use this - v1"; -const STOP_HIDNG = "stopHiding - secret - don't use this - v1"; +const START_HIDING = "startHiding - secret - don't use this - v1"; +const STOP_HIDING = "stopHiding - secret - don't use this - v1"; type CallSite = Parameters[1][number]; @@ -70,7 +70,7 @@ function CallSite(filename: string): CallSite { } as CallSite); } -export function injcectVirtualStackFrame(error: Error, filename: string) { +export function injectVirtualStackFrame(error: Error, filename: string) { if (!SUPPORTED) return; let frames = virtualFrames.get(error); @@ -97,7 +97,7 @@ export function beginHiddenCallStack( return fn(...args); }, "name", - { value: STOP_HIDNG }, + { value: STOP_HIDING }, ); } @@ -111,7 +111,7 @@ export function endHiddenCallStack( return fn(...args); }, "name", - { value: START_HIDNG }, + { value: START_HIDING }, ); } @@ -144,9 +144,9 @@ function setupPrepareStackTrace() { : "unknown"; for (let i = 0; i < trace.length; i++) { const name = trace[i].getFunctionName(); - if (name === START_HIDNG) { + if (name === START_HIDING) { status = "hiding"; - } else if (name === STOP_HIDNG) { + } else if (name === STOP_HIDING) { if (status === "hiding") { status = "showing"; if (virtualFrames.has(err)) { diff --git a/packages/babel-core/test/config-ts.js b/packages/babel-core/test/config-ts.js index 77d389d32982..a497c49b5060 100644 --- a/packages/babel-core/test/config-ts.js +++ b/packages/babel-core/test/config-ts.js @@ -11,13 +11,17 @@ const require = createRequire(import.meta.url); // 1. ts-node does not support the old version of node. // 2. In the old version of node, jest has been registered in `require.extensions`, which will cause babel to disable the transforming as expected. -describe("@babel/core config with ts [dummy]", () => { - it("dummy", () => { - expect(1).toBe(1); - }); -}); +const LessThanNode12 = semver.lt(process.version, "12.0.0"); -semver.gte(process.version, "12.0.0") +!LessThanNode12 + ? describe + : describe.skip("@babel/core config with ts [dummy]", () => { + it("dummy", () => { + expect(1).toBe(1); + }); + }); + +LessThanNode12 ? describe : describe.skip("@babel/core config with ts", () => { it("should work with simple .cts", () => { @@ -29,29 +33,32 @@ semver.gte(process.version, "12.0.0") }); expect(config.options.targets).toMatchInlineSnapshot(` - Object { - "node": "12.0.0", - } - `); + Object { + "node": "12.0.0", + } + `); }); it("should throw with invalid .ts register", () => { require.extensions[".ts"] = () => { throw new Error("Not support .ts."); }; - expect(() => { - loadPartialConfigSync({ - configFile: path.join( - __dirname, - "fixtures/config-ts/invalid-cts-register/babel.config.cts", - ), - }); - }).toThrow(/Unexpected identifier.*/); - delete require.extensions[".ts"]; + try { + expect(() => { + loadPartialConfigSync({ + configFile: path.join( + __dirname, + "fixtures/config-ts/invalid-cts-register/babel.config.cts", + ), + }); + }).toThrow(/Unexpected identifier.*/); + } finally { + delete require.extensions[".ts"]; + } }); it("should work with ts-node", async () => { - const service = eval("import('ts-node')").register({ + const service = require("ts-node").register({ experimentalResolver: true, compilerOptions: { module: "CommonJS", @@ -59,24 +66,26 @@ semver.gte(process.version, "12.0.0") }); service.enabled(true); - require(path.join( - __dirname, - "fixtures/config-ts/simple-cts-with-ts-node/babel.config.cts", - )); - - const config = loadPartialConfigSync({ - configFile: path.join( + try { + require(path.join( __dirname, "fixtures/config-ts/simple-cts-with-ts-node/babel.config.cts", - ), - }); + )); - service.enabled(false); + const config = loadPartialConfigSync({ + configFile: path.join( + __dirname, + "fixtures/config-ts/simple-cts-with-ts-node/babel.config.cts", + ), + }); - expect(config.options.targets).toMatchInlineSnapshot(` - Object { - "node": "12.0.0", - } - `); + expect(config.options.targets).toMatchInlineSnapshot(` + Object { + "node": "12.0.0", + } + `); + } finally { + service.enabled(false); + } }); }); From b76ec12edee876346df892367d7e06d61302a5cc Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Thu, 9 Feb 2023 02:14:41 +0800 Subject: [PATCH 10/13] support `process.env.BABEL_8_BREAKING && x` --- babel.config.js | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/babel.config.js b/babel.config.js index 206537d9417d..5e74efcf1d51 100644 --- a/babel.config.js +++ b/babel.config.js @@ -464,17 +464,30 @@ function pluginPolyfillsOldNode({ template, types: t }) { }, }; } + +/** + * @param {import("@babel/core")} pluginAPI + * @returns {import("@babel/core").PluginObj} + */ function pluginToggleBooleanFlag({ types: t }, { name, value }) { + function check(test) { + let keepConsequent = value; + + if (test.isUnaryExpression({ operator: "!" })) { + test = test.get("argument"); + keepConsequent = !keepConsequent; + } + return { + test, + keepConsequent, + }; + } + return { visitor: { "IfStatement|ConditionalExpression"(path) { - let test = path.get("test"); - let keepConsequent = value; - - if (test.isUnaryExpression({ operator: "!" })) { - test = test.get("argument"); - keepConsequent = !keepConsequent; - } + // eslint-disable-next-line prefer-const + let { test, keepConsequent } = check(path.get("test")); // yarn-plugin-conditions injects bool(process.env.BABEL_8_BREAKING) // tests, to properly cast the env variable to a boolean. @@ -494,6 +507,26 @@ function pluginToggleBooleanFlag({ types: t }, { name, value }) { : path.node.alternate || t.emptyStatement() ); }, + LogicalExpression(path) { + const { test, keepConsequent } = check(path.get("left")); + + if (!test.matchesPattern(name)) return; + + switch (path.node.operator) { + case "&&": + path.replaceWith( + keepConsequent ? path.node.right : t.booleanLiteral(false) + ); + break; + case "||": + path.replaceWith( + keepConsequent ? t.booleanLiteral(true) : path.node.right + ); + break; + default: + throw path.buildCodeFrameError("This check could not be stripped."); + } + }, MemberExpression(path) { if (path.matchesPattern(name)) { throw path.buildCodeFrameError("This check could not be stripped."); From b34add19944e85e60dd80a9b56f5fff53c5da4b1 Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Tue, 14 Feb 2023 00:53:01 +0800 Subject: [PATCH 11/13] Update packages/babel-core/src/config/files/module-types.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nicolò Ribaudo --- packages/babel-core/src/config/files/module-types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/babel-core/src/config/files/module-types.ts b/packages/babel-core/src/config/files/module-types.ts index 3e7ae2353baa..3739cc0d0f06 100644 --- a/packages/babel-core/src/config/files/module-types.ts +++ b/packages/babel-core/src/config/files/module-types.ts @@ -85,7 +85,7 @@ function loadCtsDefault(filepath: string) { allExtensions: true, onlyRemoveTypeImports: true, optimizeConstEnums: true, - ...(process.env.BABEL_8_BREAKING && { + ...(!process.env.BABEL_8_BREAKING && { allowDeclareFields: true, }), }, From 72bbe2822a5552ab576b52e297ba640ca1382ea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Mon, 13 Feb 2023 17:55:49 +0100 Subject: [PATCH 12/13] Updates to cts config support (#4) --- packages/babel-core/package.json | 8 ---- .../src/config/files/module-types.ts | 40 ++++++++++++++----- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/packages/babel-core/package.json b/packages/babel-core/package.json index 3ee9edb032b6..83ae6a7fce3e 100644 --- a/packages/babel-core/package.json +++ b/packages/babel-core/package.json @@ -77,14 +77,6 @@ "rimraf": "^3.0.0", "ts-node": "^10.9.1" }, - "peerDependencies": { - "@babel/preset-typescript": "^7.0.0" - }, - "peerDependenciesMeta": { - "@babel/preset-typescript": { - "optional": true - } - }, "conditions": { "BABEL_8_BREAKING": [ null, diff --git a/packages/babel-core/src/config/files/module-types.ts b/packages/babel-core/src/config/files/module-types.ts index 3739cc0d0f06..25ffe6c429ef 100644 --- a/packages/babel-core/src/config/files/module-types.ts +++ b/packages/babel-core/src/config/files/module-types.ts @@ -63,15 +63,6 @@ function loadCtsDefault(filepath: string) { let handler: NodeJS.RequireExtensions[""]; if (!hasTsSupport) { - const preset = require("@babel/preset-typescript"); - - if (!preset) { - throw new ConfigError( - "You appear to be using a .cts file as Babel configuration, but the `@babel/preset-typescript` package was not found, please install it!", - filepath, - ); - } - const opts: InputOptions = { babelrc: false, configFile: false, @@ -79,7 +70,7 @@ function loadCtsDefault(filepath: string) { sourceMaps: "inline", presets: [ [ - preset, + getTSPreset(filepath), { disallowAmbiguousJSXLike: true, allExtensions: true, @@ -140,3 +131,32 @@ async function loadMjsDefault(filepath: string) { const module = await endHiddenCallStack(import_)(pathToFileURL(filepath)); return module.default; } + +function getTSPreset(filepath: string) { + try { + // eslint-disable-next-line import/no-extraneous-dependencies + return require("@babel/preset-typescript"); + } catch (error) { + if (error.code !== "MODULE_NOT_FOUND") throw error; + + let message = + "You appear to be using a .cts file as Babel configuration, but the `@babel/preset-typescript` package was not found: please install it!"; + + if (process.versions.pnp) { + // Using Yarn PnP, which doesn't allow requiring packages that are not + // explicitly specified as dependencies. + // TODO(Babel 8): Explicitly add `@babel/preset-typescript` as an + // optional peer dependency of `@babel/core`. + message += ` +If you are using Yarn Plug'n'Play, you may also need to add the following configuration to your .yarnrc.yml file: + +packageExtensions: +\t"@babel/core@*": +\t\tpeerDependencies: +\t\t\t"@babel/preset-typescript": "*" +`; + } + + throw new ConfigError(message, filepath); + } +} From 9f79e04614828002a3dc279d08bc9fcc1781dee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Mon, 13 Feb 2023 19:14:12 +0100 Subject: [PATCH 13/13] lockfile --- yarn.lock | 5 ----- 1 file changed, 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index 48a4c81efe89..99516d1cc6bc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -370,11 +370,6 @@ __metadata: rimraf: ^3.0.0 semver: "condition:BABEL_8_BREAKING ? ^7.3.4 : ^6.3.0" ts-node: ^10.9.1 - peerDependencies: - "@babel/preset-typescript": ^7.0.0 - peerDependenciesMeta: - "@babel/preset-typescript": - optional: true languageName: unknown linkType: soft