vitejs / vite

Next generation frontend tooling. It's fast!
http://vitejs.dev
MIT License
66.21k stars 5.92k forks source link

Inconsistent behaviour optimising dependencies #12505

Open marcolarosa opened 1 year ago

marcolarosa commented 1 year ago

Describe the bug

I've written a vue plugin that i'm distributing via npm: https://github.com/describo/crate-builder-component

Recently (the last few weeks maybe?) I've seen that i get errors relating to commonjs dependencies used in the plugin when I try to use it in something. Example repo is @ https://github.com/marcolarosa/vite-dependency-test. The only thing in this test repo is a basic vite configuration and the plugin.

The really odd thing is that I use vite to develop the plugin and I don't see this issue. Vite is optimising dependencies as expected without any special config. This seems to only happen when the plugin is included from node_modules.

Reproduction

https://github.com/marcolarosa/vite-dependency-test

Steps to reproduce

Run npm install and npm run dev then check the browser console.

Here's the output in chrome: Screenshot 2023-03-21 at 10 19 40 am

And here's the terminal log with DEBUG=vite:deps Screenshot 2023-03-21 at 10 19 44 am

So vite is finding my plugin and optimising it, but the lodash library (in this case, it can be other dep's that throw the same error) is causing an issue.

The really odd thing is that sometimes after removing node_modules and reinstalling, it will work once but then restarting the dev server causes the issue to reappear. But I can't reliably reproduce this.

I've tried editing the order of the plugins in the vite config (swapping commonjs and vue plugins around); defining the plugin in optimizeDeps.include; and adding the plugin js files to optimizeDeps.entries.

System Info

System:
    OS: macOS 13.2.1
    CPU: (10) arm64 Apple M1 Max
    Memory: 831.25 MB / 64.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.12.1 - ~/.nvm/versions/node/v18.12.1/bin/node
    npm: 8.19.2 - ~/.nvm/versions/node/v18.12.1/bin/npm
  Browsers:
    Brave Browser: 111.1.49.120
    Chrome: 111.0.5563.64
    Firefox: 111.0
    Safari: 16.3
  npmPackages:
    @vitejs/plugin-vue: ^4.1.0 => 4.1.0
    vite: ^4.2.1 => 4.2.1

Used Package Manager

npm

Logs

VITE v4.2.1 ready in 159 ms

➜ Local: http://localhost:5173/ ➜ Network: use --host to expose ➜ press h to show help vite:deps deps bundled in 1207.35ms +1s vite:deps ✨ static imports crawl ended +38ms vite:deps ✨ new dependencies were found while crawling that weren't detected by the scanner +1ms vite:deps ✨ re-running optimizer +0ms vite:deps new dependencies found: @describo/crate-builder-component, vue, @describo/crate-builder-component/src/crate-builder/index.js +2ms vite:deps deps bundled in 420.75ms +421ms vite:deps ✨ dependencies optimized +1ms vite:deps ✨ static imports crawl ended +2s

Validations

marcolarosa commented 1 year ago

Still trying to work this out. Running vite with full debug and grepping for cloneDeep (using this example) shows that vite is finding the file and transforming it:

$ DEBUG=* npm run dev 2>&1  | grep cloneDeep
2023-03-25T04:20:07.316Z vite:resolve 0.18ms lodash/cloneDeep -> /Users/mlarosa/src/describo/tmp/test/node_modules/lodash/cloneDeep.js?v=65c9d623
2023-03-25T04:20:07.316Z vite:resolve 0.05ms /node_modules/lodash/cloneDeep.js?v=65c9d623 -> /Users/mlarosa/src/describo/tmp/test/node_modules/lodash/cloneDeep.js?v=65c9d623
2023-03-25T04:20:07.387Z vite:load 66.78ms [fs] /node_modules/lodash/cloneDeep.js?v=65c9d623
2023-03-25T04:20:07.387Z vite:import-analysis 0.00ms [no imports] node_modules/lodash/cloneDeep.js?v=65c9d623
2023-03-25T04:20:07.387Z vite:transform 0.11ms /node_modules/lodash/cloneDeep.js?v=65c9d623
Sat, 25 Mar 2023 04:20:07 GMT connect:dispatcher viteTimeMiddleware  : /node_modules/lodash/cloneDeep.js?v=65c9d623
Sat, 25 Mar 2023 04:20:07 GMT connect:dispatcher corsMiddleware  : /node_modules/lodash/cloneDeep.js?v=65c9d623
Sat, 25 Mar 2023 04:20:07 GMT connect:dispatcher viteServePublicMiddleware  : /node_modules/lodash/cloneDeep.js?v=65c9d623
Sat, 25 Mar 2023 04:20:07 GMT connect:dispatcher viteTransformMiddleware  : /node_modules/lodash/cloneDeep.js?v=65c9d623
2023-03-25T04:20:07.684Z vite:cache [memory] /node_modules/lodash/cloneDeep.js?v=65c9d623
2023-03-25T04:20:07.684Z vite:time 0.16ms /node_modules/lodash/cloneDeep.js?v=65c9d623

So the 3rd line loads it vite:load The 4th says there's no imports vite:import-analysis And the 5th transforms it: vite:transform

Seem like vite is handling the cloneDeep import which then raises the question of why the browser console reports no default export for cloneDeep.

Also my colleage @alvinsw reports that there are no issues running vite preview and vite build; only vite dev seems to be failing.

Leuchak commented 1 year ago

I have the same issue. image

// imported file content
export enum APIResponseStatusEnum {
  ERROR = 0,
  SUCCESS = 1,
}
import "/node_modules/.vite/deps/chunk-RSJERJUL.js?v=3f51cee7";

// node_modules/@evvue/src/typing/api/APIResponseStatusEnum.ts
var APIResponseStatusEnum = /* @__PURE__ */ ((APIResponseStatusEnum2) => {
  APIResponseStatusEnum2[APIResponseStatusEnum2["ERROR"] = 0] = "ERROR";
  APIResponseStatusEnum2[APIResponseStatusEnum2["SUCCESS"] = 1] = "SUCCESS";
  return APIResponseStatusEnum2;
})(APIResponseStatusEnum || {});
export {
  APIResponseStatusEnum
};
//# sourceMappingURL=@evvue_typing_api_APIResponseStatusEnum.js.map

If I copy the file into my project and use this file instead, I get this and it work:

export var APIResponseStatusEnum = /* @__PURE__ */
((APIResponseStatusEnum2)=>{
    APIResponseStatusEnum2[APIResponseStatusEnum2["ERROR"] = 0] = "ERROR";
    APIResponseStatusEnum2[APIResponseStatusEnum2["SUCCESS"] = 1] = "SUCCESS";
    return APIResponseStatusEnum2;
}
)(APIResponseStatusEnum || {});
//# sourceMappingURL=...
silverwind commented 1 year ago

Vite can not correctly deal with dependency chains of mixed ESM and CJS:

App -> ESM works App -> CJS works App -> ESM -> ESM works App -> ESM -> CJS fails

There is a suggested workaround via optimizeDeps.include that each module consumer would have to add, so it's far from a usable solution.

The only reliable workaround is to bundle your ESM modules that have CJS dependencies themselves, but that comes at the cost of dependency duplication.

marcolarosa commented 1 year ago

@silverwind Thanks for the info!

I don't understand why vite can deal with mixed esm / cjs imports when in development but not when the code is called from node_modules but am happy to accept it as it is. I did try the optimizeDeps.include option but I couldn't get it to work. Presumably I was doing something incorrectly.

In the end I needed to do the following in case others come across this issue:

Kansuler commented 1 year ago

I'm also having issues with this, I'm trying to use @google-cloud/firestore on backend in the endpoints, and I get the error ReferenceError: __dirname is not defined

I've figured out that the dependency @grpc/grpc-js and @grpc/proto-loader are using __dirname, and they are sub-dependencies to google-gax which is used by @google-cloud/firestore.

I've tried to add them to vite.config.ts like this:

optimizeDeps: {
    include: ['google-gax > @grpc/grpc-js', 'google-gax > @grpc/proto-loader'],
}

and

optimizeDeps: {
    include: ['@google-cloud/firestore > google-gax > @grpc/grpc-js', '@google-cloud/firestore > google-gax > @grpc/proto-loader'],
}

without success.

Xorba001 commented 10 months ago

I was reading on microservices from gRPC page using Node.js and found your project. It can be used for Inter-microservice communication.

Here was the informative page i was on that brought my searching. Maybe some of the included information can help further document this @grpc/grpc-js dependency.

https://blog.logrocket.com/communicating-between-node-js-microservices-with-grpc/

jam-fran commented 5 months ago

@Kansuler Did you ever find a solution or workaround for the __dirname issue? I'm running into the same thing and feel like I've tried every single vite configuration with no luck.