Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Support React Server Component #6502

Open
wants to merge 24 commits into
base: release/rsc
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ce00d18
feat: rsc poc
chenjun1011 Aug 31, 2023
475b118
refactor: update react version
chenjun1011 Sep 1, 2023
3153c62
Merge branch 'release/rsc' into feat-rsc
chenjun1011 Sep 4, 2023
ae2d17e
fix: conflict
chenjun1011 Sep 4, 2023
d28ddd2
feat: bundle canary version of react (#6518)
ClarkXia Sep 7, 2023
cfe85e4
feat: rsc server route (#6528)
chenjun1011 Sep 13, 2023
a8a18eb
feat: rsc refresh (#6532)
chenjun1011 Sep 18, 2023
86bd500
Merge branch 'release/rsc' into feat-rsc
ClarkXia Sep 20, 2023
eaba00d
Merge branch 'feat-rsc' of github.com:alibaba/ice into feat-rsc
ClarkXia Sep 20, 2023
930d5b7
feat: support rsc transform by swc plugin (#6538)
ClarkXia Sep 22, 2023
823af35
chore: changeset
ClarkXia Sep 26, 2023
9301d5d
chore: package name
ClarkXia Sep 26, 2023
e5c9c4e
fix: root id (#6556)
chenjun1011 Sep 27, 2023
c136c38
chore: do not publish rsc example
ClarkXia Sep 27, 2023
b02f088
fix: decoupled from express (#6582)
chenjun1011 Oct 13, 2023
72c2898
Merge branch 'release/next' into feat-rsc
ClarkXia Oct 13, 2023
a7fd208
Merge branch 'feat-rsc' of github.com:alibaba/ice into feat-rsc
ClarkXia Oct 13, 2023
bdde149
Merge branch 'release/rsc' into feat-rsc
ClarkXia Oct 23, 2023
bcf6d4f
feat: bundle for client chunk (#6596)
chenjun1011 Oct 26, 2023
6198eea
fix: changeset (#6612)
chenjun1011 Oct 26, 2023
67dc6e9
fix: content type (#6616)
chenjun1011 Nov 1, 2023
e88c729
feat: render rsc into document (#6653)
chenjun1011 Nov 27, 2023
1cc8326
Merge branch 'release/rsc' into feat-rsc
ClarkXia Dec 26, 2023
c1deba8
fix: use compilation api to get assets
ClarkXia Dec 26, 2023
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
10 changes: 10 additions & 0 deletions .changeset/chilled-jars-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@ice/webpack-config': minor
'@ice/shared-config': minor
'@ice/runtime': minor
'@ice/app': minor
'@ice/bundles': patch
'@ice/route-manifest': patch
---

feat: support react server component
11 changes: 11 additions & 0 deletions examples/with-rsc/ice.config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineConfig } from '@ice/app';

export default defineConfig({
ssr: true,
// TODO: support esm format and resolve runtime dependencies to compiled dependencies.
server: {
bundle: true,
format: 'cjs',
},
rsc: true,
});
22 changes: 22 additions & 0 deletions examples/with-rsc/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "@examples/with-server-component",
"private": true,
"version": "1.0.0",
"scripts": {
"start": "ice start",
"build": "ice build"
},
"description": "ICE example with server-component",
"author": "ICE Team",
"license": "MIT",
"dependencies": {
"@ice/app": "workspace:*",
"@ice/runtime": "workspace:*",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6"
}
}
7 changes: 7 additions & 0 deletions examples/with-rsc/src/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineAppConfig } from 'ice';

export default defineAppConfig({
app: {
rootId: 'app',
},
});
33 changes: 33 additions & 0 deletions examples/with-rsc/src/components/Comments.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
async function Comments() {
const comments = await getData();

console.log('Render: Comments');

return (
<div>
{comments.map((comment, i) => (
<p className="comment" key={i}>
{comment}
</p>
))}
</div>
);
}

export default Comments;

const fakeData = [
"Wait, it doesn't wait for React to load?",
'How does this even work?',
'I like marshmallows',
];

async function getData() {
console.log('load comments');

await new Promise<any>((resolve) => {
setTimeout(() => resolve(null), 3000);
});

return fakeData;
}
21 changes: 21 additions & 0 deletions examples/with-rsc/src/components/Counter.client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use client';
import { useState } from 'react';
import { useAppContext } from 'ice';
import styles from './counter.module.css';

export default function Counter() {
const [count, setCount] = useState(0);

function updateCount() {
setCount(count + 1);
}

const appContext = useAppContext();
console.log(appContext);

return (
<button className={styles.button} type="button" onClick={updateCount}>
👍🏻 {count}
</button>
);
}
24 changes: 24 additions & 0 deletions examples/with-rsc/src/components/EditButton.client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use client';
import { useTransition } from 'react';

export default function EditButton({ noteId, children }) {
const [isPending, startTransition] = useTransition();
const isDraft = noteId == null;
return (
<button
className={[
'edit-button',
isDraft ? 'edit-button--solid' : 'edit-button--outline',
].join(' ')}
disabled={isPending}
onClick={() => {
startTransition(() => {
console.log('onClick');
});
}}
role="menuitem"
>
{children}
</button>
);
}
29 changes: 29 additions & 0 deletions examples/with-rsc/src/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useSuspenseData, withSuspense } from 'ice';

function Footer() {
const data = useSuspenseData(getData);

console.log('Render: Footer');

return (
<div>
<h2>{data.title}</h2>
</div>
);
}

export default withSuspense(Footer);

const fakeData = {
title: 'Thanks for reading!',
};

async function getData() {
console.log('load footer');

await new Promise<any>((resolve) => {
setTimeout(() => resolve(null), 2000);
});

return fakeData;
}
14 changes: 14 additions & 0 deletions examples/with-rsc/src/components/counter.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.link {
font-size: 1.2rem;
color: var(--primary);
}

.button {
outline: none;
border: none;
border-radius: 8px;
padding: 10px 35px;
background: var(--primary);
box-shadow: 0 5px 10px 0 #ddd;
font-size: calc(10px + 2vmin);
}
22 changes: 22 additions & 0 deletions examples/with-rsc/src/document.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Meta, Title, Links, Main, Scripts } from 'ice';

function Document() {
return (
<html>
<head>
<meta charSet="utf-8" />
<meta name="description" content="ICE 3.0 Demo" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Title />
<Links />
</head>
<body>
<Main />
<Scripts async />
</body>
</html>
);
}

export default Document;
30 changes: 30 additions & 0 deletions examples/with-rsc/src/pages/about.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.about {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}

.about > header {
display: flex;
flex-direction: column;
align-items: center;
}

.about > header > img {
width: 120px;
}

.about > header > p {
margin: 20px 0;
text-align: center;
font-size: 2.6rem;
}

.about > main {
display: flex;
flex-direction: column;
margin: 20px 0 10px;
font-size: 0.9rem;
}
22 changes: 22 additions & 0 deletions examples/with-rsc/src/pages/about.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useAppContext } from 'ice';
import styles from './about.module.css';
import Counter from '@/components/Counter.client';

if (!global.requestCount) {
global.requestCount = 0;
}

export default function Home() {
console.log('Render: Index');

const appContext = useAppContext();
console.log(appContext);

return (
<div className={styles.about}>
<h2>About Page</h2>
<div>server request count: { global.requestCount++ }</div>
<Counter />
</div>
);
}
30 changes: 30 additions & 0 deletions examples/with-rsc/src/pages/index.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.app {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}

.app > header {
display: flex;
flex-direction: column;
align-items: center;
}

.app > header > img {
width: 120px;
}

.app > header > p {
margin: 20px 0;
text-align: center;
font-size: 2.6rem;
}

.app > main {
display: flex;
flex-direction: column;
margin: 20px 0 10px;
font-size: 0.9rem;
}
27 changes: 27 additions & 0 deletions examples/with-rsc/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Suspense } from 'react';
import { useAppContext } from 'ice';
import styles from './index.module.css';
import EditButton from '@/components/EditButton.client';
import Counter from '@/components/Counter.client';
import Comments from '@/components/Comments';

export default function Home() {
console.log('Render: Index');

const appContext = useAppContext();
console.log(appContext);

return (
<div className={styles.app}>
<h2>Home Page</h2>
<Counter />
<Suspense fallback={<>loading</>}>
{/* @ts-ignore */}
<Comments />
</Suspense>
<EditButton noteId="editButton">
hello world
</EditButton>
</div>
);
}
10 changes: 10 additions & 0 deletions examples/with-rsc/src/pages/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default function Layout(props) {
console.log('Render: Layout');

return (
<div>
<h1>Suspense App</h1>
{props.children}
</div>
);
}
1 change: 1 addition & 0 deletions examples/with-rsc/src/typings.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="@ice/app/types" />
32 changes: 32 additions & 0 deletions examples/with-rsc/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"compileOnSave": false,
"buildOnSave": false,
"compilerOptions": {
"baseUrl": ".",
"outDir": "build",
"module": "esnext",
"target": "esnext",
"jsx": "react-jsx",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"rootDir": "./",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": false,
"importHelpers": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true,
"skipLibCheck": true,
"paths": {
"@/*": ["./src/*"],
"ice": [".ice"]
}
},
"include": ["src", ".ice", "ice.config.*"],
"exclude": ["build", "public"]
}
Loading
Loading