Skip to content

v0.0.13 cross-package fix doesn't cover workspace-member modules + dep-scan still errors #156

Description

@antosubash

v0.0.13 fixed wheel-installed module pages, but the same crash still hits workspace-member module pages because in an npm-workspaces layout fsRoot IS the workspace root, so workspace-member pages sit under fsRoot and the new plugin's early-return excludes them.

Where the bug is

The plugin added in #154 short-circuits before the workspace-root re-resolution:

// host/client_app/vite.config.ts (v0.0.13)
async resolveId(source, importer) {
  
  const importerPath = importer.split('?')[0];
  if (importerPath.startsWith(fsRootPrefix)) return null;   // ← skips workspace modules
  if (!modulePagesPrefixes.some((prefix) => importerPath.startsWith(prefix))) {
    return null;
  }
  
}

For a wheel-installed module the importer is /repo/.venv/.../site-packages/<pkg>/pages/... which is outside fsRoot (= host/client_app or workspace root), so the early-return is skipped and the workspace-root resolution runs — works.

For a workspace-member module the importer is /repo/modules/<name>/<pkg>/pages/.... In npm-workspaces (workspaces: ["host/client_app", "modules/*"]) deps hoist to /repo/node_modules, so fsRoot resolves to /repo and fsRootPrefix = "/repo/". The importer starts with that prefix → plugin returns null → Vite's default resolver walks up from pages/lib/ looking for node_modules, never finds one before hitting /repo/node_modules (which it can't see through the importer-relative walk), and the scan-imports phase fails:

Error: The following dependencies are imported but could not be resolved:
  maplibre-gl (imported by /repo/modules/gis/gis/pages/lib/maplibre.ts)
  pmtiles    (imported by /repo/modules/gis/gis/pages/lib/maplibre.ts)

Minimal repro

In any smpy new-scaffolded app, add a workspace module that imports a cross-package bare specifier:

smpy create-module gis --dest modules/gis
# Add maplibre-gl + pmtiles to modules/gis/package.json
# Add `import maplibregl from 'maplibre-gl'` to modules/gis/gis/pages/Browse.tsx
npm install        # hoists to /repo/node_modules
make dev           # Vite fails with "could not be resolved"

Proposed fix

Drop the early-return so the plugin fires for any module-pages importer regardless of fsRoot containment, and only skip when the importer is genuinely outside the module-pages set:

const importerPath = importer.split('?')[0];
if (!modulePagesPrefixes.some((prefix) => importerPath.startsWith(prefix))) {
  return null;
}
const resolved = await this.resolve(source, fakeWorkspaceImporter, { skipSelf: true });
return resolved ?? null;

The workspace-root re-resolution is correct in both cases — wheel modules need it because their importer path doesn't transit <repo>/node_modules, and workspace members need it because esbuild's relative node_modules walk doesn't reach the hoisted root.

Extra: dep-scan path

The dev-server resolve pass goes through environment.pluginContainer.resolveId(...) which calls the user's Vite plugins, but the dep-scan pass uses esbuild via optimizeDeps.esbuildOptions and does not (I checked by adding a debug console.log to the plugin: never fires for unresolvable bare specifiers during the scan, even though the same plugin is registered in the config root).

Confirming this: with the if (importerPath.startsWith(fsRootPrefix)) return null line dropped locally, the scan still errors with the same message. The Vite plugin is correct for dev resolves; the scan needs a parallel optimizeDeps.esbuildOptions.plugins esbuild plugin that does the same workspace-root re-resolution. (I tried this locally with require.resolve({ paths: [fsRoot] }) returning { path, external: true } from onResolve; the bare imports still ended up in missing[]. Worth investigating whether the scan plugin order or filter shape is wrong, or whether optimizeDeps.include populated transitively from collectOptimizeIncludes is supposed to suppress the missing check for these specifiers — for us it doesn't.)

Environment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions