首页
/ Vite 官方 Qwik + TypeScript 启动模板(CSR 模式)深度解析

Vite 官方 Qwik + TypeScript 启动模板(CSR 模式)深度解析

2026-09-04 23:56:58作者:韦蓉瑛

本文围绕 Vite 官方 create-vite 脚手架内置的 template-qwik-ts(Qwik + TypeScript)启动模板展开。该模板展示了如何用 Vite 驱动一个纯 CSR(Client-Side Rendering)模式的 Qwik 应用:从 qwikVite({ csr: true }) 插件配置、create-vite 中的模板注册逻辑,到入口引导链(qwikloader.jsrender)、Qwik 信号与事件指令(useSignalonClick$),以及模板的 TypeScript 工程配置。读完本文,你将理解该模板每个文件的职责、各 npm 脚本的构建行为,以及 CSR 模式与 Qwik 全栈 SSR/QwikCity 方案的适用边界。

模板定位:它是 create-vite 中的哪个脚手架

template-qwik-ts 位于仓库的 packages/create-vite/template-qwik-ts/ 目录,是 create-vite(即 npm create vite@latest)可选模板之一。在脚手架入口 packages/create-vite/src/index.ts 中,Qwik 以 name: 'qwik' 的形式注册了一组变体:

  • qwik-ts:TypeScript 版,即本文分析的这个模板;
  • qwik:JavaScript 版(对应 template-qwik 目录);
  • custom-qwik-city(显示为 "QwikCity ↗"):不走本地模板,而是直接执行 npm create qwik@latest empty TARGET_DIR,引导用户使用 Qwik 官方的服务端元框架 QwikCity 创建完整的生产级应用。

因此,通过 CLI 创建该模板项目的标准方式是:

npm create vite@latest my-qwik-app -- --template qwik-ts
cd my-qwik-app
npm install # 或使用 pnpm / yarn

模板自身的 README 也明确提示:如果目标是"完整、生产就绪、使用 SSR 和 QwikCity 的 Qwik 应用",应使用 npm create qwik@latest,而不是本模板。本模板的定位是纯 CSR 的快速起步——应用完全在浏览器中引导(bootstrap),不依赖服务端渲染。README 中同时指出:Qwik 的许多核心创新(如 resumability 等)通常是在 SSR 模式下发挥作用的,CSR 模式属于 Qwik 运行形态中的一个子集。

构建配置:qwikVite 插件与 CSR 开关

模板的 Vite 配置极其精简,见 vite.config.ts

import { qwikVite } from '@builder.io/qwik/optimizer'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    qwikVite({
      csr: true,
    }),
  ],
})

要点说明:

  1. 插件来源qwikVite@builder.io/qwik/optimizer 子路径导出,而非主包。这与 Qwik 包的组织方式有关——其 Vite 集成(负责 JSX/TSX 转换、component$ 编译、事件指令处理等)被拆分在 optimizer 子包中。
  2. csr: true:这是本模板与 Qwik SSR 项目的关键配置差异。该选项告知插件以纯客户端渲染方式处理构建产物:不需要为 Node.js 环境生成服务端 bundle,也就不需要额外的 SSR 入口文件与打包步骤。从模板文件结构看,整个 src/ 下只有 main.tsxapp.tsx 与若干静态资源,没有任何 server entry,印证了 CSR 单入口的形态。
  3. 除此之外没有配置任何 alias、resolve 或自定义 build 选项——Qwik 模板把复杂度都收敛到了插件内部,用户侧的 Vite 配置保持最小化。

依赖与 npm 脚本

package.json 定义了三个脚本和一组最小依赖:

{
  "name": "vite-qwik",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "preview": "serve dist"
  },
  "devDependencies": {
    "@types/node": "^24.13.3",
    "serve": "^14.2.6",
    "typescript": "~6.0.2",
    "vite": "^8.2.2"
  },
  "dependencies": {
    "@builder.io/qwik": "^1.20.0"
  }
}

README 中的 "Available Scripts" 一节,各脚本行为如下:

  • npm run dev:启动 Vite 开发服务器,默认在 http://localhost:5173 访问。开发模式下享受原生 ESM 快速冷启动与 HMR(README 中提示修改 src/app.tsx 保存即可验证 HMR 生效)。
  • npm run build:执行 tsc -b && vite build,即先用 TypeScript 项目引用模式做类型检查(见下文 tsconfig 一节),再调用 vite build 产出生产构建到 dist 目录。注意这里 tsc -b 只校验不输出(各子 tsconfig 均为 noEmit: true),产物完全由 Vite 生成。
  • npm run preview:使用 serve dist 静态托管构建产物,用于本地验证生产构建效果。serve 因此被放在 devDependencies 中。

依赖层面,运行时依赖仅有 @builder.io/qwik(^1.20.0);开发期依赖包括 Vite 8.x、TypeScript 6.x 及 @types/nodeserve,整体保持"框架只有一个包"的轻量结构。

入口引导链:index.html → main.tsx → qwikloader.js

CSR 应用的启动流程可以从三个文件串起来:

1. index.html —— 标准 Vite HTML 入口,<body> 内只有一处挂载点和一个模块脚本:

<div id="app"></div>
<script type="module" src="/src/main.tsx"></script>

<head> 中引用了 public/ 下的 favicon.svg 作为站点图标。

2. src/main.tsx —— 客户端引导入口:

import '@builder.io/qwik/qwikloader.js'

import { render } from '@builder.io/qwik'
import './index.css'
import { App } from './app.tsx'

render(document.getElementById('app') as HTMLElement, <App />)

两行关键导入体现了 Qwik 的启动约定:

  • @builder.io/qwik/qwikloader.js:Qwik 的运行时加载器,负责在运行时管理组件代码的懒加载(resumability 相关机制依赖它在浏览器侧的工作)。CSR 模式下它同样会被引入,保证与 SSR 产物的运行时行为一致;
  • render(element, <App />):Qwik 提供的客户端渲染 API,将根组件挂载到 index.htmlid="app" 的占位 DOM 上。

3. src/app.tsx —— 根组件,也是模板附带的示例代码,集中演示了 Qwik 的三个核心 API:

export const App = component$(() => {
  const count = useSignal(0)
  // ...
  <button type="button" class="counter" onClick$={() => count.value++}>
    Count is {count.value}
  </button>
})
  • component$:Qwik 的组件声明函数(注意 $ 后缀是 Qwik 组件/函数命名惯例的一部分);
  • useSignal(0):响应式信号,count.value 的变化会驱动 DOM 更新;
  • onClick$:Qwik 的事件指令。它以 JSX 属性形式声明事件处理,事件函数在首次序列化后以"可恢复(resumable)"的形态保存在标记化输出中,点击时才需要求值——这正是 README 中所说"多数创新在 SSR 下更充分"的机制在 CSR 场景中的降级表现:CSR 下组件在浏览器内挂载,事件绑定同样可用,但序列化-恢复链路不会跨越服务端。

组件中还通过 import heroImg from './assets/hero.png' 等方式引入了 assets 下的图片hero.pngqwik.svgvite.svg),由 Vite 的静态资源管线处理;index.cssapp.css 分别承载全局样式与组件区块样式。页面中的 SVG 图标通过 public/ 下的 icons.svg<use href="/icons.svg#documentation-icon"> 形式引用,走 Vite 的静态资源直出。

TypeScript 工程配置:双引用结构

模板沿用 Vite 生态通用的"项目引用"式 TS 组织,tsconfig.json 本身不编译任何文件,仅声明两个引用:

{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ]
}
  • tsconfig.app.json:覆盖 src/moduleResolution: "bundler"verbatimModuleSyntaxjsx: "react-jsx"。其中最值得注意的是:

    "jsxImportSource": "@builder.io/qwik"
    

    Qwik 的 JSX 运行时(jsx / jsxs / Fragment)来自 Qwik 包自身而非 React,这个配置让 tsc 按 Qwik 的 JSX 类型签名校验模板代码——这是 Qwik 能"借用 React 风格 JSX 语法但拥有独立运行时"的关键接线。

  • tsconfig.node.json:仅包含 vite.config.tsmodule: "nodenext"types: ["node"],为配置文件提供独立的 Node 环境类型。

build 脚本中的 tsc -b 即按这两个引用顺序做增量类型检查(tsBuildInfoFile 指向 node_modules/.tmp/),检查通过后才执行 vite build

适用边界与升级路径

综合模板 README 与 create-vite 源码,可以归纳出该模板的适用边界:

维度 本模板(template-qwik-ts) Qwik 官方脚手架
渲染模式 纯 CSR,浏览器引导 SSR 为主
路由/元框架 无,单页 #app 挂载 QwikCity(文件路由、meta 等)
构建配置 qwikVite({ csr: true }) 单插件 更完整的服务端 + 客户端双端配置
创建命令 npm create vite@latest my-app -- --template qwik-ts npm create qwik@latest

如果你的项目目标只是快速体验 Qwik 的组件/信号/事件指令 API 与 Vite 开发体验(例如学习 useSignalcomponent$onClick$),本模板足够;一旦需要服务端渲染、文件路由或生产级部署形态,应切换到 create-vite 中注册的 QwikCity 入口(对应命令 npm create qwik@latest empty TARGET_DIR)。

关键文件索引

文件 作用
packages/create-vite/template-qwik-ts/README.md 模板说明:CSR 模式、用法与脚本
packages/create-vite/template-qwik-ts/vite.config.ts qwikVite({ csr: true }) 构建配置
packages/create-vite/template-qwik-ts/package.json dev / build / preview 脚本与依赖
packages/create-vite/template-qwik-ts/index.html HTML 入口与 #app 挂载点
packages/create-vite/template-qwik-ts/src/main.tsx qwikloader 引入与 render 引导
packages/create-vite/template-qwik-ts/src/app.tsx 根组件示例:component$ / useSignal / onClick$
packages/create-vite/template-qwik-ts/tsconfig.app.json 应用侧 TS 配置与 Qwik JSX 运行时接线
packages/create-vite/src/index.ts create-vite 中 Qwik 模板变体的注册逻辑
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
980
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384