Skip to content

fix: resolve profile-installed plugins from cordis-plugin-loader - #83

Open
yaojin3616 wants to merge 1 commit into
mainfrom
fix/profile-node-modules-resolution
Open

fix: resolve profile-installed plugins from cordis-plugin-loader#83
yaojin3616 wants to merge 1 commit into
mainfrom
fix/profile-node-modules-resolution

Conversation

@yaojin3616

Copy link
Copy Markdown
Contributor

Fixes #73

Root cause

Plugins installed via the plugin market go into the profile's node_modules (e.g. DSH_HOME/profiles/web/node_modules), but the cordis-plugin-loader resolves packages from the app bundle's own node_modules directory. After Electron packaging, these two paths are different, so both hot-mount and post-restart plugin loading fail with Cannot find package errors.

The key error from user logs:

hot-mount: @liustack/modlens: fell back to restart —
  Cannot find package '@liustack/modlens' imported from
  ...app.asar.unpacked/node_modules/@deepseek-ai/cordis-plugin-loader/lib/index.js

Fix

Injects the profile's node_modules directories into the harness Node.js process via two mechanisms:

  1. CommonJS: Sets NODE_PATH and appends to Module.globalPaths
  2. ESM: Registers a custom resolve hook (via --import) that falls back to profile node_modules when default resolution fails

The ESM hook uses a synthetic parent URL inside each profile's node_modules directory so that Node's standard resolver — including package.json exports, conditions, and subpaths — handles the actual resolution correctly.

Files changed

  • build/profile-module-paths.mjs — Setup script: collects profile node_modules dirs from DSH_HOME, configures CJS paths, registers ESM hook
  • build/profile-esm-resolver.mjs — ESM resolve hook with synthetic parent URL fallback
  • src/main/runtime/harness-runtime.ts — Passes --import flag and DSH_DESKTOP_PROFILE_MODULE_PATHS env to harness process
  • src/main/index.ts — Wires profile module paths resource into HarnessRuntime
  • package.json — Adds new build files to extraResources
  • test/runtime.test.ts — Updated tests for new arguments
  • test/profile-module-paths.test.ts — Tests for ESM resolver behavior

Plugins installed via the plugin market (dsh-market) go into the
profile's node_modules (e.g. DSH_HOME/profiles/web/node_modules),
but the cordis-plugin-loader resolves packages from the app bundle's
own node_modules directory. After packaging, these two paths are
different, so both hot-mount and post-restart plugin loading fail
with 'Cannot find package' errors.

This change injects the profile's node_modules directories into the
harness Node.js process via two mechanisms:

1. NODE_PATH + Module.globalPaths for CommonJS resolution
2. A custom ESM resolve hook (registered via --import) that falls
   back to profile node_modules when the default resolution fails

The ESM hook uses a synthetic parent URL inside each profile's
node_modules directory so that Node's standard resolver (including
package.json exports, conditions, subpaths) handles the actual
resolution correctly.

Closes #73
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.

插件市场装的插件在 v2.0.0 中无法加载:loader 从 app.asar.unpacked 解析,插件在 profile 的 node_modules

1 participant