diff --git a/packages/babel-core/package.json b/packages/babel-core/package.json index 86a491084a44..ece540ca2dae 100644 --- a/packages/babel-core/package.json +++ b/packages/babel-core/package.json @@ -41,11 +41,9 @@ "./lib/config/files/index.js": "./lib/config/files/index-browser.js", "./lib/config/resolve-targets.js": "./lib/config/resolve-targets-browser.js", "./lib/transform-file.js": "./lib/transform-file-browser.js", - "./lib/transformation/util/clone-deep.js": "./lib/transformation/util/clone-deep-browser.js", "./src/config/files/index.ts": "./src/config/files/index-browser.ts", "./src/config/resolve-targets.ts": "./src/config/resolve-targets-browser.ts", - "./src/transform-file.ts": "./src/transform-file-browser.ts", - "./src/transformation/util/clone-deep.ts": "./src/transformation/util/clone-deep-browser.ts" + "./src/transform-file.ts": "./src/transform-file-browser.ts" }, "dependencies": { "@ampproject/remapping": "^2.1.0", diff --git a/packages/babel-core/src/transformation/util/clone-deep-browser.ts b/packages/babel-core/src/transformation/util/clone-deep-browser.ts deleted file mode 100644 index 78ae53ebf087..000000000000 --- a/packages/babel-core/src/transformation/util/clone-deep-browser.ts +++ /dev/null @@ -1,19 +0,0 @@ -const serialized = "$$ babel internal serialized type" + Math.random(); - -function serialize(key, value) { - if (typeof value !== "bigint") return value; - return { - [serialized]: "BigInt", - value: value.toString(), - }; -} - -function revive(key, value) { - if (!value || typeof value !== "object") return value; - if (value[serialized] !== "BigInt") return value; - return BigInt(value.value); -} - -export default function (value) { - return JSON.parse(JSON.stringify(value, serialize), revive); -} diff --git a/packages/babel-core/src/transformation/util/clone-deep.ts b/packages/babel-core/src/transformation/util/clone-deep.ts index cc077ce937c1..6d9fc30c302d 100644 --- a/packages/babel-core/src/transformation/util/clone-deep.ts +++ b/packages/babel-core/src/transformation/util/clone-deep.ts @@ -1,9 +1,32 @@ -import v8 from "v8"; -import cloneDeep from "./clone-deep-browser"; - -export default function (value) { - if (v8.deserialize && v8.serialize) { - return v8.deserialize(v8.serialize(value)); +//https://github.com/babel/babel/pull/14583#discussion_r882828856 +function deepClone(value: any, cache: Map): any { + if (value !== null) { + if (cache.has(value)) return cache.get(value); + let cloned: any; + if (Array.isArray(value)) { + cloned = new Array(value.length); + for (let i = 0; i < value.length; i++) { + cloned[i] = + typeof value[i] !== "object" ? value[i] : deepClone(value[i], cache); + } + } else { + cloned = {}; + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + cloned[key] = + typeof value[key] !== "object" + ? value[key] + : deepClone(value[key], cache); + } + } + cache.set(value, cloned); + return cloned; } - return cloneDeep(value); + return value; +} + +export default function (value: T): T { + if (typeof value !== "object") return value; + return deepClone(value, new Map()); } diff --git a/packages/babel-core/test/api.js b/packages/babel-core/test/api.js index de42b106df8b..eedf91b88031 100644 --- a/packages/babel-core/test/api.js +++ b/packages/babel-core/test/api.js @@ -261,7 +261,45 @@ describe("api", function () { }, ); - it("transformFromAstSync should not mutate the AST", function () { + it("transformFromAst should generate same code with different cloneInputAst", function () { + const program = `//test1 + /*test2*/var/*test3*/ a = 1/*test4*/;//test5 + //test6 + var b; + `; + const node = parseSync(program); + const { code } = transformFromAstSync(node, program, { + plugins: [ + function () { + return { + visitor: { + Identifier: function (path) { + path.node.name = "replaced"; + }, + }, + }; + }, + ], + }); + const { code: code2 } = transformFromAstSync(node, program, { + cloneInputAst: false, + plugins: [ + function () { + return { + visitor: { + Identifier: function (path) { + path.node.name = "replaced"; + }, + }, + }; + }, + ], + }); + + expect(code).toBe(code2); + }); + + it("transformFromAst should not mutate the AST", function () { const program = "const identifier = 1"; const node = parseSync(program); const { code } = transformFromAstSync(node, program, {