Shopify / hydrogen

Hydrogen lets you build faster headless storefronts in less time, on Shopify.
https://hydrogen.shop
MIT License
1.41k stars 267 forks source link

CommonJS dependency incompatibility: `ReferenceError: require is not defined` #2129

Closed cwkosman closed 5 months ago

cwkosman commented 5 months ago

What is the location of your example repository?

https://github.com/ninetailed-inc/ninetailed-hydrogen

Which package or tool is having this issue?

Hydrogen

What version of that package or tool are you using?

2024.4.2

What version of Remix are you using?

^2.8.0

Steps to Reproduce

  1. Create new Hydrogen project and install deps
  2. npm install a dependency that uses CommonJS syntax. In the provided example URL, I use @ninetailed/experience.js-react and i18n-iso-countries as examples.
  3. Import a function from the dependency. For example: import {NinetailedProvider} from '@ninetailed/experience.js-react' or import {getAlpha2Codes} from 'i18n-iso-countries'
  4. Run npm run dev
  5. Receive error: ReferenceError: require is not defined error.

Expected Behavior

The Vite bundler should be able to handle CommonJS dependencies (https://vitejs.dev/guide/dep-pre-bundling#the-why | https://shopify.engineering/developer-experience-with-hydrogen-and-vite), and the project would boot in dev mode by using Vite's depedency pre-bundling. A test case of spinning up a new non-Hydrogen Remix project produces the expected behaviour where modules with CommonJS syntax are handled without error: https://github.com/ninetailed-inc/ninetailed-remix

Actual Behavior

Error output to console. Full error log:

ReferenceError: require is not defined
    at /Users/cwk/projects/hydrogen-quickstart/node_modules/@ninetailed/experience.js-shared/node_modules/i18n-iso-countries/index.js:3:15
    at Object.runViteModule (Users/cwk/projects/hydrogen-quickstart/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1181:17)
    at ViteRuntime.directRequest (Users/cwk/projects/hydrogen-quickstart/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1026:78)
    at ViteRuntime.cachedRequest (Users/cwk/projects/hydrogen-quickstart/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:949:28)
    at request (Users/cwk/projects/hydrogen-quickstart/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:976:128)
    at /node_modules/@ninetailed/experience.js-shared/index.esm.js?v=e6bb8ae0:2:31
    at Object.runViteModule (Users/cwk/projects/hydrogen-quickstart/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1181:11)
    at ViteRuntime.directRequest (Users/cwk/projects/hydrogen-quickstart/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1026:60)
    at ViteRuntime.cachedRequest (Users/cwk/projects/hydrogen-quickstart/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:950:79)
    at /node_modules/@ninetailed/experience.js/index.esm.js?v=e6bb8ae0:1:110

Note that the Ninetailed module itself uses ESM syntax to export NinetailedProvider. The error throws on it's dependency i18n-iso-countries, which uses CJS. This is also reproducible by importing functions from i18n-iso-countries directly.

frandiox commented 5 months ago

Hey 👋

This is a known issue (1, 2) when running on a worker environment such as MiniOxygen, which is what the oxygen() plugin is adding.

So far, you need to add these CJS dependencies manually to your Vite config in the ssr.optimizeDeps.include array.

We are soon releasing a tool to do this automatically: https://github.com/Shopify/hydrogen/pull/2106 Hopefully at some point Vite itself will be able to discover these CJS dependencies for the server (right now it only does it for the browser because the server is normally Node.js).

duncan-fairley commented 5 months ago

ssr.optimizeDeps.include did the trick. Thanks @frandiox!