Skip to content

Client HMR codegen drops some bindings from hmr.imports destructuring on long re-export barrels (breaks @apollo/client v4) #29781

@Alex-Ferreli

Description

@Alex-Ferreli

What version of Bun is running?

1.3.13 on Linux 6.8.0-110-generic (Ubuntu).

What platform is your computer?

Linux x86_64.

What steps can reproduce the bug?

bun init a React project (or use bun create react).
bun add @apollo/client graphql

In the client entry, instantiate Apollo Client:

import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client";

new ApolloClient({
  link: new HttpLink({ uri: "https://rickandmortyapi.com/graphql" }),
  cache: new InMemoryCache(),
});

Load the page in a browser.

What is the expected behavior?

The Apollo Client instantiates without error.

What do you see instead?

Browser console:

TypeError: import_internal41.storeKeyNameFromField is not a function
    at Policies.getStoreFieldName (cache/inmemory/policies.js)
Root cause (from inspecting /_bun/client/<hash>.js):

The HMR-bundled module for @apollo/client/utilities/internal/index.js declares 8 of its re-exports as empty objects, then omits them from the hmr.imports destructuring that initializes the rest:

// node_modules/@apollo/client/utilities/internal/index.js (HMR-bundled)
var import_dealias = {};
var import_getGraphQLErrorsFromResult = {};
var import_getStoreKeyName = {};
var import_isPlainObject = {};
var import_mergeDeep = {};
var import_omitDeep = {};
var import_storeKeyNameFromField = {};
var import_stringifyForDisplay = {};
var [
import_argumentsObjectFromField, import_canUseDOM, import_checkDocument,
import_cloneDeep, /* ... ~40 others, but none of the 8 above ... */,
import_caches
] = hmr.imports;

hmr.exports = {
// ...
storeKeyNameFromField: import_storeKeyNameFromField.storeKeyNameFromField, // always undefined
// ...
};
Because those 8 bindings are never reassigned, every consumer that calls e.g. storeKeyNameFromField(...) gets undefined is not a function. cache/inmemory/policies.js is the first hot path to hit this.

The 8 missing names (in source-file order from utilities/internal/index.js):
dealias, getGraphQLErrorsFromResult, getStoreKeyName, isPlainObject, mergeDeep, omitDeep, storeKeyNameFromField, stringifyForDisplay.

Confirmation it's HMR-specific:
bun run build (no HMR) produces a working bundle — the string storeKeyNameFromField doesn't even appear (treeshaken). The bug only reproduces when Bun.serve({ development: { hmr: true } }) serves the client bundle from /_bun/client/*.js.

Workaround:
Set development.hmr: false in the Bun.serve config.

Hypothesis:
Likely a deduplication step in the HMR codegen that removes entries from the hmr.imports destructuring when their import name collides/overlaps with a pre-declared binding, but fails to also drop the empty var import_X = {} shim — or vice versa, fails to wire the shim through.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions