Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to the run vue app with latest vite version 2.9.0 and above #7939

Closed
7 tasks done
sadashivm opened this issue Apr 28, 2022 · 24 comments · Fixed by #8235
Closed
7 tasks done

Unable to the run vue app with latest vite version 2.9.0 and above #7939

sadashivm opened this issue Apr 28, 2022 · 24 comments · Fixed by #8235

Comments

@sadashivm
Copy link

Describe the bug

Hello team,
I've created a latest vue project using below command,
npm init vue@latest
and project was created, in the latest code vite version installed as
"vite": "^2.9.5".

I tried all the versions from 2.9.0 to 2.9.6, but didn't worked. When run the below command,

npm run dev

I'm getting bellow error,

image

I tried all the below versions. I got the same above error,

image

But when I build the application it is working fine. like,

npm run build

Finally I downgraded the vite version to ("vite": "2.8.6"), the app is working properly like,

image

Reproduction

https://github.com/sadashivm/vue3-latest

System Info

OS - Windows 10,
Node - v16.14.2
npm - 8.7.2

Used Package Manager

npm

Logs

12:58:28 pm [vite] error while updating dependencies:
Error: EPERM: operation not permitted, rename 'D:/Vue/vue3-latest/node_modules/.vite/processing' -> 'D:/Vue/vue3-latest/node_modules/.vite/deps'
    at Object.renameSync (node:fs:980:3)
    at commitProcessingDepsCacheSync (D:\Vue\vue3-latest\node_modules\vite\dist\node\chunks\dep-8db0e223.js:37269:21)
    at Object.commit (D:\Vue\vue3-latest\node_modules\vite\dist\node\chunks\dep-8db0e223.js:37261:13)
    at commitProcessing (D:\Vue\vue3-latest\node_modules\vite\dist\node\chunks\dep-8db0e223.js:58587:34)
    at runOptimizer (D:\Vue\vue3-latest\node_modules\vite\dist\node\chunks\dep-8db0e223.js:58625:17)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

Validations

@bluwy
Copy link
Member

bluwy commented Apr 28, 2022

Vite 2.9 has a new prebundling method that does fs.renameSync, which is what the error shows. The relevant code is:

removeDirSync(depsCacheDir)
fs.renameSync(processingCacheDir, depsCacheDir)

We did ensure the .vite/deps is removed before renaming though, so it may be an issue with your system. Perhaps this helps nodejs/node#6335

@patak-dev
Copy link
Member

Do you have an Antivirus enabled? I was checking this related node issue: nodejs/node#29481 (comment)

If that is the case, we could add some retry scheme like graceful-fs is using here: https://github.com/isaacs/node-graceful-fs/blob/main/polyfills.js#L88-L116

@bluwy following the issues, it looks like remove dir sync could return before the directory is properly deleted (because of Antivirus or indexing software locking some files). Looks like they tried to bake a fix in libuv and then they reverted it.

@bluwy
Copy link
Member

bluwy commented Apr 28, 2022

Not a fan of letting these antivirus software "win", but I guess we could implement retries if it's just for this case 😄

@sadashivm
Copy link
Author

Yes I have antivirus active

@sadashivm
Copy link
Author

Team,
What should I do now?
are you giving any fixes?

@bluwy
Copy link
Member

bluwy commented Apr 29, 2022

Turn off your antivirus

@sadashivm
Copy link
Author

Turn off your antivirus

Sorry to say, this is not correct soultion right?

@bluwy
Copy link
Member

bluwy commented May 1, 2022

I'm not the person for security advice so take my comment with a grain of salt, but I've never quite find antivirus software to be really helpful as long as you're browsing safely and only install software you trust. Plus modern browsers all have solid first line of defence to protect you from it. It's worked for me and I never had issues on my machines (windows/linux/mac).

If you're on Windows, you can turn on Windows Defender and remove any other antivirus software. That has worked well even for my 8yo brother who randomly installs stuff 🥲

@mattnathan
Copy link
Contributor

I'm having the same issue. As an experiment I disabled the virus check for my project folder (and sub-folders) but that didn't seem to have an effect.

When I run the vite dev server and check the node_module/.vite folder I see an empty deps folder, and a processing folder with all the lib files in it.

Using vite@2.9.6

@patak-dev
Copy link
Member

@mattnathan @sadashivm would you test vite@2.9.8 in your projects and report back? Thanks!

@sadashivm
Copy link
Author

sadashivm commented May 5, 2022

Wow Great!. It is working perfectly.
Thank you so much @patak-dev

Here is the updated package.json file,

image

I have uninstalled all the dev depency packages and installed the latest one.

It is working as well.

@mattnathan
Copy link
Contributor

Unfortunately this didn't change anything for me, still getting the same error and .vite directory contents

[vite] error while updating dependencies:
Error: EPERM: operation not permitted, rename 'C:\Users\name\path\to\project\node_modules\.vite\processing' -> 'C:\Users\name\path\to\project\node_modules\.vite\deps'

> vite --version
vite/2.9.8 win32-x64 node-v14.17.6

@mattnathan
Copy link
Contributor

mattnathan commented May 5, 2022

I've done some digging (mostly by adjusting the code in my node_modules/vite dir) - here are my findings:

It appears that commitProcessingDepsCacheSync is called twice. The first time it succeeds, the second time it fails. I've been deleting the node_modules/.vite dir between each run, but as it's calling the function twice there's always a deps dir that exists when the second call start.

During the second run, the rename fails with EPERM error, which triggers the retry logic. However the retry logic doesn't retry because the stat call returns a null stater, so the original er is returned without retrying the op. I guess this is correct as this indicates that the to dir exists, so the rename wouldn't work anyway - doesn't help with the underlying intent though.

Adding a sleep (2s, chosen at random) between the "delete deps dir" and "rename processing to deps" steps in commitProcessingDepsCacheSync causes things to work for me.

With all that said I think deleteDirSync is returning before the dir is actually deleted on the fs, it's close but it's still a race. When renameDir runs it hits this error and can't rename to a dirname that already exists, it attempts to retry but isn't retrying enough steps - or is aborting the retry early due to the lack of "not found" in the stat call.

I think that if there were a waitForDirToActuallyBeDeletedOnFs function between the removeDirSync and renameDir this would likely fix my issue (something more intelligent than sleep(2s)). Up to you though, I'm sure there are other ways to get it working.

Thanks for looking into this issue, it's really appreciated.

@patak-dev
Copy link
Member

Hey @mattnathan, I don't know how much better we can do without making this more complex. I would suggest reviewing what kind of processes or antivirus you have in your system. At least without more data about how common this is, I think we may need to wait a bit here. If it is common enough, maybe we could first rename deps to temp, then rename processing to deps and then delete temp 🤔
You could try to modify this line to set GRACEFUL_RENAME_TIMEOUT to 60000 as it was originally in graceful-fs. But if this is taking more than 5 secs in your system... I don't think this will really fix the issue, so again, better to understand what is happening in your system. https://github.com/vitejs/vite/blob/main/packages/vite/src/node/utils.ts#L762

@mattnathan
Copy link
Contributor

I don't think any of those options will work for me.

I've disabled my antivirus completely (temporarily while running these tests), so it's not that, well I don't think it's that - I'm never sure :(.

The value of GRACEFUL_RENAME_TIMEOUT doesn't affect the outcome due to the deps dir still existing when the stat call is made. The check on line 778 fails and the else clause is executed exiting the retry logic before it even has chance to sleep+retry.

I've done a little test adding a fs.existsSync call directly after the removeDirSync call in commitProcessingDepsCacheSync and I get these log lines:

Calling removeDirSync C:/Users/name/path/to/project/node_modules/.vite/deps
Dir exists? false
Calling removeDirSync C:/Users/name/path/to/project/node_modules/.vite/deps
Dir exists? true

The code looks basically like this:

function commitProcessingDepsCacheSync() {
    // Processing is done, we can now replace the depsCacheDir with processingCacheDir
    // Rewire the file paths from the temporal processing dir to the final deps cache dir
    console.log('Calling removeDirSync', depsCacheDir);
    removeDirSync(depsCacheDir);
    console.log('Dir exists?', fs.existsSync(depsCacheDir))
    fs.renameSync(processingCacheDir, depsCacheDir);
}

This all makes me think that there's something strange going on. Why would removeDirSync return when the dir hasn't been removed yet. Or maybe something has re-made it in the meantime.

Changing the code so it's the equivalent to the below, actually results in a different error which surprised me, as the deps dir appears to be empty to me.

console.log('Dir exists before wait?', fs.existsSync(depsCacheDir))
const maxTime = 5000;
const t0 = Date.now();
while((Date.now() - t0) < maxTime && fs.existsSync(depsCacheDir)){
  removeDirSync(depsCacheDir);
}
console.log('Dir exists after wait?', fs.existsSync(depsCacheDir))

// outputs:
Calling removeDirSync C:/Users/name/path/to/project/node_modules/.vite/deps
Dir exists before wait? false
Dir exists after wait? false 
Calling removeDirSync C:/Users/name/path/to/project/node_modules/.vite/deps
Dir exists before wait? true
16:47:02 [vite] error while updating dependencies:
Error: EPERM: operation not permitted, lstat '\\?\C:\Users\name\path\to\project\node_modules\.vite\deps\vuetify.js'

No idea why the first removeDirSync succeeds (but doesn't delete the dir) but the second call, almost immediately afterwards throws an exception. Totally confused!

@patak-dev
Copy link
Member

@mattnathan I think you're right, we may be seeing a bug in the node-graceful-fs rename version we copied. Would you check if #8036 works in your system?

@patak-dev patak-dev reopened this May 5, 2022
@tony19
Copy link
Contributor

tony19 commented May 6, 2022

Related vuejs/core#5823

@tony19
Copy link
Contributor

tony19 commented May 6, 2022

I reproduced the error messages on npm run dev in a project scaffolded from npm init vue in this environment:

OS: Windows 11
Node: 14.17.6, 16.14.2, and 17.4.0
Vite: 2.9.5
Antivirus: K7 Ultimate Security

And verified that updating to Vite 2.9.8 resolved the issue.

@mattnathan Maybe I'm missing something important. What antivirus are you using?

@patak-dev
Copy link
Member

@tony19 would you also test with #8036 in your system to check that also works?

@mattnathan
Copy link
Contributor

Thanks for continuing to look at this, I really appreciate it.

The change made in #8036 hasn't fixed the issue for me, though the change looks worthwhile and I now see a 5s delay before the error shows indicating the retry is executing.

Something I've noticed while I've been trying to create a reproduction repository is that this error is triggered under very specific (but unknown) conditions. There seems to be some timing somewhere that causes this to happen that isn't covered by the retry logic.

As an example, I have a component whose template looks like <div></div>, this does not trigger the issue. When I edit the component template by adding lorem ipsum to it <div>lorem ipsum ...</div> the error is shown. I'm unable to find a pattern to the changes that trigger the error vs those that don't. Sometimes the same change does and doesn't cause the error depending on other changes. Whenever I see symptoms like this I tend to think there's a race/timing/synchronisation issue somewhere.

In all cases I'm using Vuetify and Vue2. I think this is important because the loading of Vuetify causes commitProcessingDepsCacheSync to be called more than once in quick succession, guaranteeing a flow like rename->delete->rename which I think is the underlying cause of the issue I'm seeing, and potentially why others aren't seeing this issue when I am.

// vite.config.js
import {defineConfig} from 'vite';
import {createVuePlugin} from 'vite-plugin-vue2';
import rollupPluginVuetify from 'rollup-plugin-vuetify';
import {VuetifyResolver} from 'unplugin-vue-components/resolvers';
import Components from 'unplugin-vue-components/vite';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    createVuePlugin(),
    Components({
      resolvers: [
        // Vuetify
        VuetifyResolver(),
      ],
    }),
    rollupPluginVuetify(),
  ]
})

@tony19 I've attempted this with Windows Defender, Sentinal One (centrally managed), and with AV turned off completely without change in outcome.

Unfortunately I have been unable to create a reliable reproduction of this issue that I'm happy to share, I have reproduced it in a fresh repo but it feels very flaky so I'm doubtful it would reproduce for all people/runs.

@patak-dev
Copy link
Member

Ok, we'll merge #8036 as that should help others with more intrusive Antivirus. But waiting a few seconds for a rename goes against DX, the whole idea of doing the deleteSync/renameSync was to avoid timing issues. We can leave this issue open for a bit @mattnathan, and see if others are experiencing the same. You could work on a PR to do things differently, but we should really take care of avoiding extra complexity if this actually ends up being an issue in your setup.

One thing you could try (and only for win32)
rename deps -> prev-deps
rename processing -> deps
delete prev-deps

But the initial rename may also fail? Worth trying it though... and you could ask the other users in this issue to try your PR

@mattnathan
Copy link
Contributor

I totally agree, don't want to make life worse for most just for me. Thanks for your time on this so far.

I'll have a go at writing a PR, but I won't be able to look into this until at least w/c 23rd unfortunately.
I have a manual work around for now: If the error happens, manually delete node_modules/.vite/deps and manually rename node_modules/.vite/processing -> deps, restart vite. Luckily I don't change dependencies that often.

@tony19
Copy link
Contributor

tony19 commented May 7, 2022

@patak-dev Oddly, my machine does not produce an error in the fs.rename callback (er is always null for me), even with antivirus enabled, so I cannot verify the change in #8036 (although that change appears correct to me).

It seems replacing fs.renameSync() with the promisify-ied fs.rename() was enough to resolve the problem on my machine.

@mattnathan
Copy link
Contributor

Managed to get around to this a little earlier than expected.
The fix didn't end up being that convoluted, just needed to add the retry logic to the correct operation (removeDir).

Vite with the applied PR now consistently works on my system in places where it used to fail.

@github-actions github-actions bot locked and limited conversation to collaborators Jun 6, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants