Deployment - replace existing content (npm error: "Refusing to install package with name...")

Hello!
I have a question regarding the deployment step where the new content (in the clone directory) should replace the existing site. If someone have some info on that I would be happy.

I have gitlab runner installed on the remote server, registered as a “specific” runner, and it works.

The runner clones the repository into a specific folder ( which is $CI_PROJECT_DIR.).

From this point I’m not sure whatr the conventional step is. I assume I need to move the content to the folder where the live site is. I have these steps in the yml file:

- cp -R $CI_PROJECT_DIR /var/www
- npm install /var/www/my-project
- npm run buildprod /var/www/my-project
- composer install -d=/var/www/my-project

The first line (cp) copies the folder contents into the existing project folder and, as I’ve understood it, replaces files that have the same filename (while other existing files will still remain).

When doing npm install however, I get this error:

Refusing to install package with name "myproject" under a package also called "myproject".

But there is no package with the same name as the project. It doesn’t matter if I rename the project in package.json.
I don’t know if the npm install starts before the previous step is finished (just a guess) and there is some kind of timing conflict. But if I ssh into the server I can run “npm install” with no problem.
Also I had to remove the .git folder which is included, so when replacing it there is the error
cp: cannot create regular file '/var/www/my-project/.git/objects/78/d155142128e1489a415a58b7fdbfdbb5f3404b

So I remove it first: rm -r -f /var/www/my-project/.git

But I don’t think the conventional way would be to erase the the project folder /var/www/myproject before moving the new content. Because then with each deployment you would have to download all dependencies each time?

But to summarize - my problem is the error Refusing to install package...
But I’m also wondering about what is the conventional way to update the existing content with the new cloned content. I have not seen this step documented or demonstrated on the internet.