Skip to content

Commit

Permalink
feat(viteroll): ssr sourcemap (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa authored Nov 29, 2024
1 parent 39fdabd commit 4e6f84c
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 16 deletions.
6 changes: 6 additions & 0 deletions viteroll/examples/ssr/e2e/basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,9 @@ test("hmr", async ({ page, request }) => {
const res = await request.get("/");
expect(await res.text()).toContain("Count-EDIT-EDIT");
});

test("server stacktrace", async ({ page }) => {
const res = await page.goto("/crash-ssr");
expect(await res?.text()).toContain("examples/ssr/src/error.tsx:8:8");
expect(res?.status()).toBe(500);
});
4 changes: 4 additions & 0 deletions viteroll/examples/ssr/src/entry-server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
import ReactDOMServer from "react-dom/server.browser";
import type { Connect } from "vite";
import { App } from "./app";
import { throwError } from "./error";

const handler: Connect.SimpleHandleFunction = (req, res) => {
const url = new URL(req.url ?? "/", "https://vite.dev");
console.log(`[SSR] ${req.method} ${url.pathname}`);
if (url.pathname === "/crash-ssr") {
throwError();
}
const ssrHtml = ReactDOMServer.renderToString(<App />);
res.setHeader("content-type", "text/html");
// TODO: transformIndexHtml?
Expand Down
9 changes: 9 additions & 0 deletions viteroll/examples/ssr/src/error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//
// random new lines
//
export function throwError() {
//
// and more
//
throw new Error("boom");
}
44 changes: 28 additions & 16 deletions viteroll/viteroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ export class RolldownEnvironment extends DevEnvironment {
if (this.outputOptions.format === "app") {
console.time(`[rolldown:${this.name}:hmr]`);
const result = await this.instance.experimental_hmr_rebuild([ctx.file]);
this.getRunner().evaluate(result[1].toString());
this.getRunner().evaluate(result[1].toString(), result[0]);
console.timeEnd(`[rolldown:${this.name}:hmr]`);
} else {
await this.build();
Expand All @@ -301,7 +301,7 @@ export class RolldownEnvironment extends DevEnvironment {
const filepath = path.join(this.outDir, output.fileName);
this.runner = new RolldownModuleRunner();
const code = fs.readFileSync(filepath, "utf-8");
this.runner.evaluate(code);
this.runner.evaluate(code, filepath);
}
return this.runner;
}
Expand All @@ -310,9 +310,11 @@ export class RolldownEnvironment extends DevEnvironment {
if (this.outputOptions.format === "app") {
return this.getRunner().import(input);
}
const output = this.result.output.find((o) => o.name === input);
assert(output, `invalid import input '${input}'`);
// input is no use
const output = this.result.output[0];
const filepath = path.join(this.outDir, output.fileName);
// TODO: source map not applied when adding `?t=...`?
// return import(`${pathToFileURL(filepath)}`)
return import(`${pathToFileURL(filepath)}?t=${this.buildTimestamp}`);
}
}
Expand All @@ -337,22 +339,29 @@ class RolldownModuleRunner {
return mod.exports;
}

evaluate(code: string) {
evaluate(code: string, sourceURL: string) {
const context = {
self: this.context,
...this.context,
};
// TODO: sourcemap
code = code.replace(/^\/\/# sourceMapping.*$/m, "");
const wrapped = `'use strict';(${Object.keys(context).join(",")})=>{{
${code};
// TODO: need to re-expose runtime utilities for now
self.__toCommonJS = __toCommonJS;
self.__export = __export;
self.__toESM = __toESM;
}}`;
const fn = (0, eval)(wrapped);
// extract sourcemap
const sourcemap = code.match(/^\/\/# sourceMappingURL=.*/m)?.[0] ?? "";
if (sourcemap) {
code = code.replace(sourcemap, "");
}
// as eval
code = `\
'use strict';(${Object.keys(context).join(",")})=>{{${code}
// TODO: need to re-expose runtime utilities for now
self.__toCommonJS = __toCommonJS;
self.__export = __export;
self.__toESM = __toESM;
}}
//# sourceURL=${sourceURL}
${sourcemap}
`;
try {
const fn = (0, eval)(code);
fn(...Object.values(context));
} catch (e) {
console.error(e);
Expand Down Expand Up @@ -440,7 +449,10 @@ function viterollEntryPlugin(
if (viterollOptions.reactRefresh) {
output.prepend(getReactRefreshRuntimeCode());
}
return { code: output.toString(), map: output.generateMap() };
return {
code: output.toString(),
map: output.generateMap({ hires: "boundary" }),
};
}
},
generateBundle(_options, bundle) {
Expand Down

0 comments on commit 4e6f84c

Please sign in to comment.