Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion packages/mocker/src/node/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,14 @@ export class ServerMockResolver {

private async resolveMockId(rawId: string, importer: string) {
if (!importer.startsWith(this.server.config.root)) {
importer = join(this.server.config.root, importer)
const resolved = await this.server.pluginContainer.resolveId(
Copy link
Member

@sheremet-va sheremet-va Apr 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the current logic is that if it doesn't start with root, then it's /relative-from-root.js, so we can safely just join them. The resolveId here seems over complicated, importer should always be resolved/partially resolved

I assume importer here has /@fs/ or something (this is what vite does to files outside of root), so we can just strip it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume importer here has /@fs/ or something (this is what vite does to files outside of root), so we can just strip it

This wasn't the case since normal usages (other than public-mocker test) already has fully resolved absolute path (i.e. resolved id), for example on test/browser/fixtures/mocking-out-of-root test case:

root: (abs-path)/project1
id: (abs-path)/project3/lib.js
importer: (abs-path)/project3/index.js

This wasn't about /@fs, which is already stripped out during getImporter and stack trace parsing:

if (url.startsWith('/@fs/')) {
const isWindows = /^\/@fs\/[a-zA-Z]:\//.test(url)
url = url.slice(isWindows ? 5 : 4)
}

Non fully resolved id only happend for public-mocker test which doesn't have the same logic. Alternative is to add extra mocker option to applying joining only for public-mocker usage.

Copy link
Contributor Author

@hi-ogawa hi-ogawa Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, I just realized project root path is not only public-mocker test, for example test/browser/fixtures/mocking-out-of-root/project1/imported-test.js:

{ rawId: './lib.js', importer: '/imported-test.js' }

We'll need to somehow tell mocker about whether (abs-path)/project3/index.js was originally with /@fs or not, so we can skip the joining.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think this extra resolveId is also fine. If you know other idea, I would be happy to hear.

Copy link
Member

@sheremet-va sheremet-va Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I still think resolveId is overkill because we know exactly how this value is resolved already. Maybe we can just check moduleGraph.getByUrl and return the module.file if it exists, with a fallback to importer without joining

importer,
this.server.config.root,
{
ssr: false,
},
)
importer = resolved?.id ?? this.server.config.root
}
const resolved = await this.server.pluginContainer.resolveId(
rawId,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { test, expect, vi } from 'vitest';
import project2 from "../project2/index.js"
import "../project3/index.js"

vi.mock("../project2/index.js", () => ({
default: 'project2-mocked'
Expand Down
8 changes: 8 additions & 0 deletions test/browser/fixtures/mocking-out-of-root/project3/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { vi, test, expect } from "vitest"
import lib from "./lib.js";

vi.mock("./lib.js", () => ({ default: "mocked" }))

test("project3", () => {
expect(lib).toBe("mocked");
})
1 change: 1 addition & 0 deletions test/browser/fixtures/mocking-out-of-root/project3/lib.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default "lib"
Loading