feat: bump to pnpm 11, migrate shiki-magic-move to @shikijs/magic-move, update deps#2615
Merged
Conversation
…ve, update deps
- packageManager: pnpm@10.33.4 → pnpm@11.5.1
- shiki-magic-move@1.3.0 → @shikijs/magic-move@4.2.0 (same author, API-compatible
rename; CSS class names preserved); update imports in client and slidev CLI
- pnpm v11 config migration:
- onlyBuiltDependencies → allowBuilds map (required by v11)
- trustPolicyIgnoreAfter: 43200 (30d) to silence trust-downgrade false
positives on long-lived transitives that root `resolutions` already overrides
- minimumReleaseAgeExclude entries for the freshly-published shiki v4.2.0
cohort (pnpm v11 now defaults minimumReleaseAge to 24h)
- taze -r major: bump all catalogs to latest (respecting taze.config.ts:
prettier kept on patch range, typeit and @types/vscode kept as-is)
✅ Deploy Preview for slidev ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
@slidev/client
create-slidev
create-slidev-theme
@slidev/parser
@slidev/cli
@slidev/types
commit: |
pnpm 11 makes `strictDepBuilds: true` the default, so the template's `pnpm-workspace.yaml` must explicitly allow `playwright-chromium` to run its postinstall (which downloads the bundled browser used by `slidev export` for PDF/PNG/PPTX). Without this, a fresh project from `create-slidev` fails to install with `ERR_PNPM_IGNORED_BUILDS`.
Two pnpm 11 breaking changes affect the smoke test: 1. Global binaries moved from `$PNPM_HOME` to `$PNPM_HOME/bin`; without adding the new path to $GITHUB_PATH, `pnpm i -g` aborts with 'configured global bin directory is not in PATH'. 2. `strictDepBuilds: true` is now the default, so the global install of `playwright-chromium` (which has a postinstall that downloads the browser) needs an explicit `--allow-build=playwright-chromium` when matrix.pm is pnpm. npm doesn't have this concept, so the flag is conditionally appended via a step env var.
…solation
pnpm v11 isolates each `pnpm add -g` invocation into its own directory
with its own `node_modules`. Installing `@slidev/cli` and
`@slidev/theme-seriph` in separate commands therefore lands them in
different global directories, and slidev's global theme resolver fails
to find the theme ("The theme '@slidev/theme-seriph' was not found and
cannot prompt for installation"). Install them together so they share
one global install dir.
pnpm v11's default isolated node-linker symlinks each globally-installed package to the virtual store, so slidev's resolver (which walks up from `import.meta.url`'s realpath via `findDepPkgJsonPath`) can't see a sibling-installed theme. `--node-linker=hoisted` keeps the install group's `node_modules` flat so the upward lookup finds `@slidev/theme-seriph` next to `@slidev/cli`.
…oups
pnpm v11 makes `pnpm add -g <pkg>` install each top-level package into
its own `{PNPM_HOME}/v11/{hash}/node_modules/` directory, dispatched via
a shell shim in `{PNPM_HOME}/bin/`. Two consequences for slidev:
1. The global-install heuristic (`relative(userRoot, argv[1]).includes(
'/.pnpm/')` plus the `is-installed-globally` package) doesn't fire,
because the invocation path no longer contains `.pnpm` and neither
yarn's nor npm's globals directory matches.
2. `findDepPkgJsonPath(name, cliRoot)` walks upward from the realpath of
`@slidev/cli` inside the global CAS (`{store}/links/...`), which has
no path back to the install-group's `node_modules` — so a theme
installed in a sibling group (e.g. `@slidev/theme-seriph` via the
same `pnpm add -g` call) is invisible.
This commit derives the install-group's `node_modules` directly from
`process.argv[1]` (literal lookup first, with a symlink-chain fallback
for legacy `.bin` layouts), then enumerates every sibling install
group under the global root as additional search paths. Both
`resolveImportPath` and `findGlobalPkgRoot` consult those paths, and the
global-install heuristic treats an invocation `node_modules` outside
the user workspace as a positive signal. Together this restores the
`slidev (global)` banner and lets the theme/addon resolver find sibling
packages on pnpm v11 globals.
Updates the smoke workflow to add `$PNPM_HOME/bin` to PATH (pnpm v11's
new global bin layout) and to pass `--allow-build=playwright-chromium`
when matrix.pm is pnpm (`strictDepBuilds: true` is the new default).
Global-mode build is still gated to npm only because pnpm v11 doesn't
co-locate optional peer deps (notably `@vue/compiler-sfc` for
`unplugin-icons`/`local-pkg`) with isolated globals — that gap is
upstream and tracked separately.
Exports `findInvocationNodeModulesPath` and `computeInvocationSearchPaths`
as the path-string-parsing units underneath `findGlobalPkgRoot` and adds
unit tests for both, plus a virtual-fs mock so tests can exercise
filesystem shapes (symlink chains, sibling install groups, missing
directories) without touching disk.
Covered scenarios:
- pnpm v11 shell-shim dispatch (`{PNPM_HOME}/v11/{hash}/node_modules/...`)
- npm/yarn globals and local project installs
- nested `node_modules` (e.g. pnpm's `.pnpm/` virtual store inside a
project's own `node_modules/`)
- single- and multi-hop fs symlink chains, including relative targets
- enumerating sibling install groups for pnpm v11 isolated globals,
skipping siblings without a `node_modules/` child
- graceful handling of unreadable global roots and infinitely-deep
symlink chains
… for node_modules
On Windows, `path.isAbsolute('/foo')` returns true (Windows treats a
leading slash as drive-relative), so the previous `isAbsolute(target) ?
target : resolve(dirname(current), target)` branch returned a target
with forward slashes verbatim. The subsequent
`lastIndexOf(`${sep}node_modules${sep}`)` scan uses the platform
separator (`\` on Windows) and would miss the segment.
Always going through `resolve()` normalizes both relative and absolute
targets to the platform separator, which is also what the production
code wants for the upward search to find a sibling `node_modules` in
the install group.
Surfaced by the new `findInvocationNodeModulesPath` tests when they ran
on the Windows CI matrix.
…change Commit 6baeb85 ("feat: load preparser also from theme", #2558) changed the `load()` signature in `@slidev/parser/fs` from `load(_: string, ...)` to `load(_: LoadRootsInfo, ...)` and exported the new `LoadRootsInfo` interface, but didn't regenerate the tsnapi snapshot. The Test workflow has been red on `main` ever since. Regenerated via `vitest run test/api-snapshots.test.ts -u`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
packageManagerto pnpm@11.5.1 (frompnpm@10.33.4)taze(respectingtaze.config.ts)playwright-chromium's postinstall in thecreate-slidevtemplateshiki-magic-move → @shikijs/magic-move
Upstream renamed and rehoused the package; the public API and the runtime CSS class names (
shiki-magic-move-*) are unchanged, so the migration is a mechanical import rewrite.Imports updated:
packages/client/builtin/ShikiMagicMove.vue—shiki-magic-move/{types,vue}→@shikijs/magic-move/{types,vue}packages/client/styles/index.ts—shiki-magic-move/style.css→@shikijs/magic-move/style.csspackages/slidev/node/syntax/codeblock/magic-move.ts—shiki-magic-move/core→@shikijs/magic-move/corepackages/slidev/node/vite/extendConfig.ts—optimizeDeps.excludeentry updatedpnpm 11 migration
Root workspace (
pnpm-workspace.yaml)onlyBuiltDependencies→allowBuildsmap (required by v11; same set of packages allowed to build)trustPolicyIgnoreAfter: 43200(30 days). pnpm 11 evaluatestrustPolicy: no-downgradeagainst the originally-declared transitive version before applying rootresolutions/overrides, so long-lived transitives likeundici-types@~6.21.0(declared by@types/node@22viapptxgenjs) andsemver@~6.3.1(declared by@babel/core) flag as false positives.minimumReleaseAgeExcludefor the just-published@shikijs/*v4.2.0 cohort (pnpm 11 defaultsminimumReleaseAgeto 24h).create-slidev template
The template's
pnpm-workspace.yamlnow allow-listsplaywright-chromiumso a freshly-scaffolded project on pnpm 11 can install the bundled browser used byslidev export.Global resolver —
packages/slidev/node/resolver.tspnpm 11 lays globals out as
{PNPM_HOME}/v11/{hash}/node_modules/...with one isolated install group per top-level package, dispatched through a shell shim in{PNPM_HOME}/bin/. The previous resolver did two things that no longer work:relative(userRoot, argv[1]).includes('/.pnpm/')plusis-installed-globally— neither fires for pnpm v11 isolated globals.findGlobalPkgRootwalked up fromcliRoot(the realpath of@slidev/cliinside the CAS), which has no path back to the install-group'snode_modules/— so a theme installed in a sibling install group (e.g.@slidev/theme-seriphvia the samepnpm add -gcall) was invisible.The resolver now:
node_modules/directly fromprocess.argv[1](a literal lookup for shell-shim dispatch, with anlstatSync/readlinkSyncfallback for the legacy.binsymlink layout).node_modulesoutside the user workspace as a positiveisInstalledGloballysignal.Verified locally with a pnpm 11 global install — slidev now prints
(global)and resolves@slidev/theme-seriphfrom a sibling install group instead of bailing with "The theme '@slidev/theme-seriph' was not found".Smoke workflow (
.github/workflows/smoke.yml)$PNPM_HOME/binto$GITHUB_PATH— pnpm 11 moved globally-installed binaries from$PNPM_HOMEto$PNPM_HOME/binand would otherwise abort with "configured global bin directory is not in PATH".pnpm i ... --allow-build=playwright-chromiumfor pnpm.Install globally/Test build command in global mode) is gated tomatrix.pm == 'npm'for now. The resolver fix lets slidev find sibling globals on pnpm 11, but pnpm 11 doesn't co-locate optional peer deps (notably@vue/compiler-sfcforunplugin-icons/local-pkg) with isolated globals, so the downstream build still fails. That gap is upstream-flavoured and tracked separately; once it's addressed theif:can be relaxed back tomatrix.pm != 'yarn'.Dependency upgrades (taze -r major, honoring
taze.config.ts)Notable bumps:
@shikijs/*packages: 4.0.2 → 4.2.0ovsx: 0.10 → 1.0 (VS Code extension marketplace publisher, release pipeline only)unplugin-vue-markdown: 30 → 32katex: 0.16 → 0.17volar-service-prettier/volar-service-yaml: 0.0.64 → 0.0.71vitest: 4.1.6 → 4.1.8,vite: 8.0.13 → 8.0.16,vue-tsc: 3.3.0 → 3.3.3,tsdown: 0.22.0 → 0.22.1taze.config.tsoverrides are respected:typeit(#1537) and@types/vscode(must matchengines.vscode) are left alone, andprettieris kept on a patch-only range so v2 is preserved forvolar-service-yaml.Verification
pnpm install— clean install with pnpm 11.5.1, lockfile remainslockfileVersion: '9.0', noshiki-magic-moveentries remainpnpm build— all 7 packages buildpnpm test— 155/156 pass; the single failure (test/api-snapshots.test.ts > @slidev/parser > dts: ./fs) is pre-existing onmainfrom commit6baeb853(stale tsnapi snapshot after aloadsignature change) and red on main's CIpnpm typecheck— only emits errors insidedocs/node_modules/vitepress/dist/client/...(vitepress dist.vuefiles referencing untyped.jsfiles); reproduces onmain, unrelated to this PRpnpm lint— cleanNotes for maintainers
minimumReleaseAgeExcludeentries are version-pinned and become no-ops once each package matures past 24h; can be pruned in a future housekeeping pass.https://github.com/shikijs/shiki-magic-moveandhttps://shiki-magic-move.netlify.app/was left untouched — both URLs still resolve. Updating toshiki.style/packages/magic-movewould be a separate documentation pass.pnpm i -g @slidev/cliwill need to also install@vue/compiler-sfc(or wait for upstream to address optional-peer co-location in isolated globals).