Skip to content

fix(web): break web-pkg/design-system/web-test-helpers dependency cycle - #13010

Open
mzner wants to merge 1 commit into
masterfrom
fix/web-pkg-dependency-cycle
Open

mzner wants to merge 1 commit into
masterfrom
fix/web-pkg-dependency-cycle

Conversation

@mzner

@mzner mzner commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Description

web-pkg, design-system and web-test-helpers had a dependency cycle: the mount helpers need
to install the design system (its components are registered globally) and web-pkg's mocked
pinia stores, so web-test-helpers ended up imported by both packages that imported it.

Fixed by layering the helpers instead of adding another package for them:

  • design-system/testing — mount/shallowMount, prop types, design system + gettext plugins
  • web-pkg/src/testing — the above plus casl abilities, mocked pinia, component mocks
  • web-test-helpers — just re-exports web-pkg/src/testing

design-system sits at the bottom of the graph, so it can't depend on anything that installs
it — that's why the generic bits live there. web-pkg builds on top of it instead of duplicating
it, so nothing depends on something above it anymore. Public API of web-test-helpers is
unchanged, so extensions aren't affected.

Two smaller things included here:

  • pinned typescript in pnpm.overrides — a second resolved typescript version was forking
    vue3-gettext into two instances, breaking $gettext in mounted components
  • kept design-system/testing external in web-pkg's build config — it was getting bundled in by
    accident, shipping a duplicate copy of the design system to consumers

Related Issue

  • Fixes OCISDEV-1440

Motivation and Context

Needed before we can turn on Nx (see #13011) — Nx errors out on a circular task graph, and this
was one.

How Has This Been Tested?

  • pnpm install — no more cyclic-workspace warning
  • pnpm test:unit — 380 files / 3129 tests pass
  • pnpm check:types, pnpm lint, pnpm check:format, pnpm build — all clean
  • checked the published bundles directly (not just workspace source) to make sure external
    extensions still get the real design system and @vue/test-utils instances, not duplicates
  • tried it against a real extension (web-app-skeleton) installed like an npm consumer would —
    build, typecheck and a component test using @ownclouders/web-test-helpers all pass

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Technical debt
  • Tests only (no source changes)

Checklist:

  • Code changes
  • Unit tests added
  • Acceptance tests added
  • Documentation ticket raised: n/a — internal test tooling, nothing user-facing

@mzner
mzner requested a review from a team as a code owner September 26, 2026 10:51
@update-docs

update-docs Bot commented Sep 26, 2026

Copy link
Copy Markdown

Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a changelog item based on your changes.

@kw-security

kw-security commented Sep 26, 2026 •

Copy link
Copy Markdown

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues
✅ Licenses 0 0 0 0 0 issues
✅ Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

web-pkg, design-system and web-test-helpers formed a cycle: the mount
helpers have to install the design system (its components are registered
globally) and web-pkg's mocked pinia stores, so web-test-helpers was
imported by both packages that imported it back.

Resolved by layering the helpers onto the packages that already need
them, instead of adding another one:

  design-system/testing  mount/shallowMount, prop types, design system +
                         gettext + router-link stub plugins
  web-pkg/src/testing    the above, extended with casl abilities, mocked
                         pinia stores and component mocks
  web-test-helpers       re-export of web-pkg/src/testing

design-system sits at the bottom of the workspace graph, so it cannot
depend on a package that installs it - hence the generic half lives
there. web-pkg composes those plugins rather than duplicating them, so
every helper is still defined exactly once, and no package depends on
one above it.

The public API of `@ownclouders/web-test-helpers` is unchanged, so
external extensions are unaffected.

Also:
- pin `typescript` via `pnpm.overrides` - without it, a second peer-
  resolved typescript version forks `vue`, which forks `vue3-gettext`
  into two module instances, breaking `inject(GetTextSymbol)` for any
  component mounted through these helpers.
- keep `@ownclouders/design-system/testing` external in web-pkg's lib
  build. rollup matches `external` strings exactly, so the subpath was
  inlined, shipping a second copy of the design system and of
  @vue/test-utils into the published bundle - components and wrappers
  were then not identity-equal to the consumer's own, and gettext
  injection broke.
- name the web-test-helpers umd output `.cjs`. The package is ESM, so the
  `.js` file that publishConfig.exports pointed `require` at could not be
  required.

Verified: `pnpm install --frozen-lockfile` clean, zero cyclic-workspace
warnings; `pnpm test:unit` 380 files / 3129 tests pass; `pnpm check:types`
0 errors; `pnpm lint`/`check:format` 0 errors; `pnpm build` succeeds;
published artifacts checked by mounting through the built `dist/` bundles
the way an external extension resolves them via publishConfig.exports.
@mzner
mzner added this pull request to stack #13012 September 26, 2026 11:02
@mzner
mzner force-pushed the fix/web-pkg-dependency-cycle branch from 4f8a422 to ee8c29a Compare September 26, 2026 11:09

This branch has not been deployed

No deployments
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