Skip to content

Commit c8dac09

Browse files
committed
Keep Vite asset queries when resolving Deno import maps.
1 parent 86d6cde commit c8dac09

3 files changed

Lines changed: 63 additions & 8 deletions

File tree

packages/plugin-vite/src/plugins/deno.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
import * as path from "@std/path";
1010
import * as babel from "@babel/core";
1111
import { httpAbsolute } from "./patches/http_absolute.ts";
12-
import { JS_REG, JSX_REG } from "../utils.ts";
12+
import { JS_REG, JSX_REG, joinViteQuery, splitViteQuery } from "../utils.ts";
1313
import { builtinModules } from "node:module";
1414

1515
// @ts-ignore Workaround for https://github.com/denoland/deno/issues/30850
@@ -69,6 +69,8 @@ export function deno(): Plugin {
6969
: browserLoader;
7070

7171
const original = id;
72+
let { specifier, query } = splitViteQuery(id);
73+
id = specifier;
7274

7375
let isHttp = false;
7476
if (id.startsWith("deno-http::")) {
@@ -89,7 +91,11 @@ export function deno(): Plugin {
8991
// resolution, with us being in front due to `enforce: "pre"`.
9092
// But we still want to ignore everything `vite:resolve` does
9193
// because we're kinda replacing that plugin here.
92-
const tmp = await this.resolve(id, importer, options);
94+
const tmp = await this.resolve(
95+
joinViteQuery(id, query),
96+
importer,
97+
options,
98+
);
9399
if (tmp && tmp.resolvedBy !== "vite:resolve") {
94100
if (tmp.external && !/^https?:\/\//.test(tmp.id)) {
95101
return tmp;
@@ -100,7 +106,11 @@ export function deno(): Plugin {
100106
return tmp;
101107
}
102108

103-
id = tmp.id;
109+
const resolvedTmp = splitViteQuery(tmp.id);
110+
id = resolvedTmp.specifier;
111+
if (resolvedTmp.query) {
112+
query = resolvedTmp.query;
113+
}
104114
}
105115

106116
// Plugins may return lower cased drive letters on windows
@@ -134,7 +144,7 @@ export function deno(): Plugin {
134144

135145
if (resolved.startsWith("node:")) {
136146
return {
137-
id: resolved,
147+
id: joinViteQuery(resolved, query),
138148
external: true,
139149
};
140150
}
@@ -148,15 +158,15 @@ export function deno(): Plugin {
148158
type !== RequestedModuleType.Default ||
149159
/^(https?|jsr|npm):/.test(resolved)
150160
) {
151-
return toDenoSpecifier(resolved, type);
161+
return joinViteQuery(toDenoSpecifier(resolved, type), query);
152162
}
153163

154164
if (resolved.startsWith("file://")) {
155165
resolved = path.fromFileUrl(resolved);
156166
}
157167

158168
return {
159-
id: resolved,
169+
id: joinViteQuery(resolved, query),
160170
meta: {
161171
deno: {
162172
type,
@@ -202,6 +212,8 @@ export function deno(): Plugin {
202212
id = id.slice(1);
203213
}
204214

215+
const { specifier: loadSpecifier } = splitViteQuery(id);
216+
205217
const meta = this.getModuleInfo(id)?.meta.deno as
206218
| DenoState
207219
| undefined
@@ -212,12 +224,12 @@ export function deno(): Plugin {
212224
// Skip for non-js files like `.css`
213225
if (
214226
meta.type === RequestedModuleType.Default &&
215-
!JS_REG.test(id)
227+
!JS_REG.test(loadSpecifier)
216228
) {
217229
return;
218230
}
219231

220-
const url = path.toFileUrl(id);
232+
const url = path.toFileUrl(loadSpecifier);
221233

222234
const result = await loader.load(url.href, meta.type);
223235
if (result.kind === "external") {

packages/plugin-vite/src/utils.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,27 @@ import type { ImportCheck } from "./plugins/verify_imports.ts";
55
export const JS_REG = /\.([tj]sx?|[mc]?[tj]s)(\?.*)?$/;
66
export const JSX_REG = /\.[tj]sx(\?.*)?$/;
77

8+
/** Split a Vite module id into specifier and query/hash (e.g. `?raw`, `?v=`). */
9+
export function splitViteQuery(
10+
id: string,
11+
): { specifier: string; query: string } {
12+
const hashIdx = id.indexOf("#");
13+
const base = hashIdx === -1 ? id : id.slice(0, hashIdx);
14+
const hash = hashIdx === -1 ? "" : id.slice(hashIdx);
15+
const qIdx = base.indexOf("?");
16+
if (qIdx === -1) {
17+
return { specifier: base, query: hash };
18+
}
19+
return {
20+
specifier: base.slice(0, qIdx),
21+
query: base.slice(qIdx) + hash,
22+
};
23+
}
24+
25+
export function joinViteQuery(specifier: string, query: string): string {
26+
return query ? specifier + query : specifier;
27+
}
28+
829
export function pathWithRoot(fileOrDir: string, root?: string): string {
930
if (path.isAbsolute(fileOrDir)) return fileOrDir;
1031

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { expect } from "@std/expect";
2+
import { joinViteQuery, splitViteQuery } from "./utils.ts";
3+
4+
Deno.test("splitViteQuery - keeps specifier and query apart", () => {
5+
expect(splitViteQuery("@/assets/icons/plus.svg?raw")).toEqual({
6+
specifier: "@/assets/icons/plus.svg",
7+
query: "?raw",
8+
});
9+
expect(splitViteQuery("/abs/debug.module.js?v=ff8da874")).toEqual({
10+
specifier: "/abs/debug.module.js",
11+
query: "?v=ff8da874",
12+
});
13+
expect(splitViteQuery("file:///tmp/foo.js")).toEqual({
14+
specifier: "file:///tmp/foo.js",
15+
query: "",
16+
});
17+
});
18+
19+
Deno.test("joinViteQuery - reattaches Vite queries", () => {
20+
expect(joinViteQuery("/abs/plus.svg", "?raw")).toBe("/abs/plus.svg?raw");
21+
expect(joinViteQuery("/abs/plus.svg", "")).toBe("/abs/plus.svg");
22+
});

0 commit comments

Comments
 (0)