Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
28 changes: 20 additions & 8 deletions packages/plugin-vite/src/plugins/deno.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import * as path from "@std/path";
import * as babel from "@babel/core";
import { httpAbsolute } from "./patches/http_absolute.ts";
import { JS_REG, JSX_REG } from "../utils.ts";
import { JS_REG, JSX_REG, joinViteQuery, splitViteQuery } from "../utils.ts";
import { builtinModules } from "node:module";

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

const original = id;
let { specifier, query } = splitViteQuery(id);
id = specifier;

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

id = tmp.id;
const resolvedTmp = splitViteQuery(tmp.id);
id = resolvedTmp.specifier;
if (resolvedTmp.query) {
query = resolvedTmp.query;
}
}

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

if (resolved.startsWith("node:")) {
return {
id: resolved,
id: joinViteQuery(resolved, query),
external: true,
};
}
Expand All @@ -148,15 +158,15 @@ export function deno(): Plugin {
type !== RequestedModuleType.Default ||
/^(https?|jsr|npm):/.test(resolved)
) {
return toDenoSpecifier(resolved, type);
return joinViteQuery(toDenoSpecifier(resolved, type), query);
}

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

return {
id: resolved,
id: joinViteQuery(resolved, query),
meta: {
deno: {
type,
Expand Down Expand Up @@ -202,6 +212,8 @@ export function deno(): Plugin {
id = id.slice(1);
}

const { specifier: loadSpecifier } = splitViteQuery(id);

const meta = this.getModuleInfo(id)?.meta.deno as
| DenoState
| undefined
Expand All @@ -212,12 +224,12 @@ export function deno(): Plugin {
// Skip for non-js files like `.css`
if (
meta.type === RequestedModuleType.Default &&
!JS_REG.test(id)
!JS_REG.test(loadSpecifier)
) {
return;
}

const url = path.toFileUrl(id);
const url = path.toFileUrl(loadSpecifier);

const result = await loader.load(url.href, meta.type);
if (result.kind === "external") {
Expand Down
21 changes: 21 additions & 0 deletions packages/plugin-vite/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ import type { ImportCheck } from "./plugins/verify_imports.ts";
export const JS_REG = /\.([tj]sx?|[mc]?[tj]s)(\?.*)?$/;
export const JSX_REG = /\.[tj]sx(\?.*)?$/;

/** Split a Vite module id into specifier and query/hash (e.g. `?raw`, `?v=`). */
export function splitViteQuery(
id: string,
): { specifier: string; query: string } {
const hashIdx = id.indexOf("#");
const base = hashIdx === -1 ? id : id.slice(0, hashIdx);
const hash = hashIdx === -1 ? "" : id.slice(hashIdx);
const qIdx = base.indexOf("?");
if (qIdx === -1) {
return { specifier: base, query: hash };
}
return {
specifier: base.slice(0, qIdx),
query: base.slice(qIdx) + hash,
};
}

export function joinViteQuery(specifier: string, query: string): string {
return query ? specifier + query : specifier;
}

export function pathWithRoot(fileOrDir: string, root?: string): string {
if (path.isAbsolute(fileOrDir)) return fileOrDir;

Expand Down
22 changes: 22 additions & 0 deletions packages/plugin-vite/src/utils_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { expect } from "@std/expect";
import { joinViteQuery, splitViteQuery } from "./utils.ts";

Deno.test("splitViteQuery - keeps specifier and query apart", () => {
expect(splitViteQuery("@/assets/icons/plus.svg?raw")).toEqual({
specifier: "@/assets/icons/plus.svg",
query: "?raw",
});
expect(splitViteQuery("/abs/debug.module.js?v=ff8da874")).toEqual({
specifier: "/abs/debug.module.js",
query: "?v=ff8da874",
});
expect(splitViteQuery("file:///tmp/foo.js")).toEqual({
specifier: "file:///tmp/foo.js",
query: "",
});
});

Deno.test("joinViteQuery - reattaches Vite queries", () => {
expect(joinViteQuery("/abs/plus.svg", "?raw")).toBe("/abs/plus.svg?raw");
expect(joinViteQuery("/abs/plus.svg", "")).toBe("/abs/plus.svg");
});