Vite + Qwik 模板:用 create-vite 搭建 CSR 模式的 Qwik 应用
本文基于 Vite 仓库中 create-vite 包的 Qwik 模板说明文档(template-qwik/README.md),完整讲解这个 Qwik 入门模板的定位、CSR(纯客户端渲染)配置方式、目录结构与脚本用法,并结合仓库内模板源码与 CLI 实现,说明它与完整生产级 Qwik 应用(SSR + QwikCity)之间的边界。读完本文,你将掌握如何用 create-vite 一键生成 Qwik 项目、理解 qwikVite({ csr: true }) 配置的含义,以及何时应该改用 Qwik 官方脚手架。
模板定位:Qwik 的纯 CSR 起步模板
Qwik 官方最强调的特性(如 Resumability、服务端渲染)依赖 SSR 模式,而 create-vite 仓库内置的 Qwik 模板走的是另一条路线:
这个 starter 使用的是纯 CSR(Client-Side Rendering)模式,即应用完全在浏览器中完成引导。而 Qwik 的大部分创新特性是在 SSR(Server-Side Rendering)模式下才能发挥作用的。 —— 原文见 README
这意味着该模板的核心取舍非常明确:只依赖 Vite 的 dev server 与静态构建产物,不需要 Node.js 服务端参与渲染。模板生成的项目(template-qwik/package.json)中,唯一的前端运行时依赖是:
@builder.io/qwik(版本范围^1.20.0)- devDependencies 中的
vite(^8.2.2)与serve(^14.2.6,用于本地预览构建产物)
如果目标是构建完整的生产级 Qwik 应用(SSR + QwikCity 元框架),文档给出的建议是直接运行 npm create qwik@latest。这一点在 Vite CLI 的实现中同样得到印证:在 create-vite 源码 的框架列表里,Qwik 分组除了内置的 qwik-ts(TypeScript)与 qwik(JavaScript)两个模板变体外,还提供了 custom-qwik-city 变体,其背后执行的命令正是 npm create qwik@latest empty TARGET_DIR。从源码结构看,Vite 把"轻量 CSR 模板"和"Qwik 官方全功能脚手架"并列为两个入口,让使用者按需求二选一。
Vite 配置:qwikVite 插件与 csr 选项
模板的 Vite 配置极为精简,全部逻辑集中在 vite.config.js:
import { qwikVite } from '@builder.io/qwik/optimizer'
import { defineConfig } from 'vite'
// https://vite.dev/config/
export default defineConfig({
plugins: [
qwikVite({
csr: true,
}),
],
})
各要素说明:
qwikVite插件:从@builder.io/qwik/optimizer子路径导出。Qwik 的组件语法(component$、onClick$等)需要编译期转换,这个 Vite 插件内部集成了 Qwik 编译器,负责在 dev 和 build 阶段对 Qwik 源码做转换与优化。csr: true:显式声明使用纯客户端渲染模式。这是该模板与 Qwik 默认(SSR)工作流的关键区别——插件不需要为 Node 服务端配置entry-server,构建产物是可直接部署到任意静态托管环境的 HTML + JS + CSS。- 配置没有设置
base、build.outDir等字段,因此全部采用 Vite 默认值(/、dist目录),这也是构建产物落到dist文件夹的原因(见下文npm run build说明)。
TypeScript 变体模板(template-qwik-ts/vite.config.ts)配置完全一致,唯一差异在类型配置:其 tsconfig.app.json 中设置了 "jsxImportSource": "@builder.io/qwik",使 JSX 转换指向 Qwik 自己的 React 兼容运行时而非 React。
模板目录结构与关键文件
以 JavaScript 变体(template-qwik)为例,模板文件构成如下:
template-qwik/
├── index.html # 入口 HTML,挂载点 + 模块脚本
├── vite.config.js # qwikVite({ csr: true }) 插件配置
├── package.json # dev / build / preview 脚本
├── public/ # favicon.svg、icons.svg 等静态资源
└── src/
├── main.jsx # 渲染入口:引入 qwikloader 并挂载 <App />
├── app.jsx # 根组件:component$ + useSignal 计数器示例
├── app.css # 组件样式(含 HMR 演示文案)
├── index.css # 全局样式、明暗主题变量
└── assets/ # hero.png、qwik.svg、vite.svg 图片资源
入口 HTML 与渲染流程
index.html 定义了一个空的挂载点与模块脚本:
<body>
<div id="app"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
src/main.jsx 完成三件事:
import '@builder.io/qwik/qwikloader.js'
import { render } from '@builder.io/qwik'
import './index.css'
import { App } from './app.jsx'
render(document.getElementById('app'), <App />)
- 第一行引入
qwikloader.js。在 CSR 模式下它承担了在浏览器中初始化 Qwik 客户端的核心职责(脚本懒加载、事件恢复等),是 Qwik 应用运行的前置依赖; - 调用
render()将根组件<App />挂载到#app节点,等价于其他框架的"createRoot + 首次渲染"。
根组件:component$ 与信号
src/app.jsx 展示了 Qwik 最基础的两个 API:
import { component$, useSignal } from '@builder.io/qwik'
export const App = component$(() => {
const count = useSignal(0)
return (
<>
{/* ... */}
<button type="button" class="counter" onClick$={() => count.value++}>
Count is {count.value}
</button>
</>
)
})
component$:Qwik 的组件定义方式(注意是工厂函数风格,与普通函数组件不同);useSignal(0):创建响应式信号,组件内读取count.value的地方会随值变化自动更新;onClick$:Qwik 特有的事件绑定语法(以$结尾),这是 Qwik 编译器插件需要介入的典型场景,也是qwikVite插件存在的直接原因。
模板还演示了 Vite 标准的资产处理:app.jsx 中直接 import heroImg from './assets/hero.png'、import qwikLogo from './assets/qwik.svg',由 Vite 在构建时完成资源 URL 改写;app.css 中则使用了 &:hover 这类嵌套语法,依赖 Vite 8 内置的 CSS 嵌套支持。
如何使用这个模板
通过 create-vite 创建项目
运行 npm create vite@latest my-app -- --template qwik(或交互模式中选择 Qwik → JavaScript),即会复制 template-qwik 目录;选择 TypeScript 变体则使用 template-qwik-ts。CLI 帮助信息中列出的模板名为 qwik-ts(别名 qwik),对应 源码中的框架定义。
安装依赖与运行脚本
进入项目目录后,按 package.json 中定义的脚本操作(npm、pnpm、yarn 均可):
npm install # or pnpm install or yarn install
模板提供了三个脚本:
| 脚本 | 命令 | 说明 |
|---|---|---|
npm run dev |
vite |
启动开发服务器,默认在浏览器中访问 http://localhost:5173(Vite 默认端口)。修改 src/app.jsx 保存即可测试 HMR |
npm run build |
vite build |
构建生产产物到 dist 文件夹 |
npm run preview |
serve dist |
使用 serve 静态服务器本地预览构建产物 |
由于是纯 CSR 模式,dist 产物不依赖任何 Node 服务端,可以直接部署到任意静态托管环境(对象存储、CDN、静态站点托管等)。
适用边界与后续路线
结合 README 与模板源码,这个模板的适用边界可以概括为:
- 适合:快速体验 Qwik 组件模型与响应式信号、纯静态页面、对 SEO/首屏渲染要求不高的客户端应用原型。
- 不适合:需要 SSR、预渲染、路由级元框架能力的生产应用——这些是 Qwik 的核心创新点,本模板并未启用(
qwikVite仅配置了csr: true,项目中也不存在entry-server之类的服务端入口文件)。 - 进阶路线:README 建议改用
npm create qwik@latest创建包含 SSR 与 QwikCity 元框架的完整生产级 Qwik 应用;create-vite的交互菜单中同样内置了该入口(QwikCity变体)。
更多 Qwik 用法可以查阅 Qwik 官方文档站点(qwik.dev);本仓库内如需了解 create-vite 的完整行为(模板列表、--template、--immediate 等 CLI 选项),可参考 create-vite 的 CLI 源码 与 其 README。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00