Skip to content

DF8111: Bare-Specifier Client Script Without Host Resolution

Message

Dock "{id}" declares the bare-specifier client script "{specifier}", but this host advertises no client-module resolution — the browser cannot resolve a bare npm specifier natively, so the script will fail to load.

Cause

A dock entry's client script (clientScript on iframe docks, action, renderer) names an npm module ('vite-plugin-vue-tracer/client/vite-devtools') as its importFrom. Client scripts load with a native browser import(), and a browser only resolves URL specifiers — bare specifiers work when the host runtime resolves them, advertised as ConnectionMeta.configs.dock.clientModuleResolution (a URL template whose {specifier} token is replaced with the specifier). This host declared none, so every client-script loader will throw TypeError: Failed to resolve module specifier for this entry.

Example

ts
initHub({
  base: '/__devframes/',
  configure(ctx) {
    ctx.docks.register({
      type: 'action',
      id: 'vue-tracer',
      title: 'Vue Tracer',
      icon: 'ph:crosshair-simple-duotone',
      // ✗ Bare specifier on a host with no `clientModuleResolution`
      action: { importFrom: 'vite-plugin-vue-tracer/client/vite-devtools' },
    })
  },
})

Fix

Pick whichever side you control:

  • Run under a host that resolves bare specifiers. A Vite host serves any npm module through its own module graph — declare initHub({ clientModuleResolution: '/@id/{specifier}' }). @devframes/vite/hub declares this by default, so the example above is fine there; the script's transitive bare imports work too and share the app's module graph.
  • Ship the script as a self-contained bundle and pass a URL the host serves as importFrom (the a11y inspector pattern): { importFrom: '/__devframes/my-agent/inject.js' } after mounting the bundle's directory with ctx.host.mountStatic(...).
  • Resolve it in the viewer. A custom viewer may pass createDevframeClientHost({ resolveClientModule }) (or ship a page import map); the warning is then safe to disregard — it fires because the server can't know a viewer will cover the gap.

Source

  • packages/hub/src/node/host-docks.tsDevframeDocksHost.register() warns when a bare-specifier client script registers on a host whose staticConfig.dock declares no clientModuleResolution.

Released under the MIT License.