diff --git a/e2e/react/src/react.test.ts b/e2e/react/src/react.test.ts
index 96bd03e871c6b..2130b0ecfd166 100644
--- a/e2e/react/src/react.test.ts
+++ b/e2e/react/src/react.test.ts
@@ -87,29 +87,10 @@ describe('React Applications', () => {
const appName = uniq('app');
const libName = uniq('lib');
- runCLI(`generate @nrwl/react:app ${appName} --no-interactive`);
- runCLI(`generate @nrwl/react:lib ${libName} --no-interactive`);
+ runCLI(`generate @nrwl/react:app ${appName} --no-interactive --js`);
+ runCLI(`generate @nrwl/react:lib ${libName} --no-interactive --js`);
- renameFile(`apps/${appName}/src/main.tsx`, `apps/${appName}/src/main.jsx`);
- renameFile(
- `apps/${appName}/src/app/app.tsx`,
- `apps/${appName}/src/app/app.jsx`
- );
- renameFile(
- `apps/${appName}/src/app/app.spec.tsx`,
- `apps/${appName}/src/app/app.spec.jsx`
- );
- renameFile(
- `apps/${appName}/src/polyfills.ts`,
- `apps/${appName}/src/polyfills.js`
- );
- updateProjectConfig(appName, (config) => {
- config.targets.build.options.main = `apps/${appName}/src/main.jsx`;
- config.targets.build.options.polyfills = `apps/${appName}/src/polyfills.js`;
- return config;
- });
-
- const mainPath = `apps/${appName}/src/main.jsx`;
+ const mainPath = `apps/${appName}/src/main.js`;
updateFile(
mainPath,
`import '@${proj}/${libName}';\n${readFile(mainPath)}`
diff --git a/packages/react/migrations.json b/packages/react/migrations.json
index 3378935fc04d2..d3a844f86f5af 100644
--- a/packages/react/migrations.json
+++ b/packages/react/migrations.json
@@ -287,6 +287,43 @@
"alwaysAddToPackageJson": false
}
}
+ },
+ "13.10.1": {
+ "version": "13.10.1-beta.1",
+ "packages": {
+ "@types/react": {
+ "version": "18.0.0",
+ "alwaysAddToPackageJson": false
+ },
+ "@types/react-dom": {
+ "version": "18.0.0",
+ "alwaysAddToPackageJson": false
+ },
+ "@types/styled-components": {
+ "version": "5.1.25",
+ "alwaysAddToPackageJson": false
+ },
+ "@emotion/react": {
+ "version": "11.9.0",
+ "alwaysAddToPackageJson": false
+ },
+ "@testing-library/react": {
+ "version": "13.0.0",
+ "alwaysAddToPackageJson": false
+ },
+ "@reduxjs/toolkit": {
+ "version": "1.8.1",
+ "alwaysAddToPackageJson": false
+ },
+ "react-redux": {
+ "version": "7.2.8",
+ "alwaysAddToPackageJson": false
+ },
+ "eslint-plugin-import": {
+ "version": "2.26.0",
+ "alwaysAddToPackageJson": false
+ }
+ }
}
}
}
diff --git a/packages/react/src/generators/application/files/common/src/main.tsx__tmpl__ b/packages/react/src/generators/application/files/common/src/main.tsx__tmpl__
index 564a677ba4144..53c4e73820979 100644
--- a/packages/react/src/generators/application/files/common/src/main.tsx__tmpl__
+++ b/packages/react/src/generators/application/files/common/src/main.tsx__tmpl__
@@ -1,7 +1,10 @@
<% if (strict) { %>import { StrictMode } from 'react';<% } %>
-import * as ReactDOM from 'react-dom';
+import * as ReactDOMClient from 'react-dom/client';
<% if (routing) { %>import { BrowserRouter } from 'react-router-dom';<% } %>
import App from './app/<%= fileName %>';
-ReactDOM.render(<% if (strict) { %><% } %><% if (routing) { %><% } %><% if (routing) { %><% } %><% if (strict) { %><% } %>, document.getElementById('root'));
+const root = ReactDOMClient.createRoot(document.getElementById('root') as HTMLElement);
+root.render(
+<% if (strict) { %><% } %><% if (routing) { %><% } %><% if (routing) { %><% } %><% if (strict) { %><% } %>
+);
diff --git a/packages/react/src/utils/ast-utils.spec.ts b/packages/react/src/utils/ast-utils.spec.ts
index 555a36be68b53..141278de04fcd 100644
--- a/packages/react/src/utils/ast-utils.spec.ts
+++ b/packages/react/src/utils/ast-utils.spec.ts
@@ -219,7 +219,7 @@ describe('findMainRenderStatement', () => {
tree = createTreeWithEmptyWorkspace();
});
- it('should return render(...)', () => {
+ it('should return ReactDOM.render(...)', () => {
const sourceCode = `
import React from 'react';
import ReactDOM from 'react-dom';
@@ -237,6 +237,25 @@ ReactDOM.render(
, document.getElementById('root'));
expect(node).toBeTruthy();
});
+ it('should return root.render(...)', () => {
+ const sourceCode = `
+import React from 'react';
+import ReactDOMClient from 'react-dom/client';
+const root = ReactDOM.createRoot(document.getElementById('root'));
+root.render();
+ `;
+ tree.write('/main.tsx', sourceCode);
+ const source = ts.createSourceFile(
+ '/main.tsx',
+ sourceCode,
+ ts.ScriptTarget.Latest,
+ true
+ );
+
+ const node = utils.findMainRenderStatement(source);
+ expect(node).toBeTruthy();
+ });
+
it('should return render(...)', () => {
const sourceCode = `
import React from 'react';
diff --git a/packages/react/src/utils/ast-utils.ts b/packages/react/src/utils/ast-utils.ts
index 12452c4c7254d..4356217adb361 100644
--- a/packages/react/src/utils/ast-utils.ts
+++ b/packages/react/src/utils/ast-utils.ts
@@ -43,6 +43,7 @@ export function findMainRenderStatement(
for (const expr of calls) {
const inner = expr.expression;
+ // React 17 and below
if (
ts.isPropertyAccessExpression(inner) &&
/ReactDOM/i.test(inner.expression.getText()) &&
@@ -50,6 +51,15 @@ export function findMainRenderStatement(
) {
return expr;
}
+
+ // React 18
+ if (
+ ts.isPropertyAccessExpression(inner) &&
+ /root/.test(inner.expression.getText()) &&
+ inner.name.getText() === 'render'
+ ) {
+ return expr;
+ }
}
// 2. Try to find render from 'react-dom'.
@@ -358,7 +368,7 @@ export function addReduxStoreToMain(
): StringChange[] {
const renderStmt = findMainRenderStatement(source);
if (!renderStmt) {
- logger.warn(`Could not find ReactDOM.render in ${sourcePath}`);
+ logger.warn(`Could not find render(...) in ${sourcePath}`);
return [];
}
const jsx = renderStmt.arguments[0];
diff --git a/packages/react/src/utils/versions.ts b/packages/react/src/utils/versions.ts
index 099a99e8b54ed..2c032235862eb 100755
--- a/packages/react/src/utils/versions.ts
+++ b/packages/react/src/utils/versions.ts
@@ -3,15 +3,15 @@ export const nxVersion = '*';
export const reactVersion = '18.0.0';
export const reactDomVersion = '18.0.0';
export const reactIsVersion = '18.0.0';
-export const typesReactVersion = '17.0.43';
-export const typesReactDomVersion = '17.0.14';
+export const typesReactVersion = '18.0.0';
+export const typesReactDomVersion = '18.0.0';
export const typesReactIsVersion = '17.0.3';
export const styledComponentsVersion = '5.3.5';
-export const typesStyledComponentsVersion = '5.1.24';
+export const typesStyledComponentsVersion = '5.1.25';
export const emotionStyledVersion = '11.8.1';
-export const emotionReactVersion = '11.8.2';
+export const emotionReactVersion = '11.9.0';
export const emotionBabelPlugin = '11.7.2';
export const styledJsxVersion = '5.0.2';
@@ -19,14 +19,14 @@ export const styledJsxVersion = '5.0.2';
export const reactRouterDomVersion = '5.3.0';
export const typesReactRouterDomVersion = '5.3.3';
-export const testingLibraryReactVersion = '12.1.4';
+export const testingLibraryReactVersion = '13.0.0';
export const testingLibraryReactHooksVersion = '7.0.2';
-export const reduxjsToolkitVersion = '1.8.0';
-export const reactReduxVersion = '7.2.6';
+export const reduxjsToolkitVersion = '1.8.1';
+export const reactReduxVersion = '7.2.8';
export const reactTestRendererVersion = '18.0.0';
-export const eslintPluginImportVersion = '2.25.4';
+export const eslintPluginImportVersion = '2.26.0';
export const eslintPluginJsxA11yVersion = '6.5.1';
export const eslintPluginReactVersion = '7.29.4';
export const eslintPluginReactHooksVersion = '4.4.0';