Skip to content
This repository was archived by the owner on Oct 4, 2026. It is now read-only.

webpack_server: regenerate the package manifest PnP removed - #20

Merged
slarson-redo merged 1 commit into
mainfrom
slarson/webpack-server-pnp-manifest
Sep 3, 2026
Merged

slarson-redo merged 1 commit into
mainfrom
slarson/webpack-server-pnp-manifest

Conversation

@slarson-redo

Copy link
Copy Markdown
Contributor

Problem

97e3e9b (Use Yarn PnP for nodejs_binary) dropped the CommonJS package manifest and the NODE_PACKAGE_MANIFEST export from nodejs/runner.sh.tpl. webpack/server/src/index.ts still reads that variable, so every webpack_server binary dies at startup:

Error: Unsupported path type: undefined
    at NodePathFS.mapToBase (…webpack.server_bin.pnp.cjs:10109:11)
    at NodePathFS.readFileSync (…webpack.server_bin.pnp.cjs:8665:42)
    at Object.<anonymous> (external/rules_javascript+/webpack/server/src/index.js:17:61)

(fs.readFileSync(undefined, "utf8"), via PnP's patched fs.)

Why the manifest is not vestigial

PnP resolves the dev server's own requires, so the obvious fix — deleting the manifest read — looked right. It isn't. The dev server bundles files out of the tool tree, and webpack resolves their imports from the filesystem, where PnP materializes nothing. Removing the fs-linker view instead produces:

ERROR in …/redo_npm_webpack_5.94.0/files/hot/emitter.js
Module not found: Error: Can't resolve 'events'
ERROR in …/redo_npm_pmmmwh_react-refresh-webpack-plugin_0.5.17/files/client/ReactRefreshEntry.js
Module not found: Error: Can't resolve 'core-js-pure/features/global-this'

and, before that, webpack-dev-server's isInstalled node_modules walk fails, so it prompts to yarn add -D webpack-cli. (webpack/runtime only fakes process.versions.pnp for webpack's own checkPackageExists, not for the dev server's isInstalled.)

Fix

webpack_server generates the manifest itself instead of borrowing nodejs_binary's.

It needs the server binary's CommonJS graph in the binary's own configuration — a plain cfg = "exec" attribute would not match, because nodejs_binary's dep goes through nodejs_transition (//javascript:module = "node"), and mismatched paths would make the manifest point at files that are not in runfiles. So nodejs_binary forwards its dep's CjsInfo, WebpackInfo carries it as server_cjs, and _webpack_server_impl runs gen_manifest over it with to_rlocation_path package paths — the same shape nodejs_binary used to emit. webpack/server-runner.sh.tpl exports NODE_PACKAGE_MANIFEST from it; the shim is unchanged.

Verification

Against redo at the 4b6fe19 pin, carrying this as an archive_override patch:

  • bazel run //redo/shopify/extension:server — starts, webpack 5.94.0 compiled successfully, no unresolved modules, serves main.js with HTTP 200 / 6,132,734 bytes.
  • Every webpack_server, webpack_bundle, and nodejs_binary target in redo builds.

Before the fix, the same target crashed on NODE_PACKAGE_MANIFEST at startup.

`nodejs_binary` used to write a CommonJS package manifest and export it as
`NODE_PACKAGE_MANIFEST`; the Yarn PnP migration dropped both. The webpack dev
server shim still reads that variable, so every `webpack_server` binary now
dies at startup:

    Error: Unsupported path type: undefined
        at NodePathFS.readFileSync (...pnp.cjs)
        at Object.<anonymous> (webpack/server/src/index.js:17)

The manifest is not vestigial. PnP resolves the dev server's own `require`s,
but webpack *bundles* files out of that tree -- its hot client, and the
entries plugins such as @pmmmwh/react-refresh-webpack-plugin inject -- and
webpack resolves their imports from the filesystem, where PnP materializes
nothing. Without the fs-linker view, `webpack/hot/emitter.js` cannot resolve
`events` and `ReactRefreshEntry.js` cannot resolve `core-js-pure`.
webpack-dev-server's `isInstalled` walk for webpack-cli fails the same way.

So `webpack_server` generates the manifest itself, from the CommonJS graph
`nodejs_binary` now forwards -- carried through `WebpackInfo` so it is built in
the binary's own configuration, which a plain `cfg = "exec"` attribute would
not match (`nodejs_transition` sets `//javascript:module`).

Verified against redo's `//redo/shopify/extension:server`: the dev server
starts, compiles with no unresolved modules, and serves a 6.1 MB `main.js`.
@slarson-redo
slarson-redo merged commit 3dfb292 into main Sep 3, 2026
2 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant