Skip to content

Dev client serves use-sync-external-store/shim/index.js as raw CJS, causing missing named export #1207

@eashish93

Description

@eashish93

use-sync-external-store/shim/index.js served as raw CJS in dev

Versions

  • vinext: 0.0.49
  • vite: 8.0.13
  • next: 16.2.3
  • Router: App Router

Error

In vinext dev, the browser shows:

The requested module '/node_modules/use-sync-external-store/shim/index.js?...'
does not provide an export named 'useSyncExternalStore'

Cause

A dependency imports the React compatibility shim like this:

import { useSyncExternalStore } from 'use-sync-external-store/shim/index.js';

In my app this came from @react-stately/toast.

use-sync-external-store/shim/index.js is CommonJS:

'use strict';

if (process.env.NODE_ENV === 'production') {
  module.exports = require('../cjs/use-sync-external-store-shim.production.js');
} else {
  module.exports = require('../cjs/use-sync-external-store-shim.development.js');
}

But in dev, vinext/Vite serves it to the browser as if it were ESM, so the named export does not exist.

Expected

vinext/Vite should prebundle or transform this common React compatibility shim correctly, or handle the exact nested import path automatically.

Actual

The app fails in the browser with a runtime overlay. The error is technically accurate, but hard to trace back to the nested dependency import.

Workaround

I fixed it by aliasing both shim paths to a local ESM shim:

// use-sync-external-store-shim.ts
import { useSyncExternalStore } from 'react';

export { useSyncExternalStore };

export default { useSyncExternalStore };
// vite.config.ts
import path from 'node:path';

export default defineConfig({
  resolve: {
    alias: [
      {
        find: /^use-sync-external-store\/shim(?:\/index\.js)?$/,
        replacement: path.resolve(__dirname, 'use-sync-external-store-shim.ts'),
      },
    ],
  },
  optimizeDeps: {
    include: [
      'use-sync-external-store/shim',
      'use-sync-external-store/shim/index.js',
    ],
  },
});

After this, vinext dev -- --force loads the affected routes without the browser runtime error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions