前言
Svelte,一个语法简洁、入门容易,面向未来的前端框架。
从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1:
Svelte 以其独特的编译时优化机制著称,具有轻量级 、高性能 、易上手 等特性,非常适合构建轻量级 Web 项目。
为了帮助大家学习 Svelte,我同时搭建了 Svelte 最新的中文文档站点。
如果需要进阶学习,也可以入手我的小册《Svelte 开发指南》,语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!
欢迎围观我的"网页版朋友圈"、加入"冴羽·成长陪伴社群",踏上"前端大佬成长之路"。
介绍
开始之前
[!NOTE] 如果您是 Svelte 或 SvelteKit 的新手,我们建议查看交互式教程。
如果遇到问题,可以在 Discord 聊天室寻求帮助。
什么是 SvelteKit?
SvelteKit 是一个使用 Svelte 快速开发稳健、高性能 Web 应用程序的框架。如果您来自 React,SvelteKit 类似于 Next。如果您来自 Vue,SvelteKit 类似于 Nuxt。
要了解更多关于可以用 SvelteKit 构建的应用程序类型,请参阅常见问题。
什么是 Svelte?
简而言之,Svelte 是一种编写用户界面组件的方式 ------ 比如导航栏、评论区或联系表单 ------ 这些组件用户可以在浏览器中看到并与之交互。Svelte 编译器将您的组件转换为可以运行的 JavaScript 来渲染页面的 HTML,以及为页面添加样式 CSS。您不需要了解 Svelte 就能理解本指南的其余部分,但了解它会有所帮助。如果您想了解更多,请查看 Svelte 教程。
SvelteKit 与 Svelte 的区别
Svelte 负责渲染 UI 组件。您可以组合这些组件并仅使用 Svelte 渲染整个页面,但要构建完整的应用程序,您需要的不仅仅是 Svelte。
SvelteKit 帮助您在遵循现代最佳实践的同时构建 Web 应用,并为常见的开发挑战提供解决方案。它提供从基本功能 ------ 比如在点击链接时更新 UI 的路由器 ------ 到更高级的功能。
它的广泛功能列表包括:仅加载最小所需代码的构建优化;离线支持;用户导航前的页面预加载;通过 SSR、浏览器客户端渲染或构建时预渲染来处理应用程序不同部分的可配置渲染;图像优化;等等。使用所有现代最佳实践构建应用程序非常复杂,但 SvelteKit 为您处理了所有繁琐的工作,这样您就可以专注于创造性的部分。
它利用带有 Svelte 插件的 Vite 来实现热模块替换 (HMR),从而在浏览器中即时反映代码更改,提供闪电般快速且功能丰富的开发体验。
创建项目
创建 SvelteKit 应用最简单的方法是运行 npx sv create
:
bash
npx sv create my-app
cd my-app
npm install
npm run dev
第一个命令将在 my-app
目录中搭建一个新项目,并询问您是否要设置一些基本工具,比如 TypeScript。有关设置其他工具的指导,请参见集成。随后的命令将安装其依赖项并在 localhost:5173 上启动服务端。
这里有两个基本概念:
- 应用的每个页面都是一个 Svelte 组件
- 通过在项目的
src/routes
目录中添加文件来创建页面。这些页面将被服务端渲染,以确保用户首次访问您的应用时速度尽可能快,之后客户端应用将接管
尝试编辑文件以了解所有功能是如何工作的。
编辑器设置
我们推荐使用 Visual Studio Code (简称 VS Code) 并安装 Svelte 扩展,但也支持许多其他编辑器。
项目结构
一个典型的 SvelteKit 项目结构如下:
bash
my-project/
├ src/
│ ├ lib/
│ │ ├ server/
│ │ │ └ [您的仅服务端库文件]
│ │ └ [您的库文件]
│ ├ params/
│ │ └ [您的参数匹配器]
│ ├ routes/
│ │ └ [您的路由]
│ ├ app.html
│ ├ error.html
│ ├ hooks.client.js
│ ├ hooks.server.js
│ └ service-worker.js
├ static/
│ └ [您的静态资源]
├ tests/
│ └ [您的测试]
├ package.json
├ svelte.config.js
├ tsconfig.json
└ vite.config.js
您还会发现一些常见文件,如 .gitignore
和 .npmrc
(如果您在运行 npx sv create
时选择了这些选项,还会有 .prettierrc
和 eslint.config.js
等)。
项目文件
src
src
目录包含了项目的主要内容。除了 src/routes
和 src/app.html
之外,其他都是可选的。
lib
包含您的库代码(实用工具和组件),可以通过$lib
别名导入,或使用svelte-package
打包分发server
包含您的仅服务端(server-only)库代码。可以使用$lib/server
别名导入。SvelteKit 会阻止您在客户端代码中导入这些内容。
params
包含应用需要的任何参数匹配器routes
包含应用的路由。您也可以在这里放置仅在单个路由中使用的其他组件app.html
是您的页面模板 --- 一个包含以下占位符的 HTML 文档:%sveltekit.head%
--- 应用需要的<link>
和<script>
元素,以及任何<svelte:head>
内容%sveltekit.body%
--- 渲染页面的标记。这应该放在<div>
或其他元素内,而不是直接放在<body>
内,以防止浏览器插件注入元素后被水合过程销毁而导致的错误。如果不是这样情况,SvelteKit 会在开发时警告您%sveltekit.assets%
--- 如果指定了,则是paths.assets
,否则是到paths.base
的相对路径%sveltekit.nonce%
--- 手动包含的链接和脚本的 CSP nonce(如果使用)%sveltekit.env.[NAME]%
- 这将在渲染时被替换为[NAME]
环境变量,该变量必须以publicPrefix
(通常是PUBLIC_
)开头。如果没有匹配项,将回退到''
error.html
是在所有其他内容都失败时渲染的页面。它可以包含以下占位符:%sveltekit.status%
--- HTTP 状态码%sveltekit.error.message%
--- 错误信息
hooks.client.js
包含您的客户端钩子hooks.server.js
包含您的服务端钩子service-worker.js
包含您的 service worker
(项目是包含 .js
还是 .ts
文件取决于您创建项目时是否选择使用 TypeScript。您可以使用本页底部的切换按钮在文档中的 JavaScript 和 TypeScript 之间切换。)
如果您在设置项目时添加了 Vitest,您的单元测试将位于 src
目录中,带有 .test.js
扩展名。
static
这里放置需要按原样提供的静态资源,如 robots.txt
或 favicon.png
。
tests
如果您在设置项目时添加了 Playwright 进行浏览器测试,测试文件将位于此目录中。
package.json
您的 package.json
文件必须包含 @sveltejs/kit
、svelte
和 vite
作为 devDependencies
。
当您使用 npx sv create
创建项目时,您会注意到 package.json
包含了 "type": "module"
。这意味着 .js
文件将被解释为带有 import
和 export
关键字的原生 JavaScript 模块。遗留的 CommonJS 文件需要一个 .cjs
文件扩展名。
svelte.config.js
此文件包含您的 Svelte 和 SvelteKit 配置。
tsconfig.json
如果您在 npx sv create
期间添加了类型检查,此文件(或者如果您更喜欢对 .js
文件而不是 .ts
文件进行类型检查,则为 jsconfig.json
)将配置 TypeScript。由于 SvelteKit 依赖于某些特定方式的配置设置,它会生成自己的 .svelte-kit/tsconfig.json
文件,您的配置将 extends
这个文件。
vite.config.js
SvelteKit 项目实际上就是一个使用 @sveltejs/kit/vite
插件的 Vite 项目,以及其他 Vite 配置。
其他文件
.svelte-kit
在开发和构建项目时,SvelteKit 将在 .svelte-kit
目录中生成文件(可通过 outDir
配置)。您可以忽略其内容,并随时删除它们(它们将在下次 dev
或 build
时重新生成)。
Web 标准
在本文档中,您会看到对 SvelteKit 所基于的标准 Web APIs 的引用。我们没有重新发明轮子,而是使用平台,这意味着您现有的 Web 开发技能可以应用到 SvelteKit。反之,花时间学习 SvelteKit 也会帮助您在其他地方成为更好的 Web 开发者。
这些 API 在所有现代浏览器和许多非浏览器环境(如 Cloudflare Workers、Deno 和 Vercel Functions)中都可用。在开发过程中,以及在基于 Node 的环境(包括 AWS Lambda)的适配器中,必要时会通过 polyfills 提供这些 API(目前是这样 --- Node 正在快速增加对更多 Web 标准的支持)。
特别是,您会熟悉以下内容:
Fetch APIs
SvelteKit 使用 fetch
从网络获取数据。它在 hooks 和服务端路由以及浏览器中都可用。
[!NOTE] 在
load
函数、服务端 hooks和 API 路由中提供了一个特殊版本的fetch
,用于在服务端渲染期间直接调用端点,而无需进行 HTTP 调用,同时保留凭证。(要在load
之外的服务端代码中进行带凭证的请求,您必须显式传递cookie
和/或authorization
头部。)它还允许您进行相对地址请求,而服务端的fetch
通常需要一个完整的 URL。
除了 fetch
本身,Fetch API 还包括以下接口:
Request
Request
的实例在 hooks 和服务端路由中可以通过 event.request
访问。它包含有用的方法,如 request.json()
和 request.formData()
,用于获取发送到端点的数据。
Response
Response
的实例由 await fetch(...)
和 +server.js
文件中的处理程序返回。从根本上说,SvelteKit 应用就是一个将 Request
转换为 Response
的机器。
Headers
Headers
接口允许您读取传入的 request.headers
和设置传出的 response.headers
。例如,您可以如下获取 request.headers
,并使用 json
便捷函数 发送修改后的 response.headers
:
js
// @errors: 2461
/// file: src/routes/what-is-my-user-agent/+server.js
import { json } from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */
export function GET({ request }) {
// 记录所有头部
console.log(...request.headers);
// 使用我们收到的头部创建 JSON Response
return json(
{
// 获取特定头部
userAgent: request.headers.get('user-agent')
},
{
// 在响应中设置头部
headers: { 'x-custom-header': 'potato' }
}
);
}
FormData
当处理 HTML 原生表单提交时,您将使用 FormData
对象。
js
// @errors: 2461
/// file: src/routes/hello/+server.js
import { json } from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */
export async function POST(event) {
const body = await event.request.formData();
// 记录所有字段
console.log([...body]);
return json({
// 获取特定字段的值
name: body.get('name') ?? 'world'
});
}
Stream APIs
大多数情况下,您的端点会返回完整的数据,就像上面的 userAgent
示例那样。有时,您可能需要返回一个太大而无法一次性放入内存的响应,或者需要分块传递的响应,为此平台提供了流 --- ReadableStream、WritableStream 和 TransformStream。
URL APIs
URL 由 URL
接口表示,它包含有用的属性如 origin
和 pathname
(在浏览器中还有 hash
)。这个接口出现在各个地方 --- hooks和服务端路由中的 event.url
、页面中的 page.url
、beforeNavigate
和 afterNavigate
中的 from
和 to
等。
URLSearchParams
无论在哪里遇到 URL,您都可以通过 url.searchParams
访问查询参数,它是 URLSearchParams
的实例:
js
// @filename: ambient.d.ts
declare global {
const url: URL;
}
export {};
// @filename: index.js
// ---cut---
const foo = url.searchParams.get('foo');
Web 加密
Web Crypto API 通过 crypto
全局对象提供。它在内部用于内容安全策略头部,但您也可以用它来做一些事情,比如生成 UUID:
js
const uuid = crypto.randomUUID();
Svelte 中文文档
点击查看中文文档 - SvelteKit 入门指南。
系统学习 Svelte,欢迎入手小册《Svelte 开发指南》。语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!
此外我还写过 JavaScript 系列、TypeScript 系列、React 系列、Next.js 系列、冴羽答读者问等 14 个系列文章, 全系列文章目录:github.com/mqyqingfeng...
欢迎围观我的"网页版朋友圈"、加入"冴羽·成长陪伴社群",踏上"前端大佬成长之路"。