Skip to content

Fix dependency resolution: subpath imports, DTS generation, and bundle deduplication#58

Merged
titouanmathis merged 1 commit intodevelopfrom
feature/#57-fix-dependency-resolution
Mar 10, 2026
Merged

Fix dependency resolution: subpath imports, DTS generation, and bundle deduplication#58
titouanmathis merged 1 commit intodevelopfrom
feature/#57-fix-dependency-resolution

Conversation

@titouanmathis
Copy link
Contributor

Summary

Fixes #57 — three related issues in the dependency resolution and bundling pipeline.

1. Subpath specifier handling in resolveDependencies

Problem: For a dependency like @studiometa/js-toolkit/utils, the version was looked up using the full specifier (not found) and the esm.sh URL was incorrectly formatted as esm.sh/@studiometa/js-toolkit/utils@3.4.3 (404).

Fix: Added getPackageName() and getSubpath() helpers that correctly split specifiers. The esm.sh URL is now formatted as esm.sh/@studiometa/js-toolkit@3.4.3/utils.

2. DTS generation silently fails for npm package source values

Problem: Using source: "morphdom" (a bare npm package name) creates a temporary re-export entry that falls outside tsconfig include paths, causing tsdown to silently skip DTS generation.

Fix: Bare npm package names are now rejected as source values with a clear warning. They fall back to esm.sh resolution automatically. The DependencyConfig type JSDoc has been updated to clarify that source only supports local file paths/globs.

3. Self-hosted bundles inline all dependencies, causing duplication

Problem: When @studiometa/ui is self-hosted, tsdown inlines all its dependencies into the output bundle. If those same dependencies are also imported via esm.sh, the browser ends up with two separate instances.

Fix: The plugin now auto-externalizes any specifier that already exists in the import map. The preset passes Object.keys(mergedImportMap) to the plugin constructor so self-hosted bundles emit import ... from "@studiometa/js-toolkit" instead of inlining — the browser's import map resolves it at runtime.

Changes

  • resolve-dependencies.ts: New getPackageName, getSubpath, isLocalSource helpers; fixed esm.sh URL construction; bare npm source rejection with warning
  • PlaygroundDependenciesPlugin.ts: New importMapKeys constructor parameter; pass external to tsdown build
  • playground.ts preset: Pass Object.keys(mergedImportMap) to the plugin
  • Tests: 75 tests passing — new coverage for subpath imports, npm source rejection, importMapKeys
  • README.md: Document subpath imports, clarify source field, add bundle deduplication section, remove duplicated/outdated docs

…ndle deduplication

- Add getPackageName/getSubpath helpers to correctly split specifiers
  like '@studiometa/js-toolkit/utils' into package name + subpath
- Fix esm.sh URL format: version goes on package name before subpath
  (e.g. esm.sh/@scope/pkg@1.0/subpath instead of esm.sh/@scope/pkg/subpath@1.0)
- Reject bare npm package names as source values with a warning and
  esm.sh fallback (source only supports local file paths/globs)
- Auto-externalize import map specifiers in self-hosted bundles to
  prevent duplicating shared dependencies at runtime
- Pass merged import map keys from the preset to PlaygroundDependenciesPlugin
- Update tests to cover subpath imports, npm source rejection, and
  importMapKeys constructor parameter
- Update README: document subpath imports, clarify source field
  requirements, add bundle deduplication section, remove duplicated
  and outdated documentation sections

Closes #57

Co-authored-by: Claude <claude@anthropic.com>
@github-actions
Copy link

Export Size

Unchanged

@studiometa/playground

Name Size Diff
createPlayground 1 B -
unzip 1 B -
zip 1 B -

@cloudflare-workers-and-pages
Copy link

Deploying studiometa-playground with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2f6994f
Status: ✅  Deploy successful!
Preview URL: https://cf52198e.studiometa-playground.pages.dev
Branch Preview URL: https://feature--57-fix-dependency-r.studiometa-playground.pages.dev

View logs

@titouanmathis titouanmathis merged commit cdcf31a into develop Mar 10, 2026
5 checks passed
@titouanmathis titouanmathis mentioned this pull request Mar 10, 2026
@codecov
Copy link

codecov bot commented Mar 11, 2026

Codecov Report

❌ Patch coverage is 95.65217% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 17.82%. Comparing base (a2966bb) to head (2f6994f).
⚠️ Report is 2 commits behind head on develop.

Files with missing lines Patch % Lines
...nd/src/lib/plugins/PlaygroundDependenciesPlugin.ts 50.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop      #58      +/-   ##
===========================================
+ Coverage    16.04%   17.82%   +1.77%     
===========================================
  Files           53       53              
  Lines          916      937      +21     
  Branches       156      165       +9     
===========================================
+ Hits           147      167      +20     
- Misses         756      757       +1     
  Partials        13       13              
Flag Coverage Δ
unittests 17.82% <95.65%> (+1.77%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@titouanmathis titouanmathis deleted the feature/#57-fix-dependency-resolution branch March 11, 2026 08:25
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.

Fix dependency resolution: subpath imports, DTS generation, and bundle deduplication

1 participant