Skip to content

fix: respect absolute paths in handleHotUpdate - #33

Merged
rosskevin merged 1 commit into
alienfast:mainfrom
kainstar:fix/handle-hot-update-absolute-paths
Jun 3, 2026
Merged

rosskevin merged 1 commit into
alienfast:mainfrom
kainstar:fix/handle-hot-update-absolute-paths

Conversation

@kainstar

Copy link
Copy Markdown
Contributor

Problem

handleHotUpdate never reloads the virtual module when paths contains an absolute path.

The current check is:

options.paths.some((p) => file.startsWith(path.join(process.cwd(), p)))

path.join (unlike path.resolve) does not strip an absolute prefix from its later arguments — it just concatenates with a separator:

path.join('/cwd', '/Users/me/project/locales')
// → '/cwd/Users/me/project/locales'   ← nonsense

So when a consumer passes an absolute path (very common — e.g. path.resolve(__dirname, '../resources') in a monorepo where cwd ≠ the project root), the join produces a path no real file starts with, the predicate is always false, and HMR for locale files silently does nothing.

This is independent of any Vite version — handleHotUpdate({ file }) has been absolute since Vite 3.

Fix

Only join with process.cwd() when the configured path is relative; pass absolute paths through as-is.

options.paths.some((p) =>
  file.startsWith(path.isAbsolute(p) ? p : path.join(process.cwd(), p)),
)

Tests

Adds src/__tests__/handleHotUpdate.test.ts covering:

  • absolute paths → reloadModule is called (regression test for this bug)
  • relative paths (relative to cwd) → reloadModule is called
  • file outside configured paths → reloadModule is NOT called
  • file with non-locale extension → reloadModule is NOT called

All 18 tests pass.

How to reproduce the original bug

In any project where the plugin is configured with an absolute path:

i18nextLoader({
  paths: [path.resolve(__dirname, 'locales')],
})

Edit any locale YAML/JSON and observe that the virtual module is never reloaded; you have to restart Vite to see changes.

`path.join(cwd, absolutePath)` does not strip the absolute prefix (unlike
`path.resolve`); it just concatenates with a separator. When the consumer
passes an absolute path to `paths`, the join produces a non-existent path
like `<cwd>/Users/.../resources`, so `file.startsWith(...)` is always
false and the virtual module is never reloaded.

Fix: only prepend cwd when the configured path is not already absolute.

Adds tests covering absolute paths, relative paths, non-locale files, and
files outside the configured paths.
@rosskevin

Copy link
Copy Markdown
Member

@kainstar I'm sorry I missed this notification! Thank you

@rosskevin
rosskevin merged commit 69eb6a5 into alienfast:main Jun 3, 2026
4 checks passed
@rosskevin

Copy link
Copy Markdown
Member

I'll fix the release, I need to do a little tooling maintenance. Should be out soon.

@rosskevin

Copy link
Copy Markdown
Member

Released in v4.0.0

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants