React version 18 has recently been pushed into npm which is great if all of your components support it, however, if you are working with Fluent UI then you may stumble across the following error:
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: my-app20@0.1.0
npm ERR! Found: @types/react@18.0.8
npm ERR! node_modules/@types/react
npm ERR! @types/react@"^18.0.8" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer @types/react@">=16.8.0 <18.0.0" from @fluentui/react@8.67.2
npm ERR! node_modules/@fluentui/react
npm ERR! @fluentui/react@"*" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See C:\Users\...\AppData\Local\npm-cache\eresolve-report.txt for a full report.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\...\AppData\Local\npm-cache\_logs\....-debug-0.log
This might happen if you are doing either of the following:
- When creating a standard PCF project using
pac pcf init
and then using npm install react
followed by npm install @fluentui/react
- Using
create-react-app
with the standard typescript template, followed by npm install @fluentui/react
The reason in both cases for the error is that once React 18 is installed, Fluent UI will not install since it requires a version less than 18. The Fluent UI team are working on React 18 compatibility but I do not know how long it will be until Fluent UI supports React 18.
These kinds of issues often crop up when node module dependencies are set to automatically take the newest major version of packages.
How to fix the issue?
Fundamentally the fix is to downgrade the version of React and the related libraries before installing Fluent UI:
pac pcf init
If you are using standard controls - you might consider moving to virtual controls.
Doing this actually requires a specific version of React and Fluent UI to be installed and so there is no issue.
Check out my blog post on how to convert to a virtual control and install the specific versions required.
Alternatively, if you are installing react after using pac pcf init
with a standard control you can install version 17 specifically using:
npm install react@17 react-dom@17 @types/react@17 @types/react-dom@17
After you've done that, you can install fluent as usual using:
npm install @fluentui/react@latest
create-react-app
Create-react-app
is a command-line utility that is commonly used to quickly create a react app - and is often used for testing purposes when building pcf components. Now that React 18 has been released, using create-react-app
will also install react-18. The scripts and templates have all be updated accordingly.
Unfortunately, you can't use an older version of create-react-app
that used the older version of react (e.g. npx create-react-app@5.0.0
) because you will receive the error:
You are running `create-react-app` 5.0.0, which is behind the latest release (5.0.1).
We no longer support global installation of Create React App.
The Fluent UI team are actually working on a create-react-app template for fluent that specifically installs react17 - but until then you will need to follow these steps:
- Use create-react-app as usual:
npx create-react-app my-app --template typescript
- After your app has been created use:
cd my-app
npm uninstall react react-dom @testing-library/react @types/react @types/react-dom
npm install react@17 react-dom@17 @testing-library/react@12 @types/react@17 @types/react-dom@17
- Since the latest template is designed for React 18 you will need to make some minor modifications to
index.ts:
Replace import ReactDOM from 'react-dom/client';
with import ReactDOM from 'react-dom';
Replace the following code:
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
With the code:
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
This is required because React 18 does not support the ReactDOM.render method anymore.
Once Fluent UI has been updated to support React 18, these steps will not be required - however, if you are using Virtual Controls, then until the platform is updated, your controls will continue to need to use React 16.8.6.
Hope this helps!
@ScottDurow