Skip to content

fix(style-dependencies): use absolute paths from sys.readDir in collectTsxFiles - #17

Merged
davidpett merged 1 commit into
mainfrom
fix/collect-tsx-absolute-paths
Jun 11, 2026
Merged

davidpett merged 1 commit into
mainfrom
fix/collect-tsx-absolute-paths

Conversation

@davidpett

Copy link
Copy Markdown
Collaborator

Follow-up to #16 (v0.5.1). The seeding and re-export work shipped correctly, but getComponentStyleDependencies() still returned empty maps (byComponent=0, byStyle=0) on every project — traced to a path bug in collectTsxFiles, independent of the seeding work.

The bug

collectTsxFiles built each child path with path.join(dir, entry), but Stencil's sys.readDir() already returns full normalized paths, not basenames (confirmed in stencil-public-compiler.d.ts: "All return paths are full normalized paths, not just the basenames."). So path.join doubled the path and every sys.stat failed with ENOENT, leaving the file list empty — the map was always empty for every consumer.

const entries = await sys.readDir('/abs/project/src')
// entries[0] === '/abs/project/src/components'        <-- already absolute
path.join('/abs/project/src', entries[0])
// === '/abs/project/src/abs/project/src/components'    <-- doubled, ENOENT

The fix

Use the entry directly, since sys.readDir already returns absolute paths:

for (const entry of entries) {
  const fullPath = entry // sys.readDir() returns full normalized paths
  ...
}

Tests

The existing rebuildStyleMap test mock returned basenames from readDir (['cmp.tsx']), contradicting the real contract — which is why it passed against the buggy code. Corrected the mocks to return absolute paths and added a nested-directory case (src/components/my-cmp/my-cmp.tsx) that exercises the recursion.

Verified both updated tests fail against the pre-fix implementation and pass with the fix.

Test plan

  • pnpm exec vitest run test/ (21 passing)
  • pnpm lint
  • pnpm build — confirmed compiled collectTsxFiles uses const fullPath = entry
  • Reporter verified against the storybook plugin e2e suites (eager + lazy: HMR incl. stylesheet + render all green) with the consumer-side seed removed

…ctTsxFiles

Stencil's sys.readDir returns full normalized paths, not basenames, so
path.join(dir, entry) doubled every path and made each sys.stat fail with
ENOENT. The file list came back empty and getComponentStyleDependencies()
always returned empty maps for every consumer. Use the entry directly.

Also correct the test mocks, which previously returned basenames from
readDir (contradicting the real contract) and so passed against the buggy
implementation. Add a nested-directory regression case.
@davidpett
davidpett merged commit d355d3d into main Jun 11, 2026
10 checks passed
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.

1 participant