Skip to content

webpack: ENOENT on cached virtual modules when resolveId is skipped #618

Description

@rosslh

Environment

unplugin: latest (also present on current main)
webpack: 5
Also seen with Next.js webpack (next dev) when the filesystem cache is enabled

Reproduction

On current main, this unit test fails with ENOENT on _virtual_~demo:

pnpm exec vitest run test/unit-tests/webpack/virtual-cache.test.ts

The case that fails fakes a skipped resolveId (a resolver already returns the _virtual_ path). That is the same skip webpack does when it restores the path from its on-disk cache.

A PR with that test and a fix is at #617.

The on-disk cache path was reproduced by starting and stopping a Next.js webpack app with the filesystem cache enabled. After a restart, compile fails with ENOENT on _virtual_… until the placeholder is created again.

Describe the bug

On webpack, unplugin serves modules that are not real files by creating an empty placeholder in memory during resolveId and pointing the module at a made-up _virtual_ path. The plugin's load hook supplies the real source.

Webpack then stores that _virtual_ path in its on-disk cache. The placeholder never reaches disk, so a new process starts without it.

When the cache is reused, webpack already knows the path and skips resolveId. It then opens the path and fails with ENOENT.

This shows up after a next dev restart, or a CI or Vercel build that reuses .next/cache.

I have a PR for this: #617.

Additional context

Downstream report: unplugin/unplugin-icons#206

Same family as #32 (that issue used the older virtual:~icons/… path).

Logs

Error: ENOENT: no such file or directory, open '/…/_virtual_~demo'

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions