Skip to content

@deno/loader: Workspace loader fails to resolve entrypoint from member's import map #15

@nestarz

Description

@nestarz

When using @deno/loader's Workspace in a Deno workspace project, the created loader fails to resolve an entrypoint that is defined in a workspace member's imports map.

The issue occurs when a script in the workspace root imports and executes the code from the member package. However, if the member package's script is executed directly, it works as expected. This suggests the Workspace loader is not correctly resolving the configuration context of the workspace member when initiated from the root.

Reproduction

A minimal reproduction repository is available here: https://github.com/nestarz/deno-loader-workspace-entrypoint-repro

The project structure is as follows:

test-loader
├── deno.json
├── deno.lock
├── main.ts
└── sub
    ├── deno.json
    └── mod.ts

Steps to Reproduce

  1. Clone the reproduction repository.
  2. Navigate into the project directory: cd deno-loader-workspace-entrypoint-repro.
  3. Run the root script (this will fail):
    deno run -A main.ts
  4. Run the member package's script directly (this will succeed):
    deno run -A sub/mod.ts

Code

File Contents

test-loader/deno.json

{
  "name": "test-loader",
  "workspace": ["./sub"]
}

test-loader/main.ts

import "@test/loader-workspace";

test-loader/sub/deno.json

{
  "name": "@test/loader-workspace",
  "version": "0.1.0",
  "exports": "./mod.ts",
  "imports": {
    "@deno/loader": "jsr:@deno/loader@^0.1.3",
    "@std/assert": "jsr:@std/assert@1"
  }
}

test-loader/sub/mod.ts (The file using @deno/loader)

import { ResolutionMode, Workspace } from "@deno/loader";

// Initialize workspace from the root config
const workspace = new Workspace({
  configPath: import.meta.resolve("../deno.json").slice("file://".length),
});

// Create a loader with an entrypoint that needs to be resolved
// via the `imports` map in `sub/deno.json`.
const loader = await workspace.createLoader({
  entrypoints: ["@std/assert"],
});

// Attempt to resolve the entrypoint
const resolveId = loader.resolve(
  "@std/assert",
  import.meta.url,
  ResolutionMode.Import,
);

console.log(resolveId);

const loadResult = await loader.load(resolveId);

console.log(loadResult);

Expected Behavior

The command deno run -A main.ts should execute successfully. The code in sub/mod.ts should find @std/assert in the sub/deno.json import map, resolve it to its JSR specifier, and print the resolution and load results to the console, similar to the output of running deno run -A sub/mod.ts directly.

Actual Behavior

The command deno run -A main.ts fails with the following error, indicating that the import map from sub/deno.json was not used to resolve the @std/assert entrypoint specifier.

error: Uncaught (in promise) Error: Relative import path "@std/assert" not prefixed with / or ./ or ../ and not in import map from "file:///path/to/project/test-loader/"
  const ret = new Error(getStringFromWasm0(arg0, arg1));
      ^
    at __wbg_new_2134d19335a4d6f8 (wasm://wasm/0166627f:1:10521)
    atrolldown_core_resolve_id (wasm://wasm/0166627f:1:25442)
    at Loader.resolve (file:///Users/elias/code/bureaudouble/deno-loader/src/loader.ts:162:16)
    at file:///Users/elias/code/bureaudouble/test-rolldown-deno/test-loader/sub/mod.ts:14:25

deno run -A sub/mod.ts works

Environment

  • @deno/loader: ~0.1.3
  • Deno version: 2.4.0
  • OS: macOS

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions