From 91193fa9c71084ef88cd8f50999c5649bcd0c50b Mon Sep 17 00:00:00 2001 From: Brijesh Bittu Date: Fri, 8 Mar 2024 18:09:24 +0530 Subject: [PATCH] [pigment] Handle more scenarios while transforming sx prop (#41372) --- packages/pigment-react/package.json | 18 +-- .../src/utils/pre-linaria-plugin.ts | 143 ++++++++++-------- .../src/utils/sxObjectExtractor.ts | 31 ++-- .../src/utils/sxPropConverter.ts | 45 ++++++ .../tests/styled/fixtures/styled.input.js | 10 +- .../tests/styled/fixtures/styled.output.css | 2 +- .../tests/styled/fixtures/styled.output.js | 2 +- .../tests/sx/fixtures/sxProps.input.js | 45 ++++++ .../tests/sx/fixtures/sxProps.output.css | 28 ++++ .../tests/sx/fixtures/sxProps.output.js | 43 ++++++ .../tests/sx/fixtures/sxProps2.input.js | 26 ++++ .../tests/sx/fixtures/sxProps2.output.css | 19 +++ .../tests/sx/fixtures/sxProps2.output.js | 10 ++ packages/pigment-react/tests/sx/sx.test.ts | 59 ++++++++ packages/pigment-react/tests/testUtils.ts | 26 +++- pnpm-lock.yaml | 6 + 16 files changed, 416 insertions(+), 97 deletions(-) create mode 100644 packages/pigment-react/src/utils/sxPropConverter.ts create mode 100644 packages/pigment-react/tests/sx/fixtures/sxProps.input.js create mode 100644 packages/pigment-react/tests/sx/fixtures/sxProps.output.css create mode 100644 packages/pigment-react/tests/sx/fixtures/sxProps.output.js create mode 100644 packages/pigment-react/tests/sx/fixtures/sxProps2.input.js create mode 100644 packages/pigment-react/tests/sx/fixtures/sxProps2.output.css create mode 100644 packages/pigment-react/tests/sx/fixtures/sxProps2.output.js create mode 100644 packages/pigment-react/tests/sx/sx.test.ts diff --git a/packages/pigment-react/package.json b/packages/pigment-react/package.json index f82fe99d7c1855..ad575146312e8d 100644 --- a/packages/pigment-react/package.json +++ b/packages/pigment-react/package.json @@ -51,12 +51,14 @@ "stylis": "^4.3.1" }, "devDependencies": { + "@babel/plugin-syntax-jsx": "^7.23.3", "@types/babel__core": "^7.20.5", "@types/babel__helper-module-imports": "^7.18.3", "@types/babel__helper-plugin-utils": "^7.10.3", "@types/chai": "^4.3.12", "@types/cssesc": "^3.0.2", "@types/lodash": "^4.14.202", + "@types/mocha": "^10.0.6", "@types/node": "^18.19.21", "@types/react": "^18.2.55", "@types/stylis": "^4.2.5", @@ -133,15 +135,6 @@ } }, "nx": { - "targetDefaults": { - "build": { - "outputs": [ - "{projectRoot}/build", - "{projectRoot}/processors", - "{projectRoot}/utils" - ] - } - }, "targets": { "test": { "cache": false, @@ -154,6 +147,13 @@ "dependsOn": [ "build" ] + }, + "build": { + "outputs": [ + "{projectRoot}/build", + "{projectRoot}/processors", + "{projectRoot}/utils" + ] } } } diff --git a/packages/pigment-react/src/utils/pre-linaria-plugin.ts b/packages/pigment-react/src/utils/pre-linaria-plugin.ts index 17a41372362750..a2e59449d60ba2 100644 --- a/packages/pigment-react/src/utils/pre-linaria-plugin.ts +++ b/packages/pigment-react/src/utils/pre-linaria-plugin.ts @@ -1,69 +1,82 @@ import { addNamed } from '@babel/helper-module-imports'; import { declare } from '@babel/helper-plugin-utils'; -import { sxObjectExtractor } from './sxObjectExtractor'; +import { NodePath } from '@babel/core'; +import * as Types from '@babel/types'; +import { sxPropConverter } from './sxPropConverter'; -export const babelPlugin = declare((api) => { - api.assertVersion(7); - const { types: t } = api; - return { - name: '@pigmentcss/zero-babel-plugin', - visitor: { - JSXAttribute(path) { - const namePath = path.get('name'); - const openingElement = path.findParent((p) => p.isJSXOpeningElement()); - if ( - !openingElement || - !openingElement.isJSXOpeningElement() || - !namePath.isJSXIdentifier() || - namePath.node.name !== 'sx' - ) { - return; - } - const tagName = openingElement.get('name'); - if (!tagName.isJSXIdentifier()) { - return; - } - const valuePath = path.get('value'); - if (!valuePath.isJSXExpressionContainer()) { - return; - } - const expressionPath = valuePath.get('expression'); - if (!expressionPath.isExpression()) { - return; - } - if (!expressionPath.isObjectExpression() && !expressionPath.isArrowFunctionExpression()) { - return; - } - sxObjectExtractor(expressionPath); - const sxIdentifier = addNamed(namePath, 'sx', process.env.PACKAGE_NAME as string); - expressionPath.replaceWith( - t.callExpression(sxIdentifier, [expressionPath.node, t.identifier(tagName.node.name)]), - ); - }, - ObjectProperty(path) { - // @TODO - Maybe add support for React.createElement calls as well. - // Right now, it only checks for jsx(),jsxs(),jsxDEV() and jsxsDEV() calls. - const keyPath = path.get('key'); - if (!keyPath.isIdentifier() || keyPath.node.name !== 'sx') { - return; - } - const valuePath = path.get('value'); - if (!valuePath.isObjectExpression() && !valuePath.isArrowFunctionExpression()) { - return; - } - const parentJsxCall = path.findParent((p) => p.isCallExpression()); - if (!parentJsxCall || !parentJsxCall.isCallExpression()) { - return; - } - const callee = parentJsxCall.get('callee'); - if (!callee.isIdentifier() || !callee.node.name.includes('jsx')) { - return; - } - const jsxElement = parentJsxCall.get('arguments')[0]; - sxObjectExtractor(valuePath); - const sxIdentifier = addNamed(keyPath, 'sx', process.env.PACKAGE_NAME as string); - valuePath.replaceWith(t.callExpression(sxIdentifier, [valuePath.node, jsxElement.node])); - }, - }, +function replaceNodePath( + expressionPath: NodePath, + namePath: NodePath, + importName: string, + t: typeof Types, + tagName: NodePath, +) { + const sxIdentifier = addNamed(namePath, importName, process.env.PACKAGE_NAME as string); + + const wrapWithSxCall = (expPath: NodePath) => { + expPath.replaceWith( + t.callExpression(sxIdentifier, [expPath.node, t.identifier(tagName.node.name)]), + ); }; -}); + + sxPropConverter(expressionPath, wrapWithSxCall); +} + +export const babelPlugin = declare<{ propName?: string; importName?: string }>( + (api, { propName = 'sx', importName = 'sx' }) => { + api.assertVersion(7); + const { types: t } = api; + return { + name: '@pigmentcss/zero-babel-plugin', + visitor: { + JSXAttribute(path) { + const namePath = path.get('name'); + const openingElement = path.findParent((p) => p.isJSXOpeningElement()); + if ( + !openingElement || + !openingElement.isJSXOpeningElement() || + !namePath.isJSXIdentifier() || + namePath.node.name !== propName + ) { + return; + } + const tagName = openingElement.get('name'); + if (!tagName.isJSXIdentifier()) { + return; + } + const valuePath = path.get('value'); + if (!valuePath.isJSXExpressionContainer()) { + return; + } + const expressionPath = valuePath.get('expression'); + if (!expressionPath.isExpression()) { + return; + } + replaceNodePath(expressionPath, namePath, importName, t, tagName); + }, + ObjectProperty(path) { + // @TODO - Maybe add support for React.createElement calls as well. + // Right now, it only checks for jsx(),jsxs(),jsxDEV() and jsxsDEV() calls. + const keyPath = path.get('key'); + if (!keyPath.isIdentifier() || keyPath.node.name !== propName) { + return; + } + const valuePath = path.get('value'); + if (!valuePath.isObjectExpression() && !valuePath.isArrowFunctionExpression()) { + return; + } + const parentJsxCall = path.findParent((p) => p.isCallExpression()); + if (!parentJsxCall || !parentJsxCall.isCallExpression()) { + return; + } + const callee = parentJsxCall.get('callee'); + if (!callee.isIdentifier() || !callee.node.name.includes('jsx')) { + return; + } + const jsxElement = parentJsxCall.get('arguments')[0] as NodePath; + replaceNodePath(valuePath, keyPath, importName, t, jsxElement); + }, + }, + }; + }, +); diff --git a/packages/pigment-react/src/utils/sxObjectExtractor.ts b/packages/pigment-react/src/utils/sxObjectExtractor.ts index c5dc53b8b078c8..28f5866781f3e5 100644 --- a/packages/pigment-react/src/utils/sxObjectExtractor.ts +++ b/packages/pigment-react/src/utils/sxObjectExtractor.ts @@ -23,7 +23,9 @@ function validateObjectKey( return; } if (!parentCall) { - throw keyPath.buildCodeFrameError('Expressions in css object keys are not supported.'); + throw keyPath.buildCodeFrameError( + `${process.env.PACKAGE_NAME}: Expressions in css object keys are not supported.`, + ); } if ( !identifiers.every((item) => { @@ -41,7 +43,7 @@ function validateObjectKey( }) ) { throw keyPath.buildCodeFrameError( - 'Variables in css object keys should only use the passed theme(s) object or variables that are defined in the root scope.', + `${process.env.PACKAGE_NAME}: Variables in css object keys should only use the passed theme(s) object or variables that are defined in the root scope.`, ); } } @@ -59,14 +61,14 @@ function traverseObjectExpression( const value = property.get('value'); if (!value.isExpression()) { throw value.buildCodeFrameError( - 'This value is not supported. It can only be static values or local variables.', + `${process.env.PACKAGE_NAME}: This value is not supported. It can only be static values or local variables.`, ); } if (value.isObjectExpression()) { traverseObjectExpression(value, parentCall); } else if (value.isArrowFunctionExpression()) { throw value.buildCodeFrameError( - 'Arrow functions are not supported as values of sx object.', + `${process.env.PACKAGE_NAME}: Arrow functions are not supported as values of sx object.`, ); } else if (!value.isLiteral() && !isStaticObjectOrArrayExpression(value)) { const identifiers = findIdentifiers([value], 'reference'); @@ -86,7 +88,7 @@ function traverseObjectExpression( localIdentifiers.push(id); } else { throw id.buildCodeFrameError( - 'Consider moving this variable to the root scope if it has all static values.', + `${process.env.PACKAGE_NAME}: Consider moving this variable to the root scope if it has all static values.`, ); } }); @@ -103,20 +105,23 @@ function traverseObjectExpression( if ( !identifiers.every((id) => { const binding = property.scope.getBinding(id.node.name); - if (!binding || binding.scope !== rootScope) { - return false; - } - return true; + // the indentifier definition should either be in the root scope or in the same scope + // as the object property, ie, ({theme}) => ({...theme.applyStyles()}) + return binding && (binding.scope === rootScope || binding.scope === property.scope); }) ) { throw property.buildCodeFrameError( - 'You can only use variables that are defined in the root scope of the file.', + `${process.env.PACKAGE_NAME}: You can only use variables in the spread that are defined in the root scope of the file.`, ); } } else if (property.isObjectMethod()) { - throw property.buildCodeFrameError('sx prop object does not support ObjectMethods.'); + throw property.buildCodeFrameError( + `${process.env.PACKAGE_NAME}: sx prop object does not support ObjectMethods.`, + ); } else { - throw property.buildCodeFrameError('Unknown property in object.'); + throw property.buildCodeFrameError( + `${process.env.PACKAGE_NAME}: Unknown property in object.`, + ); } }); } @@ -128,7 +133,7 @@ export function sxObjectExtractor(nodePath: NodePath ({color: 'red'}). You can accept theme object in the params if required.", + `${process.env.PACKAGE_NAME}: sx prop only supports arrow functions directly returning an object, e.g. () => ({color: 'red'}). You can accept theme object in the params if required.`, ); } traverseObjectExpression(body, nodePath); diff --git a/packages/pigment-react/src/utils/sxPropConverter.ts b/packages/pigment-react/src/utils/sxPropConverter.ts new file mode 100644 index 00000000000000..838184239a2b19 --- /dev/null +++ b/packages/pigment-react/src/utils/sxPropConverter.ts @@ -0,0 +1,45 @@ +import { NodePath } from '@babel/core'; +import { ArrowFunctionExpression, Expression, ObjectExpression } from '@babel/types'; +import { sxObjectExtractor } from './sxObjectExtractor'; + +function isAllowedExpression( + node: NodePath, +): node is NodePath | NodePath { + return node.isObjectExpression() || node.isArrowFunctionExpression(); +} + +export function sxPropConverter( + node: NodePath, + wrapWithSxCall: (expPath: NodePath) => void, +) { + if (node.isConditionalExpression()) { + const consequent = node.get('consequent'); + const alternate = node.get('alternate'); + + if (isAllowedExpression(consequent)) { + sxObjectExtractor(consequent); + wrapWithSxCall(consequent); + } + if (isAllowedExpression(alternate)) { + sxObjectExtractor(alternate); + wrapWithSxCall(alternate); + } + } else if (node.isLogicalExpression()) { + const right = node.get('right'); + if (isAllowedExpression(right)) { + sxObjectExtractor(right); + wrapWithSxCall(right); + } + } else if (isAllowedExpression(node)) { + sxObjectExtractor(node); + wrapWithSxCall(node); + } else if (node.isIdentifier()) { + const rootScope = node.scope.getProgramParent(); + const binding = node.scope.getBinding(node.node.name); + // Simplest case, ie, const styles = {static object} + // and is used as + if (binding?.scope === rootScope) { + wrapWithSxCall(node); + } + } +} diff --git a/packages/pigment-react/tests/styled/fixtures/styled.input.js b/packages/pigment-react/tests/styled/fixtures/styled.input.js index 8e2c133a04dacd..fb6173d1406689 100644 --- a/packages/pigment-react/tests/styled/fixtures/styled.input.js +++ b/packages/pigment-react/tests/styled/fixtures/styled.input.js @@ -10,24 +10,24 @@ const rotateKeyframe = keyframes({ }); const Component = styled.div(({ theme }) => ({ - color: theme.palette.primary.main, + color: (theme.vars ?? theme).palette.primary.main, animation: `${rotateKeyframe} 2s ease-out 0s infinite`, })); -const SliderRail = styled('span', { +export const SliderRail = styled('span', { name: 'MuiSlider', slot: 'Rail', })` - display: none; + display: block; position: absolute; border-radius: inherit; background-color: currentColor; opacity: 0.38; - font-size: ${({ theme }) => theme.size.font.h1}; + font-size: ${({ theme }) => (theme.vars ?? theme).size.font.h1}; `; const SliderRail2 = styled.span` display: block; opacity: 0.38; - font-size: ${({ theme }) => theme.size.font.h1}; + font-size: ${({ theme }) => (theme.vars ?? theme).size.font.h1}; `; diff --git a/packages/pigment-react/tests/styled/fixtures/styled.output.css b/packages/pigment-react/tests/styled/fixtures/styled.output.css index 79471464008abb..ff22b6cc6cb58d 100644 --- a/packages/pigment-react/tests/styled/fixtures/styled.output.css +++ b/packages/pigment-react/tests/styled/fixtures/styled.output.css @@ -11,7 +11,7 @@ animation: r1419f2q 2s ease-out 0s infinite; } .s1sjy0ja { - display: none; + display: block; position: absolute; border-radius: inherit; background-color: currentColor; diff --git a/packages/pigment-react/tests/styled/fixtures/styled.output.js b/packages/pigment-react/tests/styled/fixtures/styled.output.js index d5519e6a7a196b..dbe0d964a69688 100644 --- a/packages/pigment-react/tests/styled/fixtures/styled.output.js +++ b/packages/pigment-react/tests/styled/fixtures/styled.output.js @@ -5,7 +5,7 @@ import _theme from '@pigment-css/react/theme'; const Component = /*#__PURE__*/ _styled('div')({ classes: ['c1vtarpi'], }); -const SliderRail = /*#__PURE__*/ _styled2('span', { +export const SliderRail = /*#__PURE__*/ _styled2('span', { name: 'MuiSlider', slot: 'Rail', })({ diff --git a/packages/pigment-react/tests/sx/fixtures/sxProps.input.js b/packages/pigment-react/tests/sx/fixtures/sxProps.input.js new file mode 100644 index 00000000000000..0d8f4e16e1b14c --- /dev/null +++ b/packages/pigment-react/tests/sx/fixtures/sxProps.input.js @@ -0,0 +1,45 @@ +import { styled } from '@pigment-css/react'; + +export const SliderRail = styled('span', { + name: 'MuiSlider', + slot: 'Rail', +})` + display: block; + position: absolute; + border-radius: inherit; + background-color: currentColor; + opacity: 0.38; + font-size: ${({ theme }) => (theme.vars ?? theme).size.font.h1}; +`; + +function App() { + return ; +} + +function App2(props) { + return ( + + ); +} + +function App3(props) { + return ( + + ); +} + +const textAlign = 'center'; +const styles4 = { + mb: 1, + textAlign, +}; + +function App4(props) { + return ; +} diff --git a/packages/pigment-react/tests/sx/fixtures/sxProps.output.css b/packages/pigment-react/tests/sx/fixtures/sxProps.output.css new file mode 100644 index 00000000000000..2da9b96ba1de38 --- /dev/null +++ b/packages/pigment-react/tests/sx/fixtures/sxProps.output.css @@ -0,0 +1,28 @@ +.s4jxdij { + display: block; + position: absolute; + border-radius: inherit; + background-color: currentColor; + opacity: 0.38; + font-size: 3rem; +} +.s4jxdij-1 { + font-size: 3rem; +} +.s4jxdij.s6g18tg { + color: red; +} +.s4jxdij.sqa8j32 { + color: var(--sqa8j32-0); +} +.s4jxdij.s1vuaneo { + background-color: blue; + color: white; +} +.s4jxdij.sihzw1t { + color: var(--sihzw1t-0); +} +.s4jxdij.s1cb6hjd { + margin-bottom: 8px; + text-align: center; +} diff --git a/packages/pigment-react/tests/sx/fixtures/sxProps.output.js b/packages/pigment-react/tests/sx/fixtures/sxProps.output.js new file mode 100644 index 00000000000000..365853e2ea51e5 --- /dev/null +++ b/packages/pigment-react/tests/sx/fixtures/sxProps.output.js @@ -0,0 +1,43 @@ +import { styled as _styled } from '@pigment-css/react'; +export const SliderRail = /*#__PURE__*/ _styled('span', { + name: 'MuiSlider', + slot: 'Rail', +})({ + classes: ['s4jxdij', 's4jxdij-1'], +}); +function App() { + return ; +} +function App2(props) { + return ( + + ); +} +function App3(props) { + return ( + + ); +} +function App4(props) { + return ; +} diff --git a/packages/pigment-react/tests/sx/fixtures/sxProps2.input.js b/packages/pigment-react/tests/sx/fixtures/sxProps2.input.js new file mode 100644 index 00000000000000..7c160da9ffdd15 --- /dev/null +++ b/packages/pigment-react/tests/sx/fixtures/sxProps2.input.js @@ -0,0 +1,26 @@ +import { styled } from '@pigment-css/react'; + +const SliderRail = styled('span', { + name: 'MuiSlider', + slot: 'Rail', +})` + display: block; + position: absolute; + border-radius: inherit; + background-color: currentColor; + opacity: 0.38; + font-size: ${({ theme }) => (theme.vars ?? theme).size.font.h1}; +`; + +function App2(props) { + return ( + ({ + mb: 1, + ...theme.applyStyles('dark', { + color: 'white', + }), + })} + /> + ); +} diff --git a/packages/pigment-react/tests/sx/fixtures/sxProps2.output.css b/packages/pigment-react/tests/sx/fixtures/sxProps2.output.css new file mode 100644 index 00000000000000..e406adf7a04e85 --- /dev/null +++ b/packages/pigment-react/tests/sx/fixtures/sxProps2.output.css @@ -0,0 +1,19 @@ +.sex8rxh { + display: block; + position: absolute; + border-radius: inherit; + background-color: currentColor; + opacity: 0.38; + font-size: 3rem; +} +.sex8rxh-1 { + font-size: 3rem; +} +.sex8rxh.suhmzz0 { + margin-bottom: 8px; +} +@media (prefers-color-scheme: dark) { + .sex8rxh.suhmzz0 { + color: white; + } +} diff --git a/packages/pigment-react/tests/sx/fixtures/sxProps2.output.js b/packages/pigment-react/tests/sx/fixtures/sxProps2.output.js new file mode 100644 index 00000000000000..efe0be355aba42 --- /dev/null +++ b/packages/pigment-react/tests/sx/fixtures/sxProps2.output.js @@ -0,0 +1,10 @@ +import { styled as _styled } from '@pigment-css/react'; +const SliderRail = /*#__PURE__*/ _styled('span', { + name: 'MuiSlider', + slot: 'Rail', +})({ + classes: ['sex8rxh', 'sex8rxh-1'], +}); +function App2(props) { + return ; +} diff --git a/packages/pigment-react/tests/sx/sx.test.ts b/packages/pigment-react/tests/sx/sx.test.ts new file mode 100644 index 00000000000000..ef1a590d4c70a5 --- /dev/null +++ b/packages/pigment-react/tests/sx/sx.test.ts @@ -0,0 +1,59 @@ +import path from 'node:path'; +import { runTransformation, expect } from '../testUtils'; + +const theme = { + palette: { + primary: { + main: 'red', + }, + }, + size: { + font: { + h1: '3rem', + }, + }, + components: { + MuiSlider: { + styleOverrides: { + rail: { + fontSize: '3rem', + }, + }, + }, + }, + applyStyles(mode: string, style: object) { + return { + [`@media (prefers-color-scheme: ${mode})`]: style, + }; + }, +}; + +describe('Pigment CSS - sx prop', () => { + it('sx prop with logical and conditional expressions', async () => { + const { output, fixture } = await runTransformation( + path.join(__dirname, 'fixtures/sxProps.input.js'), + { + themeArgs: { + theme, + }, + }, + ); + + expect(output.js).to.equal(fixture.js); + expect(output.css).to.equal(fixture.css); + }); + + it('sx prop with theme spread', async () => { + const { output, fixture } = await runTransformation( + path.join(__dirname, 'fixtures/sxProps2.input.js'), + { + themeArgs: { + theme, + }, + }, + ); + + expect(output.js).to.equal(fixture.js); + expect(output.css).to.equal(fixture.css); + }); +}); diff --git a/packages/pigment-react/tests/testUtils.ts b/packages/pigment-react/tests/testUtils.ts index 88ff6ab98a3c38..4223f20d289663 100644 --- a/packages/pigment-react/tests/testUtils.ts +++ b/packages/pigment-react/tests/testUtils.ts @@ -1,13 +1,29 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; import { expect as chaiExpect } from 'chai'; +import { transformAsync } from '@babel/core'; import { asyncResolveFallback } from '@wyw-in-js/shared'; -import { TransformCacheCollection, transform, createFileReporter } from '@wyw-in-js/transform'; +import { + TransformCacheCollection, + transform as wywTransform, + createFileReporter, +} from '@wyw-in-js/transform'; import { preprocessor } from '@pigment-css/react/utils'; import * as prettier from 'prettier'; +import sxTransformPlugin from '../exports/sx-plugin'; + const shouldUpdateOutput = process.env.UPDATE_FIXTURES === 'true'; +function runSxTransform(code: string, filename: string) { + return transformAsync(code, { + babelrc: false, + configFile: false, + filename, + plugins: ['@babel/plugin-syntax-jsx', [sxTransformPlugin]], + }); +} + export async function runTransformation( absolutePath: string, options?: { themeArgs?: { theme?: any } }, @@ -24,6 +40,8 @@ export async function runTransformation( ? fs.readFileSync(outputCssFilePath, 'utf8') : ''; + const babelResult = await runSxTransform(inputContent, inputFilePath); + const pluginOptions = { themeArgs: { theme: options?.themeArgs?.theme, @@ -31,12 +49,14 @@ export async function runTransformation( babelOptions: { configFile: false, babelrc: false, + plugins: ['@babel/plugin-syntax-jsx'], }, tagResolver(_source: string, tag: string) { return require.resolve(`../exports/${tag}`); }, }; - const result = await transform( + + const result = await wywTransform( { options: { filename: inputFilePath, @@ -46,7 +66,7 @@ export async function runTransformation( cache, eventEmitter, }, - inputContent, + babelResult?.code ?? inputContent, asyncResolveFallback, ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a12a5fec79085a..b13e0946fa8755 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2152,6 +2152,9 @@ importers: specifier: ^4.3.1 version: 4.3.1 devDependencies: + '@babel/plugin-syntax-jsx': + specifier: ^7.23.3 + version: 7.23.3(@babel/core@7.23.9) '@types/babel__core': specifier: ^7.20.5 version: 7.20.5 @@ -2170,6 +2173,9 @@ importers: '@types/lodash': specifier: ^4.14.202 version: 4.14.202 + '@types/mocha': + specifier: ^10.0.6 + version: 10.0.6 '@types/node': specifier: ^18.19.21 version: 18.19.21