vitejs / vite

Next generation frontend tooling. It's fast!
http://vite.dev
MIT License
68.49k stars 6.18k forks source link

Clearing `require` cache impacts other processes and causes side effects #12313

Closed christian-bromann closed 1 year ago

christian-bromann commented 1 year ago

Describe the bug

Hi 👋 I am maintaining a Vite plugin for WebdriverIO to start a Vite server as part of a setup routine to test ones application. I am running into an issue when trying to start a Vite server alongside another process.

The procedure is as follows:

I traced it down to the following code snippet: https://github.com/vitejs/vite/blob/9885f6f113667c1e161dee5f30af1e91aeefa62f/packages/vite/src/node/config.ts#L1101-L1103:

    // clear cache in case of server restart
    delete _require.cache[_require.resolve(fileName)]
    const raw = _require(fileName)
    _require.extensions[loaderExt] = defaultLoader

It seems like caching the require cache causes Node to garbage collect the Chromedriver plugin causing the started Chromedriver process to shut down. The Chromedriver plugins runs as ESM code but the project I am working on is CJS (e.g. the vite.config.ts is CJS).

Reproduction

n/a

Steps to reproduce

You see in the logs that Chromedriver starts on port 9515 by the Chromedriver service as well as Vite server start successfully. However when the WebDriver session is being initialised, port 9515 is not accessible anymore.

System Info

System:
    OS: macOS 12.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 371.53 MB / 32.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 18.12.1 - ~/.nvm/versions/node/v18.12.1/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v18.12.1/bin/yarn
    npm: 8.19.2 - ~/.nvm/versions/node/v18.12.1/bin/npm
  Browsers:
    Brave Browser: 110.1.48.171
    Chrome: 110.0.5481.177
    Firefox: 109.0
    Firefox Nightly: 103.0a1
    Safari: 15.2
  npmPackages:
    @vitejs/plugin-vue: ^2.3.1 => 2.3.3
    vite: ^2.9.5 => 2.9.12

Used Package Manager

npm

Logs

2023-03-06T19:21:54.654Z INFO chromedriver: Initiate Chromedriver Launcher (v8.1.1)
2023-03-06T19:21:54.654Z INFO wdio-vite-service: Initiate Vite Service (v1.0.2)
2023-03-06T19:21:54.654Z INFO @wdio/cli:launcher: Run onPrepare hook
2023-03-06T19:21:54.660Z INFO chromedriver: Start Chromedriver (/Users/christianbromann/Sites/projects/trelloapp-vue-vite-ts/node_modules/chromedriver/lib/chromedriver/chromedriver) with args --port=9515 --url-base=/
2023-03-06T19:21:54.690Z INFO chromedriver: Starting ChromeDriver 110.0.5481.77 (65ed616c6e8ee3fe0ad64fe83796c020644d42af-refs/branch-heads/5481@{#839}) on port 9515
2023-03-06T19:21:54.691Z INFO chromedriver: Only local connections are allowed.
2023-03-06T19:21:54.691Z INFO chromedriver: Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
2023-03-06T19:21:54.712Z INFO chromedriver: ChromeDriver was started successfully.
...
2023-03-06T19:23:42.472Z INFO wdio-vite-service: Vite server started on http://localhost
[0-0] 2023-03-06T19:23:43.200Z INFO webdriver: Initiate new session using the WebDriver protocol
[0-0] 2023-03-06T19:23:43.267Z INFO webdriver: [POST] http://localhost:9515/session
[0-0] 2023-03-06T19:23:43.268Z INFO webdriver: DATA {
[0-0]   capabilities: {
[0-0]     alwaysMatch: { browserName: 'chrome', acceptInsecureCerts: true },
[0-0]     firstMatch: [ {} ]
[0-0]   },
[0-0]   desiredCapabilities: { browserName: 'chrome', acceptInsecureCerts: true }
[0-0] }
[0-0] 2023-03-06T19:23:43.279Z ERROR webdriver: RequestError: connect ECONNREFUSED ::1:9515
...

Validations

bluwy commented 1 year ago

I'm not sure how this can be fixed because clearing require is needed to re-read the config. IIUC WebdriverIO spawns a Vite server here, would using cp.spawn or execa help with this quirk? since it feels like a Nodejs bug. Otherwise I think it's good to encourage "type": "module" too to avoid CJS. Most of Vite starters now are ESM-first.

christian-bromann commented 1 year ago

Otherwise I think it's good to encourage "type": "module" too to avoid CJS. Most of Vite starters now are ESM-first.

The ecosystem is moving slow so not all users have been migrated their projects to ESM but you are right, most of the Vite users likely use ESM anyway so I feel like the amount of folks running into this is low.

would using cp.spawn or execa help with this quirk?

Yes, if I start Vite this way it works. I guess I can just check for the environment and one or the other. I will close this as I think it is easier to workaround it on my side than fixing it on Vite. Thanks for the feedback.