diff --git a/packages/babel-helper-create-class-features-plugin/src/features.js b/packages/babel-helper-create-class-features-plugin/src/features.js index c9e5bdd90a87..8793f550b25b 100644 --- a/packages/babel-helper-create-class-features-plugin/src/features.js +++ b/packages/babel-helper-create-class-features-plugin/src/features.js @@ -6,6 +6,7 @@ export const FEATURES = Object.freeze({ privateMethods: 1 << 2, decorators: 1 << 3, privateIn: 1 << 4, + staticBlocks: 1 << 5, }); const featuresSameLoose = new Map([ @@ -144,8 +145,8 @@ export function verifyUsedFeatures(path, file) { } } - // NOTE: We can't use path.isPrivateMethod() because it isn't supported in <7.2.0 - if (path.isPrivate() && path.isMethod()) { + // NOTE: path.isPrivateMethod() it isn't supported in <7.2.0 + if (path.isPrivateMethod?.()) { if (!hasFeature(file, FEATURES.privateMethods)) { throw path.buildCodeFrameError("Class private methods are not enabled."); } @@ -170,4 +171,13 @@ export function verifyUsedFeatures(path, file) { throw path.buildCodeFrameError("Class fields are not enabled."); } } + + if (path.isStaticBlock?.()) { + if (!hasFeature(file, FEATURES.staticBlocks)) { + throw path.buildCodeFrameError( + "Static class blocks are not enabled. " + + "Please add `@babel/plugin-proposal-class-static-block` to your configuration.", + ); + } + } } diff --git a/packages/babel-helper-create-class-features-plugin/src/fields.js b/packages/babel-helper-create-class-features-plugin/src/fields.js index 699792f6db92..4c441108c9dd 100644 --- a/packages/babel-helper-create-class-features-plugin/src/fields.js +++ b/packages/babel-helper-create-class-features-plugin/src/fields.js @@ -669,7 +669,14 @@ const thisContextVisitor = traverse.visitors.merge([ environmentVisitor, ]); -function replaceThisContext(path, ref, superRef, file, constantSuper) { +function replaceThisContext( + path, + ref, + superRef, + file, + isStaticBlock, + constantSuper, +) { const state = { classRef: ref, needsClassRef: false }; const replacer = new ReplaceSupers({ @@ -680,13 +687,13 @@ function replaceThisContext(path, ref, superRef, file, constantSuper) { refToPreserve: ref, getObjectRef() { state.needsClassRef = true; - return path.node.static + return isStaticBlock || path.node.static ? ref : t.memberExpression(ref, t.identifier("prototype")); }, }); replacer.replace(); - if (path.isProperty()) { + if (isStaticBlock || path.isProperty()) { path.traverse(thisContextVisitor, state); } return state.needsClassRef; @@ -717,19 +724,26 @@ export function buildFieldsInitNodes( const isPublic = !isPrivate; const isField = prop.isProperty(); const isMethod = !isField; + const isStaticBlock = prop.isStaticBlock?.(); - if (isStatic || (isMethod && isPrivate)) { + if (isStatic || (isMethod && isPrivate) || isStaticBlock) { const replaced = replaceThisContext( prop, ref, superRef, state, + isStaticBlock, constantSuper, ); needsClassRef = needsClassRef || replaced; } switch (true) { + case isStaticBlock: + staticNodes.push( + template.statement.ast`(() => ${t.blockStatement(prop.node.body)})()`, + ); + break; case isStatic && isPrivate && isField && privateFieldsAsProperties: needsClassRef = true; staticNodes.push( diff --git a/packages/babel-helper-create-class-features-plugin/src/index.js b/packages/babel-helper-create-class-features-plugin/src/index.js index 2534a88132e8..89394ba8f192 100644 --- a/packages/babel-helper-create-class-features-plugin/src/index.js +++ b/packages/babel-helper-create-class-features-plugin/src/index.js @@ -146,24 +146,16 @@ export function createClassFeaturePlugin({ constructor = path; } else { elements.push(path); - if (path.isProperty() || path.isPrivate()) { + if ( + path.isProperty() || + path.isPrivate() || + path.isStaticBlock?.() + ) { props.push(path); } } if (!isDecorated) isDecorated = hasOwnDecorators(path.node); - - if (path.isStaticBlock?.()) { - throw path.buildCodeFrameError(`Incorrect plugin order, \`@babel/plugin-proposal-class-static-block\` should be placed before class features plugins -{ - "plugins": [ - "@babel/plugin-proposal-class-static-block", - "@babel/plugin-proposal-private-property-in-object", - "@babel/plugin-proposal-private-methods", - "@babel/plugin-proposal-class-properties", - ] -}`); - } } if (!props.length && !isDecorated) return; diff --git a/packages/babel-helper-create-class-features-plugin/test/fixtures/missing-class-static-blocks-plugin/basic/input.js b/packages/babel-helper-create-class-features-plugin/test/fixtures/missing-class-static-blocks-plugin/basic/input.js new file mode 100644 index 000000000000..9ecd90c8ed8f --- /dev/null +++ b/packages/babel-helper-create-class-features-plugin/test/fixtures/missing-class-static-blocks-plugin/basic/input.js @@ -0,0 +1,4 @@ +class A { + #x; + static {} +} diff --git a/packages/babel-helper-create-class-features-plugin/test/fixtures/missing-class-static-blocks-plugin/basic/options.json b/packages/babel-helper-create-class-features-plugin/test/fixtures/missing-class-static-blocks-plugin/basic/options.json new file mode 100644 index 000000000000..04ef00ef4b69 --- /dev/null +++ b/packages/babel-helper-create-class-features-plugin/test/fixtures/missing-class-static-blocks-plugin/basic/options.json @@ -0,0 +1,4 @@ +{ + "plugins": ["proposal-class-properties", "syntax-class-static-block"], + "throws": "Static class blocks are not enabled. Please add `@babel/plugin-proposal-class-static-block` to your configuration." +} diff --git a/packages/babel-helper-replace-supers/src/index.ts b/packages/babel-helper-replace-supers/src/index.ts index 51b1a2215ca7..12591ad49a2a 100644 --- a/packages/babel-helper-replace-supers/src/index.ts +++ b/packages/babel-helper-replace-supers/src/index.ts @@ -281,7 +281,8 @@ export default class ReplaceSupers { this.methodPath = path; this.isDerivedConstructor = path.isClassMethod({ kind: "constructor" }) && !!opts.superRef; - this.isStatic = path.isObjectMethod() || path.node.static; + this.isStatic = + path.isObjectMethod() || path.node.static || path.isStaticBlock?.(); this.isPrivateMethod = path.isPrivate() && path.isMethod(); this.file = opts.file; diff --git a/packages/babel-plugin-proposal-class-static-block/package.json b/packages/babel-plugin-proposal-class-static-block/package.json index e37ae8552b18..5b3d2f870762 100644 --- a/packages/babel-plugin-proposal-class-static-block/package.json +++ b/packages/babel-plugin-proposal-class-static-block/package.json @@ -19,6 +19,7 @@ "babel-plugin" ], "dependencies": { + "@babel/helper-create-class-features-plugin": "workspace:^7.13.11", "@babel/helper-plugin-utils": "workspace:^7.13.0", "@babel/plugin-syntax-class-static-block": "workspace:^7.12.13" }, diff --git a/packages/babel-plugin-proposal-class-static-block/src/index.js b/packages/babel-plugin-proposal-class-static-block/src/index.js index e9eed3441d92..67b2526a8ca4 100644 --- a/packages/babel-plugin-proposal-class-static-block/src/index.js +++ b/packages/babel-plugin-proposal-class-static-block/src/index.js @@ -1,6 +1,11 @@ import { declare } from "@babel/helper-plugin-utils"; import syntaxClassStaticBlock from "@babel/plugin-syntax-class-static-block"; +import { + enableFeature, + FEATURES, +} from "@babel/helper-create-class-features-plugin"; + /** * Generate a uid that is not in `denyList` * @@ -25,10 +30,19 @@ export default declare(({ types: t, template, assertVersion }) => { return { name: "proposal-class-static-block", inherits: syntaxClassStaticBlock, + + pre() { + // Enable this in @babel/helper-create-class-features-plugin, so that it + // can be handled by the private fields and methods transform. + enableFeature(this.file, FEATURES.staticBlocks, /* loose */ false); + }, + visitor: { - Class(path: NodePath) { - const { scope } = path; - const classBody = path.get("body"); + // Run on ClassBody and not on class so that if @babel/helper-create-class-features-plugin + // is enabled it can generte optimized output without passing from the intermediate + // private fields representation. + ClassBody(classBody: NodePath) { + const { scope } = classBody; const privateNames = new Set(); const body = classBody.get("body"); for (const path of body) { diff --git a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/class-binding/output.js b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/class-binding/output.js index 8b78293ec55a..813814e1cd7e 100644 --- a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/class-binding/output.js +++ b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/class-binding/output.js @@ -1,12 +1,9 @@ -var _ = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("_"); - class Foo {} Foo.bar = 42; -Object.defineProperty(Foo, _, { - writable: true, - value: (() => { - Foo.foo = Foo.bar; - })() -}); + +(() => { + Foo.foo = Foo.bar; +})(); + expect(Foo.foo).toBe(42); diff --git a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/class-declaration/output.js b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/class-declaration/output.js index 8b78293ec55a..813814e1cd7e 100644 --- a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/class-declaration/output.js +++ b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/class-declaration/output.js @@ -1,12 +1,9 @@ -var _ = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("_"); - class Foo {} Foo.bar = 42; -Object.defineProperty(Foo, _, { - writable: true, - value: (() => { - Foo.foo = Foo.bar; - })() -}); + +(() => { + Foo.foo = Foo.bar; +})(); + expect(Foo.foo).toBe(42); diff --git a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/in-class-heritage/output.js b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/in-class-heritage/output.js index 799e4784c2a9..2ed3468c3ec4 100644 --- a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/in-class-heritage/output.js +++ b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/in-class-heritage/output.js @@ -1,23 +1,13 @@ -var _class, _2, _temp, _class2, _3, _temp2; +var _class, _temp, _class2, _temp2; -var _ = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("_"); +class Foo extends (_temp = _class = class extends (_temp2 = _class2 = class Base {}, (() => { + _class2.qux = 21; +})(), _temp2) {}, (() => { + _class.bar = 21; +})(), _temp) {} -class Foo extends (_temp = (_2 = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("_"), _class = class extends (_temp2 = (_3 = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("_"), _class2 = class Base {}), Object.defineProperty(_class2, _3, { - writable: true, - value: (() => { - _class2.qux = 21; - })() -}), _temp2) {}), Object.defineProperty(_class, _2, { - writable: true, - value: (() => { - _class.bar = 21; - })() -}), _temp) {} +(() => { + Foo.foo = Foo.bar + Foo.qux; +})(); -Object.defineProperty(Foo, _, { - writable: true, - value: (() => { - Foo.foo = Foo.bar + Foo.qux; - })() -}); expect(Foo.foo).toBe(42); diff --git a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/multiple-static-initializers/output.js b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/multiple-static-initializers/output.js index 2e8b3339a181..876d30bde8a2 100644 --- a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/multiple-static-initializers/output.js +++ b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/multiple-static-initializers/output.js @@ -1,26 +1,19 @@ var _bar = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("bar"); -var _ = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("_"); - -var _2 = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("_2"); - class Foo {} Object.defineProperty(Foo, _bar, { writable: true, value: 21 }); -Object.defineProperty(Foo, _, { - writable: true, - value: (() => { - Foo.foo = babelHelpers.classPrivateFieldLooseBase(Foo, _bar)[_bar]; - Foo.qux1 = Foo.qux; - })() -}); + +(() => { + Foo.foo = babelHelpers.classPrivateFieldLooseBase(Foo, _bar)[_bar]; + Foo.qux1 = Foo.qux; +})(); + Foo.qux = 21; -Object.defineProperty(Foo, _2, { - writable: true, - value: (() => { - Foo.qux2 = Foo.qux; - })() -}); + +(() => { + Foo.qux2 = Foo.qux; +})(); diff --git a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/name-conflict/output.js b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/name-conflict/output.js index ee0d0c1efc12..058d091286ea 100644 --- a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/name-conflict/output.js +++ b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/name-conflict/output.js @@ -1,17 +1,14 @@ var _ = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("_"); -var _2 = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("_2"); - class Foo {} Object.defineProperty(Foo, _, { writable: true, value: 42 }); -Object.defineProperty(Foo, _2, { - writable: true, - value: (() => { - Foo.foo = babelHelpers.classPrivateFieldLooseBase(Foo, _)[_]; - })() -}); + +(() => { + Foo.foo = babelHelpers.classPrivateFieldLooseBase(Foo, _)[_]; +})(); + expect(Foo.foo).toBe(42); diff --git a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/super-static-block/output.js b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/super-static-block/output.js index a2df83a0200b..ccbf240a5efa 100644 --- a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/super-static-block/output.js +++ b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration-loose/super-static-block/output.js @@ -1,26 +1,17 @@ -var _class, _2, _temp; +var _class, _temp; -var _ = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("_"); - -class Foo extends (_temp = (_2 = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("_"), _class = class {}), Object.defineProperty(_class, _2, { - writable: true, - value: (() => { - _class.bar = 42; - })() -}), _temp) {} +class Foo extends (_temp = _class = class {}, (() => { + _class.bar = 42; +})(), _temp) {} Foo.bar = 21; -Object.defineProperty(Foo, _, { - writable: true, - value: (() => { - var _class2, _3, _temp2; - Foo.foo = (_temp2 = (_3 = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("_"), _class2 = class {}), Object.defineProperty(_class2, _3, { - writable: true, - value: (() => { - _class2.bar = 42; - })() - }), _temp2).bar; - })() -}); +(() => { + var _class2, _temp2; + + Foo.foo = (_temp2 = _class2 = class {}, (() => { + _class2.bar = 42; + })(), _temp2).bar; +})(); + expect(Foo.foo).toBe(42); diff --git a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/class-binding/output.js b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/class-binding/output.js index 810eeba965a4..c5506eea7b75 100644 --- a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/class-binding/output.js +++ b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/class-binding/output.js @@ -1,10 +1,9 @@ class Foo {} babelHelpers.defineProperty(Foo, "bar", 42); -var _ = { - writable: true, - value: (() => { - Foo.foo = Foo.bar; - })() -}; + +(() => { + Foo.foo = Foo.bar; +})(); + expect(Foo.foo).toBe(42); diff --git a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/class-declaration/output.js b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/class-declaration/output.js index 810eeba965a4..c5506eea7b75 100644 --- a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/class-declaration/output.js +++ b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/class-declaration/output.js @@ -1,10 +1,9 @@ class Foo {} babelHelpers.defineProperty(Foo, "bar", 42); -var _ = { - writable: true, - value: (() => { - Foo.foo = Foo.bar; - })() -}; + +(() => { + Foo.foo = Foo.bar; +})(); + expect(Foo.foo).toBe(42); diff --git a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/in-class-heritage/output.js b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/in-class-heritage/output.js index ed5682822e11..2ed3468c3ec4 100644 --- a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/in-class-heritage/output.js +++ b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/in-class-heritage/output.js @@ -1,21 +1,13 @@ -var _class, _temp, _2, _class2, _temp2, _3; +var _class, _temp, _class2, _temp2; -class Foo extends (_temp = _class = class extends (_temp2 = _class2 = class Base {}, _3 = { - writable: true, - value: (() => { - _class2.qux = 21; - })() -}, _temp2) {}, _2 = { - writable: true, - value: (() => { - _class.bar = 21; - })() -}, _temp) {} +class Foo extends (_temp = _class = class extends (_temp2 = _class2 = class Base {}, (() => { + _class2.qux = 21; +})(), _temp2) {}, (() => { + _class.bar = 21; +})(), _temp) {} + +(() => { + Foo.foo = Foo.bar + Foo.qux; +})(); -var _ = { - writable: true, - value: (() => { - Foo.foo = Foo.bar + Foo.qux; - })() -}; expect(Foo.foo).toBe(42); diff --git a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/multiple-static-initializers/output.js b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/multiple-static-initializers/output.js index e46f995b46be..db071b19ab3f 100644 --- a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/multiple-static-initializers/output.js +++ b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/multiple-static-initializers/output.js @@ -4,17 +4,14 @@ var _bar = { writable: true, value: 21 }; -var _ = { - writable: true, - value: (() => { - Foo.foo = babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _bar); - Foo.qux1 = Foo.qux; - })() -}; + +(() => { + Foo.foo = babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _bar); + Foo.qux1 = Foo.qux; +})(); + babelHelpers.defineProperty(Foo, "qux", 21); -var _2 = { - writable: true, - value: (() => { - Foo.qux2 = Foo.qux; - })() -}; + +(() => { + Foo.qux2 = Foo.qux; +})(); diff --git a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/name-conflict/output.js b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/name-conflict/output.js index 910fb0ba8a18..fc7b08e9cfae 100644 --- a/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/name-conflict/output.js +++ b/packages/babel-plugin-proposal-class-static-block/test/fixtures/integration/name-conflict/output.js @@ -4,10 +4,9 @@ var _ = { writable: true, value: 42 }; -var _2 = { - writable: true, - value: (() => { - Foo.foo = babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _); - })() -}; + +(() => { + Foo.foo = babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _); +})(); + expect(Foo.foo).toBe(42); diff --git a/packages/babel-plugin-proposal-class-static-block/test/plugin-ordering.test.js b/packages/babel-plugin-proposal-class-static-block/test/plugin-ordering.test.js index d32d3ffe93aa..0e1fae77548e 100644 --- a/packages/babel-plugin-proposal-class-static-block/test/plugin-ordering.test.js +++ b/packages/babel-plugin-proposal-class-static-block/test/plugin-ordering.test.js @@ -2,15 +2,15 @@ import * as babel from "@babel/core"; import proposalClassStaticBlock from ".."; describe("plugin ordering", () => { - it("should throw when @babel/plugin-proposal-class-static-block is after class features plugin", () => { + it("should work when @babel/plugin-proposal-class-static-block is after class features plugin", () => { const source = `class Foo { - static { - this.foo = Foo.bar; - } - static bar = 42; -} -`; - expect(() => { + static { + this.foo = Foo.bar; + } + static bar = 42; + } + `; + expect( babel.transform(source, { filename: "example.js", highlightCode: false, @@ -20,22 +20,17 @@ describe("plugin ordering", () => { "@babel/plugin-proposal-class-properties", proposalClassStaticBlock, ], - }); - }) - .toThrow(`Incorrect plugin order, \`@babel/plugin-proposal-class-static-block\` should be placed before class features plugins -{ - "plugins": [ - "@babel/plugin-proposal-class-static-block", - "@babel/plugin-proposal-private-property-in-object", - "@babel/plugin-proposal-private-methods", - "@babel/plugin-proposal-class-properties", - ] -} - 1 | class Foo { -> 2 | static { - | ^ - 3 | this.foo = Foo.bar; - 4 | } - 5 | static bar = 42;`); + }).code, + ).toMatchInlineSnapshot(` + "function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + + class Foo {} + + (() => { + Foo.foo = Foo.bar; + })(); + + _defineProperty(Foo, \\"bar\\", 42);" + `); }); }); diff --git a/packages/babel-preset-env/test/fixtures/shipped-proposals/new-class-features-firefox-70/output.js b/packages/babel-preset-env/test/fixtures/shipped-proposals/new-class-features-firefox-70/output.js index 9de4928f8a5c..458142957dda 100644 --- a/packages/babel-preset-env/test/fixtures/shipped-proposals/new-class-features-firefox-70/output.js +++ b/packages/babel-preset-env/test/fixtures/shipped-proposals/new-class-features-firefox-70/output.js @@ -10,9 +10,6 @@ class A { } -var _ = { - writable: true, - value: (() => { - register(A, _foo.has(A)); - })() -}; +(() => { + register(A, _foo.has(A)); +})(); diff --git a/yarn.lock b/yarn.lock index cbb92c27845b..8c4e89bd2133 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1111,6 +1111,7 @@ __metadata: resolution: "@babel/plugin-proposal-class-static-block@workspace:packages/babel-plugin-proposal-class-static-block" dependencies: "@babel/core": "workspace:*" + "@babel/helper-create-class-features-plugin": "workspace:^7.13.11" "@babel/helper-plugin-test-runner": "workspace:*" "@babel/helper-plugin-utils": "workspace:^7.13.0" "@babel/plugin-syntax-class-static-block": "workspace:^7.12.13"