diff --git a/examples/09_cssmodules/package.json b/examples/09_cssmodules/package.json new file mode 100644 index 000000000..c19a6f178 --- /dev/null +++ b/examples/09_cssmodules/package.json @@ -0,0 +1,23 @@ +{ + "name": "waku-example", + "version": "0.1.0", + "type": "module", + "private": true, + "scripts": { + "dev": "waku dev --with-ssr", + "build": "waku build", + "start": "waku start --with-ssr" + }, + "dependencies": { + "express": "^4.18.2", + "react": "18.3.0-canary-7118f5dd7-20230705", + "react-dom": "18.3.0-canary-7118f5dd7-20230705", + "react-server-dom-webpack": "18.3.0-canary-7118f5dd7-20230705", + "waku": "0.13.0" + }, + "devDependencies": { + "@types/react": "^18.2.8", + "@types/react-dom": "^18.2.4", + "typescript": "^5.1.3" + } +} diff --git a/examples/09_cssmodules/src/components/App.module.css b/examples/09_cssmodules/src/components/App.module.css new file mode 100644 index 000000000..ba188ac7a --- /dev/null +++ b/examples/09_cssmodules/src/components/App.module.css @@ -0,0 +1,3 @@ +.title { + background-color: pink; +} diff --git a/examples/09_cssmodules/src/components/App.tsx b/examples/09_cssmodules/src/components/App.tsx new file mode 100644 index 000000000..403f90f5f --- /dev/null +++ b/examples/09_cssmodules/src/components/App.tsx @@ -0,0 +1,15 @@ +// @ts-expect-error no types +import styles from "./App.module.css"; +import { Counter } from "./Counter.js"; + +const App = ({ name = "Anonymous" }) => { + return ( +
+

Hello {name}!!

+

This is a server component.

+ +
+ ); +}; + +export default App; diff --git a/examples/09_cssmodules/src/components/Counter.tsx b/examples/09_cssmodules/src/components/Counter.tsx new file mode 100644 index 000000000..5313c81b9 --- /dev/null +++ b/examples/09_cssmodules/src/components/Counter.tsx @@ -0,0 +1,14 @@ +"use client"; + +import { useState } from "react"; + +export const Counter = () => { + const [count, setCount] = useState(0); + return ( +
+

Count: {count}

+ +

This is a client component.

+
+ ); +}; diff --git a/examples/09_cssmodules/src/entries.ts b/examples/09_cssmodules/src/entries.ts new file mode 100644 index 000000000..a03ce81f2 --- /dev/null +++ b/examples/09_cssmodules/src/entries.ts @@ -0,0 +1,30 @@ +import { defineEntries } from "waku/server"; + +export default defineEntries( + // getEntry + async (id) => { + switch (id) { + case "App": + return import("./components/App.js"); + default: + return null; + } + }, + // getBuildConfig + async () => { + return { + "/": { + elements: [["App", { name: "Waku" }]], + }, + }; + }, + // getSsrConfig + async (pathStr) => { + switch (pathStr) { + case "/": + return { element: ["App", { name: "Waku" }] }; + default: + return null; + } + } +); diff --git a/examples/09_cssmodules/src/index.html b/examples/09_cssmodules/src/index.html new file mode 100644 index 000000000..3e0d83554 --- /dev/null +++ b/examples/09_cssmodules/src/index.html @@ -0,0 +1,37 @@ + + + + + Waku example + + + + + +
+
+
+ + + + + + diff --git a/examples/09_cssmodules/src/main.tsx b/examples/09_cssmodules/src/main.tsx new file mode 100644 index 000000000..35d09bd58 --- /dev/null +++ b/examples/09_cssmodules/src/main.tsx @@ -0,0 +1,12 @@ +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import { serve } from "waku/client"; + +const App = serve<{ name: string }>("App"); +const rootElement = ( + + + +); + +createRoot(document.getElementById("root")!).render(rootElement); diff --git a/examples/09_cssmodules/tsconfig.json b/examples/09_cssmodules/tsconfig.json new file mode 100644 index 000000000..7781cf1ae --- /dev/null +++ b/examples/09_cssmodules/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "strict": true, + "target": "esnext", + "downlevelIteration": true, + "esModuleInterop": true, + "module": "nodenext", + "skipLibCheck": true, + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + "jsx": "react-jsx" + } +} diff --git a/package.json b/package.json index 7c37ed7b1..67529593b 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "examples:dev:06_nesting": "NAME=06_nesting npm run examples:dev", "examples:dev:07_router": "NAME=07_router npm run examples:dev", "examples:dev:08_cookies": "NAME=08_cookies npm run examples:dev", + "examples:dev:09_cssmodules": "NAME=09_cssmodules npm run examples:dev", "examples:build": "npm run compile:code && (cd ./examples/${NAME} && npm run build)", "examples:prd": "npm run examples:build && (cd ./examples/${NAME} && npm start)", "examples:prd:01_counter": "NAME=01_counter npm run examples:prd", @@ -74,6 +75,7 @@ "examples:prd:06_nesting": "NAME=06_nesting npm run examples:prd", "examples:prd:07_router": "NAME=07_router npm run examples:prd", "examples:prd:08_cookies": "NAME=08_cookies npm run examples:prd", + "examples:prd:09_cssmodules": "NAME=09_cssmodules npm run examples:prd", "website:dev": "npm run compile:code && ./dist/cli.js dev --config ./website/vite.config.ts", "website:build": "npm run compile:code && ./dist/cli.js build --config ./website/vite.config.ts", "website:vercel": "npm run website:build && cp -Lr ./website/dist/.vercel/output ./.vercel/", @@ -111,7 +113,6 @@ "eslint-plugin-react": "^7.32.2", "express": "^4.18.2", "glob": "^10.3.1", - "postcss": "^8.4.24", "prettier": "^2.8.8", "react": "18.3.0-canary-7118f5dd7-20230705", "react-dom": "18.3.0-canary-7118f5dd7-20230705", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 76faa90d5..f96ec3296 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -77,9 +77,6 @@ importers: glob: specifier: ^10.3.1 version: 10.3.1 - postcss: - specifier: ^8.4.24 - version: 8.4.24 prettier: specifier: ^2.8.8 version: 2.8.8 @@ -335,6 +332,34 @@ importers: specifier: ^5.1.3 version: 5.1.6 + examples/09_cssmodules: + dependencies: + express: + specifier: ^4.18.2 + version: 4.18.2 + react: + specifier: 18.3.0-canary-7118f5dd7-20230705 + version: 18.3.0-canary-7118f5dd7-20230705 + react-dom: + specifier: 18.3.0-canary-7118f5dd7-20230705 + version: 18.3.0-canary-7118f5dd7-20230705(react@18.3.0-canary-7118f5dd7-20230705) + react-server-dom-webpack: + specifier: 18.3.0-canary-7118f5dd7-20230705 + version: 18.3.0-canary-7118f5dd7-20230705(react-dom@18.3.0-canary-7118f5dd7-20230705)(react@18.3.0-canary-7118f5dd7-20230705)(webpack@5.88.1) + waku: + specifier: 0.13.0 + version: link:../.. + devDependencies: + '@types/react': + specifier: ^18.2.8 + version: 18.2.14 + '@types/react-dom': + specifier: ^18.2.4 + version: 18.2.6 + typescript: + specifier: ^5.1.3 + version: 5.1.6 + website: {} packages: diff --git a/src/lib/middleware/rsc/worker-impl.ts b/src/lib/middleware/rsc/worker-impl.ts index 0271b0790..f6858dab9 100644 --- a/src/lib/middleware/rsc/worker-impl.ts +++ b/src/lib/middleware/rsc/worker-impl.ts @@ -1,6 +1,7 @@ import path from "node:path"; import { parentPort } from "node:worker_threads"; import { Writable } from "node:stream"; +import { Server } from "node:http"; import { createServer as viteCreateServer } from "vite"; import { createElement } from "react"; @@ -96,6 +97,8 @@ const handleGetSsrConfig = async ( } }; +const dummyServer = new Server(); + const vitePromise = viteCreateServer({ ...configFileConfig, plugins: [ @@ -114,6 +117,7 @@ const vitePromise = viteCreateServer({ conditions: ["react-server"], }, appType: "custom", + server: { middlewareMode: true, hmr: { server: dummyServer } }, }); const shutdown = async () => {