Skip to content

Commit

Permalink
feat: add preact-ssr-prepass
Browse files Browse the repository at this point in the history
  • Loading branch information
Karpov Aleksandr Yuryevich authored and aleksandrjet committed Dec 27, 2023
1 parent 0ee255a commit cc6a41c
Show file tree
Hide file tree
Showing 29 changed files with 2,874 additions and 1,672 deletions.
5 changes: 5 additions & 0 deletions .changeset/cold-llamas-laugh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@astrojs/preact": patch
---

Allows rendering lazy components
1 change: 1 addition & 0 deletions examples/framework-preact-lazy/.codesandbox/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FROM node:18-bullseye
21 changes: 21 additions & 0 deletions examples/framework-preact-lazy/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# build output
dist/
# generated types
.astro/

# dependencies
node_modules/

# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*


# environment variables
.env
.env.production

# macOS-specific files
.DS_Store
4 changes: 4 additions & 0 deletions examples/framework-preact-lazy/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}
11 changes: 11 additions & 0 deletions examples/framework-preact-lazy/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}
13 changes: 13 additions & 0 deletions examples/framework-preact-lazy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Astro + Preact Example

```sh
npm create astro@latest -- --template framework-preact-lazy
```

[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/framework-preact-lazy)
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/framework-preact-lazy)
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/framework-preact-lazy/devcontainer.json)

This example showcases Astro working with [Preact](https://preactjs.com).

Write your Preact components as `.jsx` or `.tsx` files in your project.
8 changes: 8 additions & 0 deletions examples/framework-preact-lazy/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineConfig } from 'astro/config';
import preact from '@astrojs/preact';

// https://astro.build/config
export default defineConfig({
// Enable Preact to support Preact JSX components.
integrations: [preact({compat: true})],
});
19 changes: 19 additions & 0 deletions examples/framework-preact-lazy/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@example/framework-preact-lazy",
"type": "module",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/preact": "^3.0.1",
"@preact/signals": "^1.2.1",
"astro": "^3.6.0",
"preact": "^10.17.1"
}
}
9 changes: 9 additions & 0 deletions examples/framework-preact-lazy/public/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions examples/framework-preact-lazy/src/components/Counter.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.counter {
display: grid;
font-size: 2em;
grid-template-columns: repeat(3, minmax(0, 1fr));
margin-top: 2em;
place-items: center;
}
27 changes: 27 additions & 0 deletions examples/framework-preact-lazy/src/components/Counter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { h, Fragment } from 'preact';
import { Suspense, lazy } from 'preact/compat';
import './Counter.css';

const LazyMessage = lazy(() => import('./Message'));
const LazyNumberValue = lazy(() => import('./NumberValue'));
const Fallback = () => <p>i'm loader, which nobody should see</p>;

export default function Counter({ children, count }) {
const add = () => count.value++;
const subtract = () => count.value--;

return (
<>
<div class="counter">
<button onClick={subtract}>-</button>
<Suspense fallback={Fallback}>
<LazyNumberValue>{count}</LazyNumberValue>
</Suspense>
<button onClick={add}>+</button>
</div>
<Suspense fallback={Fallback}>
<LazyMessage>{children}</LazyMessage>
</Suspense>
</>
);
}
3 changes: 3 additions & 0 deletions examples/framework-preact-lazy/src/components/Message.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.message {
text-align: center;
}
5 changes: 5 additions & 0 deletions examples/framework-preact-lazy/src/components/Message.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import './Message.css';

export default function Message({ children }) {
return <div class="message">{children}</div>;
}
3 changes: 3 additions & 0 deletions examples/framework-preact-lazy/src/components/NumberValue.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function NumberValue({ children }) {
return <pre>{children}</pre>;
}
41 changes: 41 additions & 0 deletions examples/framework-preact-lazy/src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
// Component Imports
import Counter from '../components/Counter';
import { signal } from '@preact/signals';
// Full Astro Component Syntax:
// https://docs.astro.build/core-concepts/astro-components/
const count = signal(0);
---

<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<style>
html,
body {
font-family: system-ui;
margin: 0;
}
body {
padding: 2rem;
}
</style>
</head>
<body>
<main>
<Counter count={count} client:visible>
<h1>Hello, Preact 1!</h1>
</Counter>

<Counter count={count} client:visible>
<h1>Hello, Preact 2!</h1>
</Counter>
</main>
</body>
</html>
8 changes: 8 additions & 0 deletions examples/framework-preact-lazy/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "astro/tsconfigs/base",
"compilerOptions": {
// Preact specific settings
"jsx": "react-jsx",
"jsxImportSource": "preact"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineConfig } from 'astro/config';
import preact from '@astrojs/preact';
import mdx from '@astrojs/mdx';

// https://astro.build/config
export default defineConfig({
integrations: [preact(), mdx()],
});
11 changes: 11 additions & 0 deletions packages/astro/e2e/fixtures/preact-lazy-component/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "@e2e/preact-lazy-component",
"version": "0.0.0",
"private": true,
"dependencies": {
"@astrojs/mdx": "workspace:*",
"@astrojs/preact": "workspace:*",
"astro": "workspace:*",
"preact": "^10.15.1"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.counter {
display: grid;
font-size: 2em;
grid-template-columns: repeat(3, minmax(0, 1fr));
margin-top: 2em;
place-items: center;
}

.counter-message {
text-align: center;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { h, Fragment } from 'preact';
import { useState } from 'preact/hooks';
import { Suspense, lazy } from 'preact/compat';
import './Counter.css';

const LazyCounterMessage = lazy(() => import('./CounterMessage'))

export default function Counter({ children, count: initialCount, id }) {
const [count, setCount] = useState(initialCount);
const add = () => setCount((i) => i + 1);
const subtract = () => setCount((i) => i - 1);

return (
<>
<div id={id} className="counter">
<button className="decrement" onClick={subtract}>-</button>
<pre>{count}</pre>
<button className="increment" onClick={add}>+</button>
</div>
<Suspense fallback={<p>Load message...</p>}>
<LazyCounterMessage className="counter-message">{children}</LazyCounterMessage>
</Suspense>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const CounterMessage = (props) => {
return <div className={props.className}>{props.children}</div>
}

export default CounterMessage
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { h } from 'preact';

export default function({ id }) {
return <div id={id}>Framework client:only component</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<html>
<head><title>Preact component</title></head>
<body><slot></slot></body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
import Counter from '../components/Counter.jsx';
import PreactComponent from '../components/JSXComponent.jsx';
const someProps = {
count: 0,
};
---

<html>
<head>
<!-- Head Stuff -->
</head>
<body>
<Counter id="server-only" {...someProps}>
<h1>Hello, server!</h1>
</Counter>

<Counter id="client-idle" {...someProps} client:idle>
<h1>Hello, client:idle!</h1>
</Counter>

<Counter id="client-load" {...someProps} client:load>
<h1>Hello, client:load!</h1>
</Counter>

<Counter id="client-visible" {...someProps} client:visible>
<h1>Hello, client:visible!</h1>
</Counter>

<Counter id="client-media" {...someProps} client:media="(max-width: 50em)">
<h1>Hello, client:media!</h1>
</Counter>

<PreactComponent id="client-only" client:only="preact" />
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export { default } from '../components/Layout.astro';
import Counter from '../components/Counter.jsx';
import PreactComponent from '../components/JSXComponent.jsx';

export const someProps = {
count: 0,
};

<Counter id="server-only" {...someProps}>
# Hello, server!
</Counter>

<Counter id="client-idle" {...someProps} client:idle>
# Hello, client:idle!
</Counter>

<Counter id="client-load" {...someProps} client:load>
# Hello, client:load!
</Counter>

<Counter id="client-visible" {...someProps} client:visible>
# Hello, client:visible!
</Counter>

<Counter id="client-media" {...someProps} client:media="(max-width: 50em)">
# Hello, client:media!
</Counter>

<PreactComponent id="client-only" client:only="preact" />
24 changes: 24 additions & 0 deletions packages/astro/e2e/preact-lazy-component.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { prepareTestFactory } from './shared-component-tests.js';

const { test, createTests } = prepareTestFactory({ root: './fixtures/preact-lazy-component/' });

const config = {
counterComponentFilePath: './src/components/Counter.jsx',
componentFilePath: './src/components/JSXComponent.jsx',
};

test.describe('Preact lazy components in Astro files', () => {
createTests({
...config,
pageUrl: '/',
pageSourceFilePath: './src/pages/index.astro',
});
});

test.describe('Preact lazy components in MDX files', () => {
createTests({
...config,
pageUrl: '/mdx/',
pageSourceFilePath: './src/pages/mdx.mdx',
});
});
3 changes: 2 additions & 1 deletion packages/integrations/preact/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
"@preact/preset-vite": "^2.7.0",
"@preact/signals": "^1.2.1",
"babel-plugin-transform-hook-names": "^1.0.2",
"preact-render-to-string": "^6.3.1"
"preact-render-to-string": "^6.3.1",
"preact-ssr-prepass": "^1.2.1"
},
"devDependencies": {
"astro": "workspace:*",
Expand Down
Loading

0 comments on commit cc6a41c

Please sign in to comment.