0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-30 22:03:56 -05:00
This commit is contained in:
github-actions[bot] 2024-12-16 19:52:08 +00:00
commit f0994f6385
16 changed files with 314 additions and 0 deletions

1
.codesandbox/Dockerfile Normal file
View file

@ -0,0 +1 @@
FROM node:18-bullseye

24
.gitignore vendored Normal file
View file

@ -0,0 +1,24 @@
# 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
# jetbrains setting folder
.idea/

4
.vscode/extensions.json vendored Normal file
View file

@ -0,0 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

11
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

13
README.md Normal file
View file

@ -0,0 +1,13 @@
# Kitchen Sink: Microfrontends with Astro
```sh
npm create astro@latest -- --template framework-multiple
```
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/framework-multiple)
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/framework-multiple)
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/framework-multiple/devcontainer.json)
This example showcases Astro's built-in support for multiple frameworks ([React](https://react.dev), [Preact](https://preactjs.com), [Svelte](https://svelte.dev), and [Vue (`v3.x`)](https://v3.vuejs.org/)).
No configuration is needed to enable these frameworks—just start writing components in `src/components`.

19
astro.config.mjs Normal file
View file

@ -0,0 +1,19 @@
// @ts-check
import { defineConfig } from 'astro/config';
import preact from '@astrojs/preact';
import react from '@astrojs/react';
import svelte from '@astrojs/svelte';
import vue from '@astrojs/vue';
import solid from '@astrojs/solid-js';
// https://astro.build/config
export default defineConfig({
// Enable many frameworks to support all different kinds of components.
integrations: [
preact({ include: ['**/preact/*'] }),
solid({ include: ['**/solid/*'] }),
react({ include: ['**/react/*'] }),
svelte(),
vue(),
],
});

28
package.json Normal file
View file

@ -0,0 +1,28 @@
{
"name": "@example/framework-multiple",
"type": "module",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/preact": "^4.0.0",
"@astrojs/react": "^4.1.1",
"@astrojs/solid-js": "^5.0.0",
"@astrojs/svelte": "^7.0.1",
"@astrojs/vue": "^5.0.2",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"astro": "^5.0.8",
"preact": "^10.24.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"solid-js": "^1.9.3",
"svelte": "^5.1.16",
"vue": "^3.5.12"
}
}

9
public/favicon.svg Normal file
View file

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
</svg>

After

Width:  |  Height:  |  Size: 749 B

View file

@ -0,0 +1,22 @@
/** @jsxImportSource preact */
import { useState } from 'preact/hooks';
import type { ComponentChildren } from 'preact';
/** A counter written with Preact */
export function PreactCounter({ children }: { children?: ComponentChildren }) {
const [count, setCount] = useState(0);
const add = () => setCount((i) => i + 1);
const subtract = () => setCount((i) => i - 1);
return (
<>
<div class="counter">
<button onClick={subtract}>-</button>
<pre>{count}</pre>
<button onClick={add}>+</button>
</div>
<div class="counter-message">{children}</div>
</>
);
}

View file

@ -0,0 +1,21 @@
/** @jsxImportSource react */
import { useState, type ReactNode } from 'react';
/** A counter written with React */
export function Counter({ children }: { children?: ReactNode }) {
const [count, setCount] = useState(0);
const add = () => setCount((i) => i + 1);
const subtract = () => setCount((i) => i - 1);
return (
<>
<div className="counter">
<button onClick={subtract}>-</button>
<pre>{count}</pre>
<button onClick={add}>+</button>
</div>
<div className="counter-message">{children}</div>
</>
);
}

View file

@ -0,0 +1,21 @@
/** @jsxImportSource solid-js */
import { createSignal, type JSX } from 'solid-js';
/** A counter written with Solid */
export default function SolidCounter(props: { children?: JSX.Element }) {
const [count, setCount] = createSignal(0);
const add = () => setCount(count() + 1);
const subtract = () => setCount(count() - 1);
return (
<>
<div id="solid" class="counter">
<button onClick={subtract}>-</button>
<pre>{count()}</pre>
<button onClick={add}>+</button>
</div>
<div class="counter-message">{props.children}</div>
</>
);
}

View file

@ -0,0 +1,30 @@
<!-- @component
A counter written with Svelte
-->
<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
children?: Snippet
}
let { children }: Props = $props();
let count = $state(0);
function add() {
count += 1;
}
function subtract() {
count -= 1;
}
</script>
<div class="counter">
<button onclick={subtract}>-</button>
<pre>{count}</pre>
<button onclick={add}>+</button>
</div>
<div class="counter-message">
{@render children?.()}
</div>

View file

@ -0,0 +1,33 @@
<template>
<!--
Seeing type errors on the word `class`?
This unfortunately happens because @types/react's JSX definitions leak into every file due to being declared globally.
There's currently no way to prevent this when using both Vue and React with TypeScript in the same project.
You can read more about this issue here: https://github.com/johnsoncodehk/volar/discussions/592
-->
<div class="counter">
<button @click="subtract()">-</button>
<pre>{{ count }}</pre>
<button @click="add()">+</button>
</div>
<div class="counter-message">
<slot />
</div>
</template>
<script lang="ts">
import { ref } from 'vue';
export default {
setup() {
const count = ref(0);
const add = () => (count.value = count.value + 1);
const subtract = () => (count.value = count.value - 1);
return {
count,
add,
subtract,
};
},
};
</script>

48
src/pages/index.astro Normal file
View file

@ -0,0 +1,48 @@
---
// Style Imports
import '../styles/global.css';
// Component Imports
// For JSX components, all the common ways of exporting (under a namespace, specific export, default export etc) are supported!
import * as react from '../components/react/ReactCounter';
import { PreactCounter } from '../components/preact/PreactCounter';
import SolidCounter from '../components/solid/SolidCounter';
import VueCounter from '../components/vue/VueCounter.vue';
import SvelteCounter from '../components/svelte/SvelteCounter.svelte';
// Full Astro Component Syntax:
// https://docs.astro.build/basics/astro-components/
---
<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" />
</head>
<body>
<main>
<react.Counter client:visible>
<h1>Hello from React!</h1>
</react.Counter>
<PreactCounter client:visible>
<h1>Hello from Preact!</h1>
</PreactCounter>
<SolidCounter client:visible>
<h1>Hello from Solid!</h1>
</SolidCounter>
<VueCounter client:visible>
<h1>Hello from Vue!</h1>
</VueCounter>
<SvelteCounter client:visible>
<h1>Hello from Svelte!</h1>
</SvelteCounter>
</main>
</body>
</html>

21
src/styles/global.css Normal file
View file

@ -0,0 +1,21 @@
html,
body {
font-family: system-ui;
margin: 0;
}
body {
padding: 2rem;
}
.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;
}

9
tsconfig.json Normal file
View file

@ -0,0 +1,9 @@
{
"extends": "astro/tsconfigs/strict",
"include": [".astro/types.d.ts", "**/*"],
"exclude": ["dist"],
"compilerOptions": {
// Needed for TypeScript intellisense in the template inside Vue files
"jsx": "preserve"
}
}