diff --git a/apps/fixtures/css/README.md b/apps/fixtures/css/README.md
new file mode 100644
index 000000000..128403d02
--- /dev/null
+++ b/apps/fixtures/css/README.md
@@ -0,0 +1,30 @@
+# SolidStart
+
+Everything you need to build a Solid project, powered by [`solid-start`](https://start.solidjs.com);
+
+## Creating a project
+
+```bash
+# create a new project in the current directory
+npm init solid@latest
+
+# create a new project in my-app
+npm init solid@latest my-app
+```
+
+## Developing
+
+Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
+
+```bash
+npm run dev
+
+# or start the server and open the app in a new browser tab
+npm run dev -- --open
+```
+
+## Building
+
+Solid apps are built with _presets_, which optimise your project for deployment to different environments.
+
+By default, `npm run build` will generate a Node app that you can run with `npm start`. To use a different preset, add it to the `devDependencies` in `package.json` and specify in your `app.config.js`.
diff --git a/apps/fixtures/css/package.json b/apps/fixtures/css/package.json
new file mode 100644
index 000000000..b3b32953b
--- /dev/null
+++ b/apps/fixtures/css/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "fixture-css",
+ "type": "module",
+ "scripts": {
+ "dev": "vite dev",
+ "build": "vite build",
+ "start": "node .output/server/index.mjs"
+ },
+ "dependencies": {
+ "@solidjs/meta": "^0.29.4",
+ "@solidjs/router": "^0.15.0",
+ "@solidjs/start": "workspace:*",
+ "solid-js": "^1.9.9",
+ "vite": "7.1.10"
+ },
+ "engines": {
+ "node": ">=22"
+ },
+ "devDependencies": {
+ "@tailwindcss/vite": "^4.1.12",
+ "tailwindcss": "^4.1.12"
+ }
+}
diff --git a/apps/fixtures/css/public/favicon.ico b/apps/fixtures/css/public/favicon.ico
new file mode 100644
index 000000000..fb282da07
Binary files /dev/null and b/apps/fixtures/css/public/favicon.ico differ
diff --git a/apps/fixtures/css/src/app.css b/apps/fixtures/css/src/app.css
new file mode 100644
index 000000000..7b8888fa1
--- /dev/null
+++ b/apps/fixtures/css/src/app.css
@@ -0,0 +1,21 @@
+@import "tailwindcss";
+
+@theme {
+ --color-success: var(--color-emerald-700);
+ --color-error: var(--color-rose-700);
+ --color-warn: var(--color-orange-500);
+}
+
+@layer base {
+ body {
+ @apply bg-gray-800 text-gray-100;
+ }
+
+ a {
+ @apply text-sky-400 underline underline-offset-4 hover:no-underline;
+ }
+
+ h1 {
+ @apply text-2xl font-bold;
+ }
+}
diff --git a/apps/fixtures/css/src/app.tsx b/apps/fixtures/css/src/app.tsx
new file mode 100644
index 000000000..32aeff5ec
--- /dev/null
+++ b/apps/fixtures/css/src/app.tsx
@@ -0,0 +1,28 @@
+import { MetaProvider, Title } from "@solidjs/meta";
+import { Router } from "@solidjs/router";
+import { FileRoutes } from "@solidjs/start/router";
+import { Suspense } from "solid-js";
+import "./app.css";
+
+export default function App() {
+ return (
+ (
+
+ SolidStart - CSS Fixture
+
+
+ )}
+ >
+
+
+ );
+}
diff --git a/apps/fixtures/css/src/components/layout.tsx b/apps/fixtures/css/src/components/layout.tsx
new file mode 100644
index 000000000..91d077054
--- /dev/null
+++ b/apps/fixtures/css/src/components/layout.tsx
@@ -0,0 +1,56 @@
+import { createSignal, FlowProps, onMount } from "solid-js";
+import { getRequestEvent } from "solid-js/web";
+
+const Badge = (props: FlowProps) => (
+
{props.children}
+);
+
+const Layout = (props: FlowProps<{ title: string }>) => {
+ const [mounted, setMounted] = createSignal(false);
+ onMount(() => setMounted(true));
+
+ return (
+
+
+
{props.title}
+ Environment: {import.meta.env.DEV ? "DEV" : "PROD"}
+ Rendered: {!mounted() ? "Server" : "Server & Client"}
+
+
+
+ Agent:{" "}
+
+ {getRequestEvent()?.request.headers.get("user-agent") ?? navigator.userAgent}
+
+
+
+
+
+ Enable throttling & disable cache in the network tab to see eventual FOUC's (frames of unstyled
+ content)
+
+ Click on routes to test client navigation
+
+
+
+
+
Component
+
File
+
Integration
+
Lazy
+
Comments
+
+
+ {props.children}
+
+
+
+
pass
+
fail
+
not supported
+
+
+ );
+};
+
+export default Layout;
diff --git a/apps/fixtures/css/src/components/lazy.tsx b/apps/fixtures/css/src/components/lazy.tsx
new file mode 100644
index 000000000..462362ec2
--- /dev/null
+++ b/apps/fixtures/css/src/components/lazy.tsx
@@ -0,0 +1,7 @@
+import "../styles/lazy.css";
+
+const Lazy = () => {
+ return <>>
+}
+
+export default Lazy;
diff --git a/apps/fixtures/css/src/components/lazyGlob.tsx b/apps/fixtures/css/src/components/lazyGlob.tsx
new file mode 100644
index 000000000..75dca500b
--- /dev/null
+++ b/apps/fixtures/css/src/components/lazyGlob.tsx
@@ -0,0 +1,7 @@
+import "../styles/lazyGlob.css";
+
+const Lazy = () => {
+ return <>>
+}
+
+export default Lazy;
diff --git a/apps/fixtures/css/src/components/lazyLink.tsx b/apps/fixtures/css/src/components/lazyLink.tsx
new file mode 100644
index 000000000..f3b9084e7
--- /dev/null
+++ b/apps/fixtures/css/src/components/lazyLink.tsx
@@ -0,0 +1,5 @@
+import url from "../styles/lazyLink.css?url";
+
+const Lazy = () =>
+
+export default Lazy;
diff --git a/apps/fixtures/css/src/components/lazyLinkTmp.tsx b/apps/fixtures/css/src/components/lazyLinkTmp.tsx
new file mode 100644
index 000000000..3a04dd96e
--- /dev/null
+++ b/apps/fixtures/css/src/components/lazyLinkTmp.tsx
@@ -0,0 +1,5 @@
+import url from "../styles/lazyLinkTmp.css?url";
+
+const Lazy = () =>
+
+export default Lazy;
diff --git a/apps/fixtures/css/src/components/test.tsx b/apps/fixtures/css/src/components/test.tsx
new file mode 100644
index 000000000..8f3e8ea1a
--- /dev/null
+++ b/apps/fixtures/css/src/components/test.tsx
@@ -0,0 +1,107 @@
+import { JSX } from "solid-js";
+
+const clsx = (...args: (string | false | undefined)[]) => args.filter(Boolean).join(" ");
+
+const integrations = {
+ import: "import",
+ module: "import module",
+ url: "?url without render",
+ link: "?url + ",
+};
+const Test = (props: {
+ invert?: boolean;
+ class?: string;
+ component: string;
+ file: string;
+ integration?: keyof typeof integrations;
+ lazy?: boolean;
+ noSupport?: boolean;
+ comment?: JSX.Element;
+}) => (
+
+
{props.component}
+
{props.file}
+
{integrations[props.integration ?? "import"]}
+
{props.lazy ? <>✓> : null}
+
{props.comment}
+
+);
+
+export const CommonTests = (props: { routeModuleClass?: string }) => (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+ Tests fallbacks, only mounted while loading.
+
+ Red while mounted.
+ >
+ }
+ />
+ >
+);
+
+export default Test;
diff --git a/apps/fixtures/css/src/entry-client.tsx b/apps/fixtures/css/src/entry-client.tsx
new file mode 100644
index 000000000..b9fc52a4e
--- /dev/null
+++ b/apps/fixtures/css/src/entry-client.tsx
@@ -0,0 +1,5 @@
+// @refresh reload
+import { mount, StartClient } from "@solidjs/start/client";
+import "./styles/entryClient.css";
+
+mount(() => , document.getElementById("app")!);
diff --git a/apps/fixtures/css/src/entry-server.tsx b/apps/fixtures/css/src/entry-server.tsx
new file mode 100644
index 000000000..47822cea1
--- /dev/null
+++ b/apps/fixtures/css/src/entry-server.tsx
@@ -0,0 +1,24 @@
+// @refresh reload
+import { createHandler, StartServer } from "@solidjs/start/server";
+import "./styles/entryServer.css";
+import url from "./styles/entryServerUrl.css?url";
+
+export default createHandler(() => (
+ (
+
+
+
+
+
+
+ {assets}
+
+
+ {children}
+ {scripts}
+
+
+ )}
+ />
+));
diff --git a/apps/fixtures/css/src/global.d.ts b/apps/fixtures/css/src/global.d.ts
new file mode 100644
index 000000000..dc6f10c22
--- /dev/null
+++ b/apps/fixtures/css/src/global.d.ts
@@ -0,0 +1 @@
+///
diff --git a/apps/fixtures/css/src/routes/[...404].tsx b/apps/fixtures/css/src/routes/[...404].tsx
new file mode 100644
index 000000000..53b221ce7
--- /dev/null
+++ b/apps/fixtures/css/src/routes/[...404].tsx
@@ -0,0 +1,19 @@
+import { Title } from "@solidjs/meta";
+import { HttpStatusCode } from "@solidjs/start";
+
+export default function NotFound() {
+ return (
+
+ Not Found
+
+ Page Not Found
+
+ Visit{" "}
+
+ start.solidjs.com
+ {" "}
+ to learn how to build SolidStart apps.
+
+
+ );
+}
\ No newline at end of file
diff --git a/apps/fixtures/css/src/routes/empty.tsx b/apps/fixtures/css/src/routes/empty.tsx
new file mode 100644
index 000000000..65eff5795
--- /dev/null
+++ b/apps/fixtures/css/src/routes/empty.tsx
@@ -0,0 +1,10 @@
+import { Title } from "@solidjs/meta";
+
+export default function Empty() {
+ return (
+
+ Empty
+ Empty
+
+ );
+}
diff --git a/apps/fixtures/css/src/routes/index.tsx b/apps/fixtures/css/src/routes/index.tsx
new file mode 100644
index 000000000..08933785e
--- /dev/null
+++ b/apps/fixtures/css/src/routes/index.tsx
@@ -0,0 +1,44 @@
+import { createAsync, query } from "@solidjs/router";
+import { lazy, Show } from "solid-js";
+import Layout from "../components/layout";
+import { CommonTests } from "../components/test";
+import notRenderedInlineCSS from "../styles/notRendered.css?url";
+import "../styles/route.css";
+import classes from "../styles/route.module.css";
+import renderedInlineCSS from "../styles/url.css?url";
+
+const Lazy = lazy(() => import("../components/lazy"));
+const LazyLink = lazy(() => import("../components/lazyLink"));
+const LazyLinkTmp = lazy(() => import("../components/lazyLinkTmp"));
+
+const entries = import.meta.glob("../components/lazyG*.tsx");
+const LazyGlob = lazy(Object.values(entries)[0] as any);
+
+const getData = query(async () => {
+ "use server";
+ await new Promise(res => setTimeout(res, 1000));
+ return "CSS Tests";
+}, "data");
+
+export default function Home() {
+ const data = createAsync(() => getData(), { deferStream: true });
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/apps/fixtures/css/src/routes/unstyled.tsx b/apps/fixtures/css/src/routes/unstyled.tsx
new file mode 100644
index 000000000..f9b22315f
--- /dev/null
+++ b/apps/fixtures/css/src/routes/unstyled.tsx
@@ -0,0 +1,14 @@
+import { Title } from "@solidjs/meta";
+import Layout from "../components/layout";
+import { CommonTests } from "../components/test";
+
+export default function Others() {
+ return (
+
+ Unstyled
+
+
+
+
+ );
+}
diff --git a/apps/fixtures/css/src/styles/entryClient.css b/apps/fixtures/css/src/styles/entryClient.css
new file mode 100644
index 000000000..84dafa95c
--- /dev/null
+++ b/apps/fixtures/css/src/styles/entryClient.css
@@ -0,0 +1,3 @@
+.entryClient {
+ background-color: var(--color-success);
+}
diff --git a/apps/fixtures/css/src/styles/entryServer.css b/apps/fixtures/css/src/styles/entryServer.css
new file mode 100644
index 000000000..aac9295a0
--- /dev/null
+++ b/apps/fixtures/css/src/styles/entryServer.css
@@ -0,0 +1,3 @@
+.entryServer {
+ background-color: var(--color-success);
+}
diff --git a/apps/fixtures/css/src/styles/entryServerUrl.css b/apps/fixtures/css/src/styles/entryServerUrl.css
new file mode 100644
index 000000000..ce4d8b91c
--- /dev/null
+++ b/apps/fixtures/css/src/styles/entryServerUrl.css
@@ -0,0 +1,3 @@
+.entryServerUrl {
+ background-color: var(--color-success);
+}
diff --git a/apps/fixtures/css/src/styles/lazy.css b/apps/fixtures/css/src/styles/lazy.css
new file mode 100644
index 000000000..fdc1d5a60
--- /dev/null
+++ b/apps/fixtures/css/src/styles/lazy.css
@@ -0,0 +1,3 @@
+.lazy {
+ background-color: var(--color-success);
+}
diff --git a/apps/fixtures/css/src/styles/lazyGlob.css b/apps/fixtures/css/src/styles/lazyGlob.css
new file mode 100644
index 000000000..4c7b92f51
--- /dev/null
+++ b/apps/fixtures/css/src/styles/lazyGlob.css
@@ -0,0 +1,3 @@
+.lazyGlob {
+ background-color: var(--color-success);
+}
diff --git a/apps/fixtures/css/src/styles/lazyLink.css b/apps/fixtures/css/src/styles/lazyLink.css
new file mode 100644
index 000000000..50c6d1663
--- /dev/null
+++ b/apps/fixtures/css/src/styles/lazyLink.css
@@ -0,0 +1,3 @@
+.lazyLink {
+ background-color: var(--color-success);
+}
diff --git a/apps/fixtures/css/src/styles/lazyLinkTmp.css b/apps/fixtures/css/src/styles/lazyLinkTmp.css
new file mode 100644
index 000000000..3523d74df
--- /dev/null
+++ b/apps/fixtures/css/src/styles/lazyLinkTmp.css
@@ -0,0 +1,3 @@
+.lazyLinkTmp {
+ background-color: var(--color-error);
+}
diff --git a/apps/fixtures/css/src/styles/notRendered.css b/apps/fixtures/css/src/styles/notRendered.css
new file mode 100644
index 000000000..bf07490f8
--- /dev/null
+++ b/apps/fixtures/css/src/styles/notRendered.css
@@ -0,0 +1,3 @@
+.notRendered {
+ background-color: var(--color-error);
+}
diff --git a/apps/fixtures/css/src/styles/route.css b/apps/fixtures/css/src/styles/route.css
new file mode 100644
index 000000000..1cddfd725
--- /dev/null
+++ b/apps/fixtures/css/src/styles/route.css
@@ -0,0 +1,3 @@
+.route {
+ background-color: var(--color-success);
+}
diff --git a/apps/fixtures/css/src/styles/route.module.css b/apps/fixtures/css/src/styles/route.module.css
new file mode 100644
index 000000000..1cddfd725
--- /dev/null
+++ b/apps/fixtures/css/src/styles/route.module.css
@@ -0,0 +1,3 @@
+.route {
+ background-color: var(--color-success);
+}
diff --git a/apps/fixtures/css/src/styles/url.css b/apps/fixtures/css/src/styles/url.css
new file mode 100644
index 000000000..a587a91d2
--- /dev/null
+++ b/apps/fixtures/css/src/styles/url.css
@@ -0,0 +1,3 @@
+.url {
+ background-color: var(--color-success);
+}
diff --git a/apps/fixtures/css/tsconfig.json b/apps/fixtures/css/tsconfig.json
new file mode 100644
index 000000000..1f0bda6da
--- /dev/null
+++ b/apps/fixtures/css/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true,
+ "jsx": "preserve",
+ "jsxImportSource": "solid-js",
+ "allowJs": true,
+ "strict": true,
+ "noEmit": true,
+ "isolatedModules": true,
+ "paths": {
+ "~/*": ["./src/*"]
+ },
+ "types": ["vite/client"]
+ }
+}
diff --git a/apps/fixtures/css/vite.config.ts b/apps/fixtures/css/vite.config.ts
new file mode 100644
index 000000000..598584d4b
--- /dev/null
+++ b/apps/fixtures/css/vite.config.ts
@@ -0,0 +1,8 @@
+import tailwindcss from "@tailwindcss/vite";
+import { defineConfig } from "vite";
+import { nitroV2Plugin } from "../../../packages/start-nitro-v2-vite-plugin/src";
+import { solidStart } from "../../../packages/start/src/config";
+
+export default defineConfig({
+ plugins: [solidStart(), nitroV2Plugin(), tailwindcss()]
+});
diff --git a/packages/start/package.json b/packages/start/package.json
index 1c78617e0..23d52ccda 100644
--- a/packages/start/package.json
+++ b/packages/start/package.json
@@ -37,6 +37,7 @@
"dependencies": {
"@babel/core": "^7.28.3",
"@babel/traverse": "^7.28.3",
+ "@babel/types": "^7.28.5",
"@solidjs/meta": "^0.29.4",
"@tanstack/server-functions-plugin": "^1.133.11",
"@types/babel__traverse": "^7.28.0",
diff --git a/packages/start/src/config/fs-routes/index.ts b/packages/start/src/config/fs-routes/index.ts
index aff1cbd3c..81bad92fe 100644
--- a/packages/start/src/config/fs-routes/index.ts
+++ b/packages/start/src/config/fs-routes/index.ts
@@ -1,7 +1,6 @@
-import { relative, resolve } from "node:path";
-import { normalizePath, type PluginOption } from "vite";
+import { relative } from "node:path";
+import { type PluginOption } from "vite";
-import { VITE_ENVIRONMENTS } from "../constants.ts";
import { fileSystemWatcher } from "./fs-watcher.ts";
import type { BaseFileSystemRouter } from "./router.ts";
import { treeShake } from "./tree-shake.ts";
@@ -59,10 +58,7 @@ export function fsRoutes({ routers }: FsRoutesArgs): Array {
build: isBuild
? `_$() => import(/* @vite-ignore */ '${buildId}')$_`
: undefined,
- import:
- this.environment.name === VITE_ENVIRONMENTS.server
- ? `_$() => import(/* @vite-ignore */ '${buildId}')$_`
- : `_$(() => clientManifestImport('${relative(root, buildId)}'))$_`,
+ import: `_$() => import(/* @vite-ignore */ '${buildId}')$_`
};
}
return v;
@@ -72,15 +68,6 @@ export function fsRoutes({ routers }: FsRoutesArgs): Array {
const code = `
${js.getImportStatements()}
-${
- this.environment.name === VITE_ENVIRONMENTS.server
- ? ""
- : `
-import { getClientManifest } from "solid-start:get-client-manifest";
-function clientManifestImport(id) {
- return getClientManifest().import(id)
-}`
-}
export default ${routesCode}`;
return code;
},
diff --git a/packages/start/src/config/index.ts b/packages/start/src/config/index.ts
index 879eb6530..b284bdaa1 100644
--- a/packages/start/src/config/index.ts
+++ b/packages/start/src/config/index.ts
@@ -1,12 +1,11 @@
+import { TanStackServerFnPlugin } from "@tanstack/server-functions-plugin";
+import { defu } from "defu";
import { globSync } from "node:fs";
import { extname, isAbsolute, join, normalize } from "node:path";
import { fileURLToPath } from "node:url";
-import { TanStackServerFnPlugin } from "@tanstack/server-functions-plugin";
-import { defu } from "defu";
-import { type PluginOption, type ViteDevServer } from "vite";
+import { type PluginOption } from "vite";
import solid, { type Options as SolidOptions } from "vite-plugin-solid";
-import { isCssModulesFile } from "../server/collect-styles.ts";
import {
DEFAULT_EXTENSIONS,
VIRTUAL_MODULES,
@@ -19,6 +18,7 @@ import {
} from "./fs-router.ts";
import { fsRoutes } from "./fs-routes/index.ts";
import type { BaseFileSystemRouter } from "./fs-routes/router.ts";
+import lazy from "./lazy.ts";
import { manifest } from "./manifest.ts";
import { parseIdQuery } from "./utils.ts";
@@ -158,7 +158,6 @@ export function solidStart(options?: SolidStartOptions): Array {
},
},
manifest(start),
- css(),
fsRoutes({
routers: {
client: new SolidStartClientFileRouter({
@@ -172,6 +171,7 @@ export function solidStart(options?: SolidStartOptions): Array {
}),
},
}),
+ lazy(),
// Must be placed after fsRoutes, as treeShake will remove the
// server fn exports added in by this plugin
TanStackServerFnPlugin({
@@ -236,38 +236,3 @@ export function solidStart(options?: SolidStartOptions): Array {
}),
];
}
-
-function css(): PluginOption {
- let viteServer!: ViteDevServer;
- const cssModules: Record = {};
- return {
- name: "solid-start:css-hmr",
- configureServer(dev) {
- viteServer = dev;
- },
- async handleHotUpdate({ file, server }) {
- if (file.endsWith(".css")) {
- const resp = await server.transformRequest(file);
- if (!resp) return;
- const json = resp.code
- .match(/const __vite__css = .*\n/)?.[0]
- ?.slice("const __vite__css = ".length);
- if (!json) return;
- resp.code = JSON.parse(json);
- viteServer.ws.send({
- type: "custom",
- event: "css-update",
- data: {
- file,
- contents: resp.code,
- },
- });
- }
- },
- transform(code, id) {
- if (isCssModulesFile(id)) {
- cssModules[id] = code;
- }
- },
- };
-}
diff --git a/packages/start/src/config/lazy.ts b/packages/start/src/config/lazy.ts
new file mode 100644
index 000000000..65602f3bb
--- /dev/null
+++ b/packages/start/src/config/lazy.ts
@@ -0,0 +1,100 @@
+import type { PluginItem } from "@babel/core";
+import babel from "@babel/core";
+import * as t from "@babel/types";
+import { sep as osSep } from "path";
+import { basename, relative, sep } from "path/posix";
+import type { PluginOption } from "vite";
+import { VITE_ENVIRONMENTS } from "./constants.ts";
+
+const idTransform = (id: string): PluginItem => {
+ return {
+ visitor: {
+ Program(path) {
+ path.node.body.unshift(
+ t.exportNamedDeclaration(
+ t.variableDeclaration("const", [
+ t.variableDeclarator(t.identifier("id$$"), t.stringLiteral(id))
+ ])
+ )
+ );
+ }
+ }
+ };
+};
+
+const importTransform = (): PluginItem => {
+ return {
+ visitor: {
+ ImportDeclaration(path) {
+ if (path.node.source.value !== "solid-js") return;
+ path.traverse({
+ ImportSpecifier(subPath) {
+ if (subPath.node.local.name !== "lazy") return;
+ subPath.remove();
+ path.insertAfter(
+ t.importDeclaration(
+ [t.importSpecifier(t.identifier("lazy"), t.identifier("lazy"))],
+ t.stringLiteral("@solidjs/start/server")
+ )
+ );
+ }
+ });
+ }
+ }
+ };
+};
+
+const fileEndingRegex = /(ts|js)x(\?.*)?$/;
+
+const lazy = (): PluginOption => {
+ const cwd = process.cwd().replaceAll(osSep, sep);
+ return {
+ name: "solid-lazy-css",
+ enforce: "pre",
+ applyToEnvironment(env) {
+ return env.name === VITE_ENVIRONMENTS.server;
+ },
+ async transform(src, id) {
+ if (!id.match(fileEndingRegex)) return;
+
+ // The transformed files either import "lazy" or css files
+ // Therefore we skip, if the src doesn't have any import
+ if (src.indexOf("import") === -1) return;
+
+ const plugins: PluginItem[] = [];
+
+ const hasDefaultExport = src.indexOf("export default") !== -1;
+ if (hasDefaultExport) {
+ const localId = relative(cwd, id);
+ plugins.push(idTransform(localId));
+ }
+
+ const hasLazy = src.indexOf("lazy(") !== -1;
+ if (hasLazy) plugins.push(importTransform());
+
+ if (!plugins.length) {
+ return;
+ }
+
+ const transformed = await babel.transformAsync(src, {
+ plugins,
+ parserOpts: {
+ plugins: ["jsx", "typescript"]
+ },
+ filename: basename(id),
+ ast: false,
+ sourceMaps: true,
+ configFile: false,
+ babelrc: false,
+ sourceFileName: id
+ });
+
+ if (!transformed?.code) return;
+
+ const { code, map } = transformed;
+ return { code, map };
+ }
+ };
+};
+
+export default lazy;
diff --git a/packages/start/src/router.tsx b/packages/start/src/router.tsx
index e36da7381..7b2116e25 100644
--- a/packages/start/src/router.tsx
+++ b/packages/start/src/router.tsx
@@ -1,12 +1,15 @@
-import { getManifest } from "solid-start:get-manifest";
+import { lazy, type Component } from "solid-js";
import { getRequestEvent, isServer } from "solid-js/web";
-import lazyRoute from "./server/lazyRoute.tsx";
import { pageRoutes as routeConfigs } from "./server/routes.ts";
import type { PageEvent } from "./server/types.ts";
+const components: Record = {};
+
export function createRoutes() {
function createRoute(route: any) {
+ const component = route.$component && (components[route.$component.src] ??= lazy(route.$component.import));
+
return {
...route,
...(route.$$route ? route.$$route.require().route : undefined),
@@ -14,8 +17,7 @@ export function createRoutes() {
...(route.$$route ? route.$$route.require().route.info : {}),
filesystem: true
},
- component:
- route.$component && lazyRoute(route.$component, getManifest("client"), getManifest("ssr")),
+ component,
children: route.children ? route.children.map(createRoute) : undefined
};
}
diff --git a/packages/start/src/server/StartServer.tsx b/packages/start/src/server/StartServer.tsx
index 370e97831..1059412bf 100644
--- a/packages/start/src/server/StartServer.tsx
+++ b/packages/start/src/server/StartServer.tsx
@@ -1,37 +1,21 @@
// @refresh skip
-import App from "solid-start:app";
-import type { Component, JSX } from "solid-js";
+import type { Component } from "solid-js";
import {
Hydration,
HydrationScript,
NoHydration,
getRequestEvent,
- ssr,
- useAssets
+ ssr
} from "solid-js/web";
+import App from "solid-start:app";
import { ErrorBoundary, TopErrorBoundary } from "../shared/ErrorBoundary.tsx";
-import { renderAsset } from "./renderAsset.tsx";
-import type { Asset, DocumentComponentProps, PageEvent } from "./types.ts";
+import { useAssets } from "./assets/index.ts";
import { getSsrManifest } from "./manifest/ssr-manifest.ts";
+import type { DocumentComponentProps, PageEvent } from "./types.ts";
const docType = ssr("");
-function matchRoute(matches: any[], routes: any[], matched = []): any[] | undefined {
- for (let i = 0; i < routes.length; i++) {
- const segment = routes[i];
- if (segment.path !== matches[0].path) continue;
- let next: any = [...matched, segment];
- if (segment.children) {
- const nextMatches = matches.slice(1);
- if (nextMatches.length === 0) continue;
- next = matchRoute(nextMatches, segment.children, next);
- if (!next) continue;
- }
- return next;
- }
-}
-
/**
*
* Read more: https://docs.solidjs.com/solid-start/reference/server/start-server
@@ -41,60 +25,16 @@ export function StartServer(props: { document: Component
// @ts-ignore
const nonce = context.nonce;
-
- let assets: Asset[] = [];
- Promise.resolve()
- .then(async () => {
- const manifest = getSsrManifest("ssr");
-
- let assetPromises: Promise[] = [];
- // @ts-ignore
- if (context.router && context.router.matches) {
- // @ts-ignore
- const matches = [...context.router.matches];
- while (matches.length && (!matches[0].info || !matches[0].info.filesystem)) matches.shift();
- const matched = matches.length && matchRoute(matches, context.routes);
- if (matched) {
- for (let i = 0; i < matched.length; i++) {
- const segment = matched[i];
- assetPromises.push(manifest.getAssets(segment["$component"].src));
- }
- } else if (import.meta.env.DEV)
- console.warn(
- `No route matched for preloading js assets for path ${new URL(context.request.url).pathname}`
- );
- }
- assets = await Promise.all(assetPromises).then(a =>
- // dedupe assets
- [...new Map(a.flat().map(item => [item.attrs.key, item])).values()].filter(asset =>
- import.meta.env.START_ISLANDS
- ? false
- : (asset.attrs as JSX.LinkHTMLAttributes).rel === "modulepreload" &&
- !context.assets.find((a: Asset) => a.attrs.key === asset.attrs.key)
- )
- );
- })
- .catch(console.error);
-
- useAssets(() => (assets.length ? assets.map(m => renderAsset(m)) : undefined));
+ useAssets(context.assets, nonce);
return (
{docType as unknown as any}
-
- {context.assets.map((m: any) => renderAsset(m, nonce))}
- >
- }
+ assets={ }
scripts={
<>
-