diff --git a/viteroll/examples/ssr-simple/e2e/basic.test.ts b/viteroll/examples/ssr-simple/e2e/basic.test.ts deleted file mode 100644 index 4002877..0000000 --- a/viteroll/examples/ssr-simple/e2e/basic.test.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { expect, test } from "@playwright/test"; -import { createEditor, testNoJs } from "../../../e2e/helper"; - -testNoJs("ssr", async ({ page }) => { - await page.goto("/"); - await page.getByText("hydrated: false").click(); -}); - -test("csr", async ({ page }) => { - await page.goto("/"); - await page.getByText("hydrated: true").click(); -}); - -test("hmr", async ({ page, request }) => { - await page.goto("/"); - await page.getByText("hydrated: true").click(); - - await page.getByRole("button", { name: "Count: 0" }).click(); - - using file = createEditor("./src/app.tsx"); - file.edit((s) => s.replace("Count:", "Count-EDIT:")); - - await page.getByRole("button", { name: "Count-EDIT: 1" }).click(); - - file.edit((s) => s.replace("Count-EDIT:", "Count-EDIT-EDIT:")); - await page.getByRole("button", { name: "Count-EDIT-EDIT: 2" }).click(); - - // server module is also invalidated - const res = await request.get("/"); - expect(await res.text()).toContain("Count-EDIT-EDIT"); -}); diff --git a/viteroll/examples/ssr-simple/package.json b/viteroll/examples/ssr-simple/package.json deleted file mode 100644 index c221cf0..0000000 --- a/viteroll/examples/ssr-simple/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "@hiogawa/viteroll-example-ssr", - "private": true, - "type": "module", - "scripts": { - "dev": "vite", - "test-e2e": "playwright test" - }, - "dependencies": { - "react": "latest", - "react-dom": "latest" - }, - "devDependencies": { - "@types/react": "latest", - "@types/react-dom": "latest" - } -} diff --git a/viteroll/examples/ssr-simple/playwright.config.ts b/viteroll/examples/ssr-simple/playwright.config.ts deleted file mode 100644 index d0f2112..0000000 --- a/viteroll/examples/ssr-simple/playwright.config.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "../../playwright.config.ts"; diff --git a/viteroll/examples/ssr-simple/src/app.tsx b/viteroll/examples/ssr-simple/src/app.tsx deleted file mode 100644 index 12e7520..0000000 --- a/viteroll/examples/ssr-simple/src/app.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from "react"; - -export function App() { - const [count, setCount] = React.useState(0); - return ( -
-

Rolldown SSR

- - -
- ); -} - -function Hydrated() { - const hydrated = React.useSyncExternalStore( - React.useCallback(() => () => {}, []), - () => true, - () => false, - ); - return

hydrated: {String(hydrated)}

; -} diff --git a/viteroll/examples/ssr-simple/src/entry-client.tsx b/viteroll/examples/ssr-simple/src/entry-client.tsx deleted file mode 100644 index 3e5c48f..0000000 --- a/viteroll/examples/ssr-simple/src/entry-client.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import React from "react"; -import ReactDOMClient from "react-dom/client"; -import { App } from "./app"; - -React.startTransition(() => { - ReactDOMClient.hydrateRoot(document.getElementById("root")!, ); -}); diff --git a/viteroll/examples/ssr-simple/src/entry-server.tsx b/viteroll/examples/ssr-simple/src/entry-server.tsx deleted file mode 100644 index 5deafaf..0000000 --- a/viteroll/examples/ssr-simple/src/entry-server.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import type { Connect } from "vite"; - -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") { - const error = new Error("crash-ssr"); - console.error(error); - throw error; - } - res.setHeader("content-type", "text/html"); - // TODO: transformIndexHtml? - res.end(`\ - - - - - - -

Rolldown SSR

- /crash-ssr - - -`); -}; - -export default handler; diff --git a/viteroll/examples/ssr-simple/tsconfig.json b/viteroll/examples/ssr-simple/tsconfig.json deleted file mode 100644 index 510cef1..0000000 --- a/viteroll/examples/ssr-simple/tsconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "include": ["src", "*.ts"], - "compilerOptions": { - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "verbatimModuleSyntax": true, - "allowImportingTsExtensions": true, - "moduleResolution": "Bundler", - "module": "ESNext", - "target": "ESNext", - "lib": ["ESNext", "DOM"], - "jsx": "react-jsx", - "noEmit": true - } -} diff --git a/viteroll/examples/ssr-simple/vite.config.ts b/viteroll/examples/ssr-simple/vite.config.ts deleted file mode 100644 index 2902a53..0000000 --- a/viteroll/examples/ssr-simple/vite.config.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { defineConfig } from "vite"; -import { RolldownEnvironment, viteroll } from "../../viteroll"; - -process.setSourceMapsEnabled(true); - -export default defineConfig({ - environments: { - client: { - build: { - outDir: "dist/client", - rollupOptions: { - input: "./src/entry-client", - }, - }, - }, - ssr: { - build: { - outDir: "dist/server", - rollupOptions: { - input: { - index: "./src/entry-server", - }, - }, - }, - }, - }, - plugins: [ - viteroll({ - reactRefresh: true, - ssrModuleRunner: true, - }), - { - name: "ssr-middleware", - config() { - return { - appType: "custom", - }; - }, - configureServer(server) { - return () => { - const devEnv = server.environments.ssr as RolldownEnvironment; - server.middlewares.use(async (req, res, next) => { - try { - const mod = (await devEnv.import("src/entry-server.tsx")) as any; - await mod.default(req, res); - } catch (e) { - next(e); - } - }); - }; - }, - }, - ], -}); diff --git a/viteroll/examples/ssr/src/entry-server.tsx b/viteroll/examples/ssr/src/entry-server.tsx index fadbfb0..fb5485e 100644 --- a/viteroll/examples/ssr/src/entry-server.tsx +++ b/viteroll/examples/ssr/src/entry-server.tsx @@ -2,12 +2,13 @@ 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") { - throw new Error("crash-ssr"); + throwError(); } const ssrHtml = ReactDOMServer.renderToString(); res.setHeader("content-type", "text/html"); diff --git a/viteroll/examples/ssr/src/error.tsx b/viteroll/examples/ssr/src/error.tsx new file mode 100644 index 0000000..f127c3e --- /dev/null +++ b/viteroll/examples/ssr/src/error.tsx @@ -0,0 +1,9 @@ +// +// random new lines +// +export function throwError() { + // + // and more + // + throw new Error("boom"); +} diff --git a/viteroll/viteroll.ts b/viteroll/viteroll.ts index 7922daa..7154266 100644 --- a/viteroll/viteroll.ts +++ b/viteroll/viteroll.ts @@ -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(); @@ -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; } @@ -337,12 +337,11 @@ class RolldownModuleRunner { return mod.exports; } - evaluate(code: string) { + evaluate(code: string, sourceURL: string) { const context = { self: this.context, ...this.context, }; - // TODO: sourcemap not working? // extract sourcemap const sourcemap = code.match(/^\/\/# sourceMappingURL=.*/m)?.[0] ?? ""; if (sourcemap) { @@ -356,23 +355,11 @@ self.__toCommonJS = __toCommonJS; self.__export = __export; self.__toESM = __toESM; }} -//# sourceMappingSource=rolldown-module-runner +//# sourceURL=${sourceURL} ${sourcemap} `; - // as new Function - // code = `\ - // ${code} - // // TODO: need to re-expose runtime utilities for now - // self.__toCommonJS = __toCommonJS; - // self.__export = __export; - // self.__toESM = __toESM; - // //# sourceMappingSource=rolldown-module-runner - // ${sourcemap} - // `; - fs.writeFileSync("dump.js", code); - const fn = (0, eval)(code); - // const fn = new Function(...Object.keys(context), code); try { + const fn = (0, eval)(code); fn(...Object.values(context)); } catch (e) { console.error(e);