首页
/ Astro 多框架集成实战:一个项目同时使用 React、Preact、Solid、Svelte 与 Vue

Astro 多框架集成实战:一个项目同时使用 React、Preact、Solid、Svelte 与 Vue

2026-09-04 13:26:23作者:田桥桑Industrious

本篇基于 Astro 官方示例 examples/framework-multiple("Kitchen Sink: Microfrontends with Astro")展开,演示如何在一个 Astro 项目中同时接入五种前端框架的组件。读完后你将掌握:如何通过 integrations 配置让多框架共存、include/exclude 过滤器如何避免 Vite 插件之间的文件处理冲突,以及各框架组件在 Astro 页面中导入与客户端加载的完整写法。

一、示例定位:Astro 的多框架原生支持

该示例的核心主张只有一句话:Astro 内置了对多个前端框架的支持,可以在同一个项目中同时使用 React、Preact、Svelte 和 Vue(v3.x),甚至还能加上 Solid。README 中的关键说明是:

No configuration is needed to enable these frameworks—just start writing components in src/components.

也就是说,框架集成能力来自 Astro 生态的官方集成包(@astrojs/react@astrojs/preact 等),只需在 astro.config.mjs 中注册即可,不需要额外脚手架或构建工具改造。

用一条命令创建项目

官方提供了 framework-multiple 模板,可以直接创建此示例项目:

npm create astro@latest -- --template framework-multiple

项目目录结构如下(摘自本仓库 examples/framework-multiple 实际文件):

examples/framework-multiple/
├── astro.config.mjs            # 注册五个框架集成
├── package.json                # 依赖:五个框架 + 五个官方集成包
├── tsconfig.json               # 继承 astro/tsconfigs/strict
└── src/
    ├── components/
    │   ├── preact/PreactCounter.tsx
    │   ├── react/ReactCounter.tsx
    │   ├── solid/SolidCounter.tsx
    │   ├── svelte/SvelteCounter.svelte
    │   └── vue/VueCounter.vue
    ├── pages/index.astro      # 同页混用五种框架组件
    └── styles/global.css

每个框架组件都是一个结构相同的计数器:一个 -/+ 按钮、一个 <pre> 显示计数,外加一个接收插槽内容的消息区。五个组件在同一个首页上并排渲染,直观验证"多框架共存"的可行性。

二、核心配置:integrations 与 include 过滤器

多框架项目最关键的配置文件是 examples/framework-multiple/astro.config.mjs

// @ts-check

import preact from '@astrojs/preact';
import react from '@astrojs/react';
import solid from '@astrojs/solid-js';
import svelte from '@astrojs/svelte';
import vue from '@astrojs/vue';
import { defineConfig } from 'astro/config';

// 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(),
	],
});

这里有几个值得注意的要点:

  1. 每个框架对应一个官方集成包,通过 integrations 数组注册。从 examples/framework-multiple/package.json 可以看到当前示例使用的版本组合:@astrojs/preact@^6.0.5@astrojs/react@^6.0.5@astrojs/solid-js@^7.0.2@astrojs/svelte@^9.0.1@astrojs/vue@^7.0.2,同时安装了框架本体(preactreact/react-domsolid-jssveltevue),Node 要求为 >=22.12.0
  2. include 把各 JSX 类框架的文件隔离到独立目录。示例中 react({ include: ['**/react/*'] })preact({ include: ['**/preact/*'] })solid({ include: ['**/solid/*'] }) 各管各的目录。这一设计的原因在于:React、Preact、Solid 三者都使用 .tsx 扩展名且 JSX 语义相近(如 onClick),若不限制文件范围,Vite 插件可能把 Preact 文件交给 React 编译器处理,导致运行时错误。
  3. Svelte 和 Vue 不需要 include。Svelte 组件是独立的 .svelte 文件、Vue 是 .vue 文件,扩展名天然不冲突,因此直接 svelte()vue() 即可。

从源码结构看,include 参数确实会透传给底层的 Vite 框架插件:在 packages/integrations/react/src/index.ts 中,集成接收 include/exclude 选项后分别传给 Vite 的 React 插件(编译范围控制)与 Astro 的客户端岛处理链路;该文件还会自动将 .astro 文件加入 exclude(注释说明在 Vite 8 中 @vitejs/plugin-react 需要显式排除 .astro 文件),保证 Astro 模板本身不会被 React 编译器误处理。

三、页面层:一个页面同时渲染五个框架的组件

examples/framework-multiple/src/pages/index.astro 展示了五种框架组件在同一个 Astro 页面中的完整用法:

---
// Style Imports
import '../styles/global.css';

import { PreactCounter } from '../components/preact/PreactCounter';
// 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 SolidCounter from '../components/solid/SolidCounter';
import SvelteCounter from '../components/svelte/SvelteCounter.svelte';
import VueCounter from '../components/vue/VueCounter.vue';
---

<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" />
		<link rel="icon" href="/favicon.ico" />
	</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>

其中体现的两类要点:

  • JSX 组件的导入方式非常灵活。源码注释明确写道:"For JSX components, all the common ways of exporting (under a namespace, specific export, default export etc) are supported!"。示例中 React 组件用了命名空间导入(import * as react,页面上写作 <react.Counter>),Preact/Solid 用常规命名/默认导入,Svelte/Vue 直接按扩展名导入。
  • client:visible 客户端指令。五个计数器都需要交互,统一使用 client:visible:当组件滚动进入视口时才加载对应的框架运行时并水合,比无条件加载更省首屏成本。各框架的运行时(React、Preact 等)会被打包成独立的客户端岛,只有在需要时才下载执行。

页面样式由 examples/framework-multiple/src/styles/global.css 提供,.counter 用 CSS Grid 三列布局排列 -、计数、+

四、五个框架组件的实现对照

每个组件都是一个"计数器 + 插槽",实现方式恰好覆盖各自框架的惯用语法,适合作为跨框架速查对照。

React:显式指定 JSX 来源

examples/framework-multiple/src/components/react/ReactCounter.tsx 第一行是 /** @jsxImportSource react */——在多框架项目中这一行至关重要:TypeScript 需要知道该 .tsx 文件的 JSX 应编译为 React.createElement 而非其他框架的运行时。

/** @jsxImportSource react */
import { type ReactNode, useState } from '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>
		</>
	);
}

Preact 的写法几乎一致(PreactCounter.tsx),只是 @jsxImportSource preact、hooks 从 preact/hooks 导入;Solid(SolidCounter.tsx)则换成 @jsxImportSource solid-jscreateSignal 响应式原语。

Svelte 5:runes 语法

SvelteCounter.svelte 使用 Svelte 5 的 runes:$props() 接收插槽(类型 Snippet),$state(0) 声明响应式计数,模板中 {@render children?.()} 渲染插槽。

Vue 3:setup() + 一个已知的类型提示噪音

VueCounter.vue 使用组合式 API 的 Options 风格 setup()ref(0) 声明计数。该文件里还保留了一条很有价值的注释:如果 Vue 模板中的 class 出现类型错误,原因是 @types/react 的 JSX 定义是全局声明、会泄漏到项目所有文件,在 React 与 Vue 共用 TypeScript 的项目中目前没有完全规避的办法。这提示在混合项目中若遇到此类编辑器误报,属于已知现象而非配置错误。

五、TypeScript 配置:让 Vue 模板获得智能提示

examples/framework-multiple/tsconfig.json 只有一处特殊配置:

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

继承 Astro 官方的 strict 预设,jsx: "preserve" 则是为了让 Vue 单文件组件的 <template> 部分(内含 JSX 风格的模板语法)获得 TypeScript 智能提示。

六、运行验证:官方 e2e 测试如何覆盖多框架场景

Astro 仓库自带一套 Playwright e2e 测试来验证多框架场景,即 packages/astro/e2e/multiple-frameworks.test.ts,它对每个框架的计数器做了一致的断言:

  • 页面加载后对应 #react-counter#preact-counter#solid-counter#vue-counter#svelte-counter 均可见且初始计数为 0
  • 点击 .increment 按钮后计数变为 1,证明各框架组件的客户端事件绑定真正生效;
  • 还包含一组 HMR 用例:分别修改各框架组件源码(如 React 的 useState(0) 改为 useState(5)、Vue 的 ref(0) 改为 ref(5)、Svelte 的 let count = 0 改为 let count = 5),断言开发服务器热更新后计数器初始值变化——说明多框架集成下各框架的热替换能力同样可用。

该测试基于独立的 fixture(packages/astro/e2e/fixtures/multiple-frameworks/)运行,验证的是 Astro 核心与集成层的组合行为,与本文示例目录互为印证。

小结

把这篇示例的要点浓缩成可复用的实践清单:

  1. 注册集成:在 astro.config.mjsintegrations 中加入需要的 @astrojs/* 集成包,无需其他配置;
  2. 目录隔离:JSX 类框架(React/Preact/Solid)建议通过 { include: ['**/框架名/*'] } 限定处理范围,.svelte/.vue 组件可免配置;
  3. 显式 JSX 来源:每个 .tsx 组件文件首行用 @jsxImportSource 注释指明所属框架;
  4. 按需水合:交互组件配合 client:visible 等指令,只在需要时加载对应框架运行时;
  5. TS 兼容:使用 astro/tsconfigs/strict 预设,并视 Vue 提示需求开启 jsx: "preserve"

这套机制使"微前端"式的多技术栈共存成为可能——团队可以按组件维度选择最合适的框架,而整个站点仍由 Astro 的构建、路由与渲染管线统一托管。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
903
1.82 K
docsdocs
暂无描述
Markdown
888
5.78 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.51 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384
flutter_flutterflutter_flutter
本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本,由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用,3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。
Dart
1.17 K
341