Showing posts with label react. Show all posts
Showing posts with label react. Show all posts

Saturday, October 10, 2026

Fix npm error code ERESOLVE

Have you encountered this error, npm error code ERESOLVE? Right, following the setup instructions in a node app project, it was time to run npm ci. Lo and behold, the npm error code ERESOLVE error staring right into my face. Feeling confident I ask GitHub Copilot to fix my npm error. Let me share this journey.

System Used

Not a lot. Just a couple of things.

  • Node v22.12.0
  • Windows 11 Home 10.0.26200

The npm error code ERESOLVE Encounter

What is npm ci? It's a clean install of the project dependencies. It installs packages from the package-lock.json. This ensures you have the exact dependencies and version listed in that file. Unlike npm install, which can install packages from the node_modules cache. Alrighty then, let's see the error I got.

  
C:\workspace\shopify-app>npm ci
npm warn ERESOLVE overriding peer dependency
... more npm warn snipped...
npm error code ERESOLVE
npm error ERESOLVE could not resolve
npm error
npm error While resolving: @react-router/serve@7.14.0
npm error Found: react-router@7.13.2
npm error node_modules/react-router
npm error   react-router@"^7.12.0" from the root project
npm error   peer react-router@"^7.13.2" from @react-router/dev@7.13.2
npm error   node_modules/@react-router/dev
npm error     @react-router/dev@"^7.12.0" from the root project
npm error     peer @react-router/dev@"^7.13.2" from @react-router/fs-routes@7.13.2
npm error     node_modules/@react-router/fs-routes
npm error       @react-router/fs-routes@"^7.12.0" from the root project
npm error   2 more (@react-router/node, @shopify/shopify-app-react-router)
npm error
npm error Could not resolve dependency:
npm error peer react-router@"7.14.0" from @react-router/serve@7.14.0
npm error node_modules/@react-router/serve
npm error   @react-router/serve@"^7.14.0" from the root project
npm error   peerOptional @react-router/serve@"^7.13.2" from @react-router/dev@7.13.2
npm error   node_modules/@react-router/dev
npm error     @react-router/dev@"^7.12.0" from the root project
npm error     1 more (@react-router/fs-routes)
npm error
npm error Conflicting peer dependency: react-router@7.14.0
npm error node_modules/react-router
npm error   peer react-router@"7.14.0" from @react-router/serve@7.14.0
npm error   node_modules/@react-router/serve
npm error     @react-router/serve@"^7.14.0" from the root project
npm error     peerOptional @react-router/serve@"^7.13.2" from @react-router/dev@7.13.2
npm error     node_modules/@react-router/dev
npm error       @react-router/dev@"^7.12.0" from the root project
npm error       1 more (@react-router/fs-routes)
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
...snipped...
  

Troubleshooting npm error code ERESOLVE

Upon seeing the error I scrolled up to the starting line of the error. Hmmm... what is this "npm error code ERESOLVE"? Looks like something is wrong with building the dependencies. No worries, I got GitHub Copilot running GPT6-Luna (free tier) by my side. I then tell Copilot to fix my npm ci error.

Copilot did its thing. Had several back and for with it. After like 7 attempts, no concrete solution was found. So I told copilot to stop trying to fix and restore everything back.

I went back to good old googling around. Stack Overflow finally gave me a clue. Why didn't I believe right away on the npm printed output? It did say retry command with --legacy-peer-deps. I guess I needed more information before I try it.

Fixed npm error code ERESOLVE

So I tried the --legacy-peer-deps flag. What does this flag do? This provides a way of resolving overly strict peer dependencies of packages. It will cause npm to ignore peer dependencies when building a package tree. Which is what heppens on npm versions 3 through 6. Here's how it looked like.

  
C:\workspace\shopify-app>npm ci --legacy-peer-deps
npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated @humanwhocodes/config-array@0.13.0: Use @eslint/config-array instead
npm warn deprecated rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
npm warn deprecated glob@7.2.3: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
npm warn deprecated @humanwhocodes/object-schema@2.0.3: Use @eslint/object-schema instead
npm warn deprecated node-domexception@1.0.0: Use your platform's native DOMException instead
npm warn deprecated @graphql-tools/prisma-loader@8.0.17: This package was intended to be used with an older versions of Prisma.\nThe newer versions of Prisma has a different approach to GraphQL integration.\nTherefore, this package is no longer needed and has been deprecated and removed.\nLearn more: https://www.prisma.io/graphql
npm warn deprecated eslint@8.57.1: This version is no longer supported. Please see https://eslint.org/version-support for other options.

added 748 packages, and audited 749 packages in 43s

178 packages are looking for funding
  run `npm fund` for details

47 vulnerabilities (2 low, 4 moderate, 40 high, 1 critical)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.
  

I finally got my node_modules directory built and I can then npm run dev just fine.

  
C:\workspace\shopify-app>npm run dev

> dev
> react-router dev

  ➜  Local:   http://localhost:3000/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help
  

Final Thoughts

  
C:\workspace\shopify-app>npm -version
10.9.0
  

I'm guessing if I was on npm versions 3 through 6, I would not have encountered this error. This project was probably built with a version of npm between 3 to 6. Anyway, didn't dig deeper anymore because I already got what I wanted. In fairness to GitHub Copilot, even though it failed in fixing this error, it was successful in upgrading my a couple of my Spring Boot projects. First was upgrading Apache ActiveMQ to fix a vulnerability. Second was upgrading json-flattener because of a commons-text vulnerability. The successful ones were paid GitHub Copilot subscriptions though. That makes the scoring into:

Process Points
Old school googling/Stack Overflow 1
GitHub Copilot Subscription 2
GitHub Copilot Free 0

More npm error solutions.

Sunday, August 13, 2023

React FE Spring Boot Example

In this article we will demonstrate a React Front-End app served through Spring Boot's embedded Tomcat. Why do it this way? We can serve a React app in different ways (e.g. Apache Web Server, Nginx, etc.). What is so special about serving a React app through Spring Boot's Tomcat? There is nothing special. A reason could be that the development team is already well versed in Spring Boot with Tomcat. They have mastered configuring Tomcat and investing in a new web server (e.g. Nginx) is of little value. Another could be the deployment pipeline is already set up to do Java/Maven deployment (e.g. Jenkins). Lastly, it could be that you are a new hire and the development team already do it that way. That is, we don't have a choice but to support an existing React FE app served through Spring Boot.

Our focus will be on building the React app so that it can be deployed through a Spring Boot fat jar. We will lightly touch on starting a Spring Boot and React apps. It is assumed that the reader has knowledge regarding Node, React, Java, Maven, Spring Boot, etc. The reader should know how to set up the mentioned technology stack.

If you have been reading my past blogs, then the previous paragraphs sound so familiar. That is because I have done a similar thing for an Angular app. Essentially this article is similar to Angular FE Spring Boot Example. But I added in an extra. In my Angular FE Spring Boot Example, we had to do two steps to build the fat jar. In this article, we will build the fat jar in one step. Sounds good? Let's do it!

Building

Same as in my Angular FE Spring Boot Example, there were two ways to build a React app so that it can be deployed as single Spring Boot fat jar. First one is to use the exec-maven-plugin. Second is to use the maven-resources-plugin.

But wait. There's more. We'll be using the maven-resource-plugin in combination with frontend-maven-plugin. With these two plugins working together, we only need to run one command to build the fat jar. This means, we have leveled up from Angular FE Spring Boot Example.

Spring Initializr

Head over to Spring Initializr and it should look like below:

React FE Sprint Boot Example
Spring Initializr

React Bit

Under the root directory, create a dev folder. This is where all the React stuff goes. Assuming you have Node, Node Version Manager and Node Package Manager ready, run npx create-react-app my-app to set up a web app. We should have something like below:


D:\workspace\react-fe-spring-boot\dev>npx create-react-app my-app
Need to install the following packages:
  create-react-app@5.0.1
Ok to proceed? (y) y

Creating a new React app in D:\workspace\react-fe-spring-boot\dev\my-app.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template...

Created git commit.

Success! Created my-app at D:\workspace\react-fe-spring-boot\dev\my-app
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd my-app
  npm start

Happy hacking!

We follow the bottom two commands (i.e. cd my-app, npm start) and we should have something like below. For more details, head over to Create React App. Thank you Create React App for creating our project. The React app should be available at localhost:3000.

React FE Sprint Boot Example
React app on port 3000

Build the React project, npm run build. This will create files in the build directory. Take note of this folder as we will need it in our POM file. We should see something like below after the build:


D:\workspace\react-fe-spring-boot\dev>npm run build

> my-app@0.1.0 build
> react-scripts build

Creating an optimized production build...
Compiled successfully.

File sizes after gzip:

  46.61 kB  build\static\js\main.46f5c8f5.js
  1.78 kB   build\static\js\787.28cb0dcd.chunk.js
  541 B     build\static\css\main.073c9b0a.css

The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.

The build folder is ready to be deployed.
You may serve it with a static server:

  npm install -g serve
  serve -s build

Find out more about deployment here:

  https://cra.link/deployment

Maven Bit

We don't need to change any Java code. The key is in the POM. We will copy the build files over to the classes/static folder and then Maven will take care of making the fat jar. Add the maven-resources-plugin like below (make sure you get the diretories right ;) ):


<plugin> 
	<artifactId>maven-resources-plugin</artifactId>
	<executions>
		<execution>
			<id>copy-resources</id>
			<phase>validate</phase>
			<goals>
				<goal>copy-resources</goal>
			</goals> 
			<configuration>
				<outputDirectory>${build.directory}/classes/static/</outputDirectory>
				<resources>
					<resource>
						<directory>dev/my-app/build</directory>
					</resource>
				</resources>
			</configuration>
		</execution>
	</executions>
</plugin>

Running the Fat Jar

Do a mvn clean package. Now, run java -jar ./target/react-fe-spring-boot-0.0.1-SNAPSHOT.jar and we should be able to see the it running on localhost:8080. It's now being served by Tomcat.

React FE Sprint Boot Example
React app on port 8080

Wait? What?! That was 2 steps to build it into a fat jar! What gives?

One Command to Build Them All

To build it all in one command, we'll enlist the help of the frontend-maven-plugin and a minor change on maven-resource-plugin. Before we do that, let's review the goals bound to the package phase, run mvn help:describe -Dcmd=package.


D:\workspace\react-fe-spring-boot>mvn help:describe -Dcmd=package

[INFO] 'package' is a phase corresponding to this plugin:
org.apache.maven.plugins:maven-jar-plugin:2.4:jar

It is a part of the lifecycle for the POM packaging 'jar'. This lifecycle includes the following phases:
* validate: Not defined
* initialize: Not defined
* generate-sources: Not defined
* process-sources: Not defined
* generate-resources: Not defined
* process-resources: org.apache.maven.plugins:maven-resources-plugin:2.6:resources
* compile: org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
* process-classes: Not defined
* generate-test-sources: Not defined
* process-test-sources: Not defined
* generate-test-resources: Not defined
* process-test-resources: org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
* test-compile: org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
* process-test-classes: Not defined
* test: org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
* prepare-package: Not defined
* package: org.apache.maven.plugins:maven-jar-plugin:2.4:jar
* pre-integration-test: Not defined
* integration-test: Not defined
* post-integration-test: Not defined
* verify: Not defined
* install: org.apache.maven.plugins:maven-install-plugin:2.4:install
* deploy: org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.947 s
[INFO] Finished at: 2023-08-06T23:04:08+01:00
[INFO] ------------------------------------------------------------------------

First change is to make maven-resources-plugin execute on the generate-sources phase. Change validate like so.


<plugin> 
	<artifactId>maven-resources-plugin</artifactId>
	<executions>
		<execution>
			<id>copy-resources</id>
			<!-- <phase>validate</phase> -->
			<phase>generate-sources</phase>
			...snipped...

Next is add the frontend-maven-plugin like so.


<plugin>
	<groupId>com.github.eirslett</groupId>
	<artifactId>frontend-maven-plugin</artifactId>
	<version>1.11.3</version>
	<configuration>
		<workingDirectory>dev/my-app</workingDirectory>
		<nodeVersion>v18.10.0</nodeVersion>
		<yarnVersion>v1.22.17</yarnVersion>
	</configuration>
	<executions>
		<execution>
			<id>install-frontend-tools</id>
			<goals>
				<goal>install-node-and-yarn</goal>
			</goals>
			<phase>validate</phase>
		</execution>
		<execution>
			<id>build-frontend</id>
			<goals>
				<goal>yarn</goal>
			</goals>
			<phase>initialize</phase>
			<configuration>
				<arguments>build</arguments>
			</configuration>
		</execution>
	</executions>
</plugin>

Now, do you know why I had to show you the Maven package phases? During the package phase, the first thing that will be done by the frontend plugin will be to install node and yarn (i.e. validate phase). After that is building the React app, yarn build (i.e. initialize phase). And lastly, resources will copy the files over (i.e. generate-sources phase). Viola! We're ready to run the build again. Remove the built files (e.g. mvn clean or delete target directory, delete the React app build directory) and then do a mvn clean package. You should see something like below. After the build you should be able to run the jar like before.


D:\workspace\react-fe-spring-boot>mvn clean package
[INFO] Scanning for projects...
[INFO]
[INFO] -------------< com.blogspot.jpllosa:react-fe-spring-boot >--------------
[INFO] Building react-fe-spring-boot 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.2.0:clean (default-clean) @ react-fe-spring-boot ---
[INFO]
[INFO] --- frontend-maven-plugin:1.11.3:install-node-and-yarn (install-frontend-tools) @ react-fe-spring-boot ---
[INFO] Installing node version v18.10.0
[INFO] Copying node binary from C:\Users\jpllosa\.m2\repository\com\github\eirslett\node\18.10.0\node-18.10.0-win-x64.exe to D:\workspace\react-fe-spring-boot\dev\my-app\node\node.exe
[INFO] Installed node locally.
[INFO] Installing Yarn version v1.22.17
[INFO] Unpacking C:\Users\jpllosa\.m2\repository\com\github\eirslett\yarn\1.22.17\yarn-1.22.17.tar.gz into D:\workspace\react-fe-spring-boot\dev\my-app\node\yarn
[INFO] Installed Yarn locally.
[INFO]
[INFO] --- frontend-maven-plugin:1.11.3:yarn (build-frontend) @ react-fe-spring-boot ---
[INFO] Running 'yarn build' in D:\workspace\react-fe-spring-boot\dev\my-app
[INFO] yarn run v1.22.17
[INFO] $ react-scripts build
[INFO] Creating an optimized production build...
[INFO] Compiled successfully.
[INFO]
[INFO] File sizes after gzip:
[INFO]
[INFO]   46.61 kB  build\static\js\main.46f5c8f5.js
[INFO]   1.78 kB   build\static\js\787.28cb0dcd.chunk.js
[INFO]   541 B     build\static\css\main.073c9b0a.css
[INFO]
[INFO] The project was built assuming it is hosted at /.
[INFO] You can control this with the homepage field in your package.json.
[INFO]
[INFO] The build folder is ready to be deployed.
[INFO] You may serve it with a static server:
[INFO]
[INFO]   npm install -g serve
[INFO]   serve -s build
[INFO]
[INFO] Find out more about deployment here:
[INFO]
[INFO]   https://cra.link/deployment
[INFO]
[INFO] Done in 8.49s.
[INFO]
[INFO] --- maven-resources-plugin:3.2.0:copy-resources (copy-resources) @ react-fe-spring-boot ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 15 resources
[INFO]
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ react-fe-spring-boot ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 1 resource
[INFO] Copying 0 resource

There you have it. Serving a Rect app through Spring Boot's fat jar and embedded Tomcat. Plus building it in one command! Grab the full repo here, github.com/jpllosa/react-fe-spring-boot