diff --git a/packages/babel-core/package.json b/packages/babel-core/package.json index 61d4871ef6b3..8fa9545468e1 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", @@ -58,7 +56,6 @@ "@babel/template": "workspace:^", "@babel/traverse": "workspace:^", "@babel/types": "workspace:^", - "clone-deep": "^4.0.1", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -86,4 +83,4 @@ ".": "./lib/index.js", "./package.json": "./package.json" } -} +} \ No newline at end of file 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 f375bbaf3f1c..000000000000 --- a/packages/babel-core/src/transformation/util/clone-deep-browser.ts +++ /dev/null @@ -1,5 +0,0 @@ -import cloneDeep from "clone-deep"; - -export default function (value) { - return cloneDeep(value); -} diff --git a/packages/babel-core/src/transformation/util/clone-deep.ts b/packages/babel-core/src/transformation/util/clone-deep.ts index d04e8cf2dc38..25e607dd7f65 100644 --- a/packages/babel-core/src/transformation/util/clone-deep.ts +++ b/packages/babel-core/src/transformation/util/clone-deep.ts @@ -1,16 +1,32 @@ -import v8 from "v8"; -import cloneDeep from "clone-deep"; -import semver from "semver"; +//https://github.com/babel/babel/pull/14583#discussion_r882828856 +function deepClone(value, cache) { + if (value !== null) { + if (cache.has(value)) return cache.get(value); + let cloned; + 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 value; +} export default function (value) { - // There was a memory leak prior to node 18.2.0 - // https://github.com/nodejs/node/issues/40828 - if ( - v8.deserialize && - v8.serialize && - semver.satisfies(process.versions.node, ">=18.2.0") - ) { - return v8.deserialize(v8.serialize(value)); - } - return cloneDeep(value); + 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 c714a7516df2..e5018a585197 100644 --- a/packages/babel-core/test/api.js +++ b/packages/babel-core/test/api.js @@ -201,6 +201,44 @@ describe("api", function () { expect(options).toEqual({ babelrc: false }); }); + 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 = parse(program); + const { code } = transformFromAst(node, program, { + plugins: [ + function () { + return { + visitor: { + Identifier: function (path) { + path.node.name = "replaced"; + }, + }, + }; + }, + ], + }); + const { code: code2 } = transformFromAst(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 = parse(program);