Skip to content

fix: discover npm components declared in webui-press config#371

Merged
mohamedmansour merged 1 commit into
mainfrom
mohamedmansour/fix-npm-component-discovery
Jun 25, 2026
Merged

fix: discover npm components declared in webui-press config#371
mohamedmansour merged 1 commit into
mainfrom
mohamedmansour/fix-npm-component-discovery

Conversation

@mohamedmansour

Copy link
Copy Markdown
Contributor

Closes #370.

Problem

External components declared as npm packages in a webui-press config.json components array (e.g. "@mai-ui") were never discovered — the build failed with either Component path not found: /<project>/@mai-ui or Could not find node_modules/ directory (searched upward from /var/folders/...).

Two coupled causes:

  1. webui-press mangled the specifier. Every configured source was resolved with current_dir().join(source), turning the npm specifier @mai-ui into an absolute path /<project>/@mai-ui. webui-discovery then classified it as a local path and failed.
  2. Discovery anchored at the wrong directory. npm discovery walks up for node_modules/ from the build app directory. webui-press renders each page from a synthesized scratch dir in the system temp folder, which has no node_modules ancestor — so even a correctly-bare @scope could not be resolved.

Changes

webui-discovery

  • Add find_node_modules_with_fallback(primary, fallback), used by resolve(): walk up from the app directory first, then from the process working directory (the project root the command was invoked in). The primary error is preserved when both fail. Normal webui build/serve is unaffected — the app dir is already inside the project, so the fallback never triggers there.
  • Expose pub fn is_local_source(&str) -> bool as the single source of truth for path-vs-npm classification; classify_source now delegates to it.

webui-press

  • Resolve configured component sources through webui_discovery::is_local_source: npm names/scopes stay bare (so discovery resolves them from node_modules), while local paths are still made absolute against the project root. Adds microsoft-webui-discovery as a direct dependency.

Why this approach

Discovery already receives the app directory; the only gap is that webui-press's app dir is a throwaway scratch dir outside the project. A cwd fallback fixes that at the source without a new BuildOptions field and without relocating scratch into the project tree (which would otherwise need to be git-ignored and watcher-ignored).

Testing

  • cargo test -p microsoft-webui-discovery (34 passed) and -p microsoft-webui-press (45 passed), including new tests for the fallback resolver, is_local_source, and webui-press config source resolution.
  • cargo fmt + cargo clippy clean on both crates.
  • End-to-end: a press site with "@mai-ui" in config now builds and renders all 15 <mai-*> tags (button, link, text-input, spinner, divider, dropdown, listbox, menu-button, menu-item, menu-list, option, tab, tablist, tree, tree-item).

Compatibility

Behavior-preserving for existing builds. The fallback only adds a resolution path when the primary walk-up finds no node_modules; it never overrides a successful primary match. is_local_source is purely a refactor of existing classification logic.

External components declared as npm packages in a webui-press
`config.json` `components` array (e.g. `"@mai-ui"`) failed to build with
either:

  Component path not found: <project>/@mai-ui

or, once the name reached discovery intact:

  Component discovery error: Could not find node_modules/ directory
  (searched upward from /var/folders/.../webui-press-404-...)

Two coupled causes:

1. webui-press prefixed every configured component source with the
   working directory (`cwd.join(source)`), turning the npm specifier
   `@mai-ui` into an absolute path. `webui-discovery` then classified it
   as a local filesystem path and failed to find it.

2. npm discovery anchors its `node_modules` walk-up at the build app
   directory. webui-press renders each docs page from a synthesized
   scratch directory in the system temp folder, which has no
   `node_modules` ancestor, so even a correctly-bare `@scope` specifier
   could not be resolved.

Fixes:

- webui-discovery: add `find_node_modules_with_fallback`, used by
  `resolve`, which walks up from the app directory first and then from
  the process working directory (the project root the command was run
  in). Normal CLI builds are unaffected because the app directory is
  already inside the project.
- webui-discovery: expose `is_local_source` as the single source of
  truth for path-vs-npm classification (`classify_source` now delegates
  to it).
- webui-press: resolve configured component sources through
  `is_local_source` so npm names/scopes stay bare while local paths are
  still made absolute against the project root.

Adds unit tests for the fallback resolver, the shared classifier, and
the webui-press config source resolution.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mohamedmansour mohamedmansour requested a review from akroshg June 25, 2026 19:38
@mohamedmansour mohamedmansour merged commit 0116e3e into main Jun 25, 2026
21 checks passed
@mohamedmansour mohamedmansour deleted the mohamedmansour/fix-npm-component-discovery branch June 25, 2026 21:04
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.

[Bug]: webui-press does not discover npm-package components declared in config.json

3 participants