跳至主要内容

附录

常见问题

在 GitHub 上编辑此页面

其他资源

请参阅 Svelte FAQvite-plugin-svelte FAQ,以获取有关这些库中衍生问题的答案。

我可以用 SvelteKit 制作什么?

SvelteKit 可用于创建大多数类型的应用程序。开箱即用,SvelteKit 支持许多功能,包括

SvelteKit 还可以通过 适配器 部署到广泛的托管架构。在使用 SSR(或在不预渲染的情况下添加服务器端逻辑)的情况下,这些函数将适应目标后端。一些示例包括

  • 使用 Node.js 后端 的自托管动态 Web 应用程序。
  • 将后端加载器和 API 部署为远程函数的无服务器 Web 应用程序。有关流行的部署选项,请参阅 零配置部署
  • 静态预渲染站点,例如托管在 CDN 或静态主机上的博客或多页站点。静态生成的站点在没有后端的情况下交付。
  • 单页应用程序 (SPA) 具有客户端路由和渲染,适用于 API 驱动的动态内容。SPA 在没有后端的情况下交付,并且不是服务器渲染的。当将 SvelteKit 与用 PHP、.Net、Java、C、Golang、Rust 等编写的应用程序捆绑在一起时,通常选择此选项。
  • 上述内容的组合;一些路由可以是静态的,而一些路由可以使用后端函数来获取动态信息。这可以通过 页面选项 进行配置,其中包括选择退出 SSR 的选项。

为了支持 SSR,需要一个 JS 后端——例如基于 Node.js 或 Deno 的服务器、无服务器函数或边缘函数。

还可以编写自定义适配器或利用社区适配器将 SvelteKit 部署到更多平台,例如专用服务器环境、浏览器扩展或原生应用程序。有关更多示例和集成,请参阅 集成

如何将 HMR 与 SvelteKit 一起使用?

SvelteKit 默认启用 HMR,由 svelte-hmr 提供支持。如果您在 2020 年 Svelte 峰会上看到了 Rich 的演讲,您可能已经看到了更强大的 HMR 版本。此演示启用了 svelte-hmrpreserveLocalState 标志。此标志现在默认关闭,因为它可能导致意外行为和极端情况。但别担心,您仍然可以使用 SvelteKit 获得 HMR!如果您想保留本地状态,可以使用 svelte-hmr 页面上记录的 @hmr:keep@hmr:keep-all 指令。

如何将 package.json 中的详细信息包含在我的应用程序中?

您无法直接要求 JSON 文件,因为 SvelteKit 希望 svelte.config.js 是一个 ES 模块。如果您想在应用程序中包含应用程序的版本号或来自 package.json 的其他信息,则可以像这样加载 JSON

svelte.config.js
ts
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
const path = fileURLToPath(new URL('package.json', import.meta.url));
const pkg = JSON.parse(readFileSync(path, 'utf8'));

如何修复我在尝试包含包时遇到的错误?

与包含库相关的大多数问题都是由于打包不正确造成的。你可以通过在publint 网站中输入库来检查库的打包是否与 Node.js 兼容。

在检查库是否打包正确时,需要记住以下几点

  • exports 优先于其他入口点字段,例如 mainmodule。添加 exports 字段可能不向后兼容,因为它阻止了深度导入。
  • ESM 文件应以 .mjs 结尾,除非设置了 "type": "module",在这种情况下,任何 CommonJS 文件都应以 .cjs 结尾。
  • 如果未定义 exports,则应定义 main。它应该是一个 CommonJS 或 ESM 文件,并遵守上一条规则。如果定义了 module 字段,则它应引用 ESM 文件。
  • Svelte 组件应作为未编译的 .svelte 文件分发,其中包中的任何 JS 都只写为 ESM。自定义脚本和样式语言(如 TypeScript 和 SCSS)应分别预处理为香草 JS 和 CSS。我们建议使用svelte-package打包 Svelte 库,它将为你完成此操作。

当库分发 ESM 版本时,它们在使用 Vite 的浏览器中效果最佳,尤其当它们是 Svelte 组件库的依赖项时。你可能希望建议库作者提供 ESM 版本。但是,CommonJS (CJS) 依赖项也应该可以正常工作,因为默认情况下,vite-plugin-svelte 会要求 Vite 使用 esbuild 预先捆绑它们以将它们转换为 ESM。

如果你仍然遇到问题,我们建议同时搜索Vite 问题跟踪器和相关库的跟踪器。有时可以通过修改optimizeDepsssr配置值来解决问题,尽管我们建议仅将其作为短期解决方法,以修复相关库。

如何在 SvelteKit 中使用视图过渡 API?

虽然 SvelteKit 并未与 视图过渡 进行任何特定集成,但你可以在 onNavigate 中调用 document.startViewTransition 以在每次客户端导航时触发视图过渡。

ts
import { onNavigate } from '$app/navigation';
onNavigate((navigation) => {
Property 'startViewTransition' does not exist on type 'Document'.2339Property 'startViewTransition' does not exist on type 'Document'.
if (!document.startViewTransition) return;
return new Promise((resolve) => {
document.startViewTransition(async () => {
resolve();
await navigation.complete;
});
});
});

更多信息,请参阅 Svelte 博客上的 "解锁视图过渡"

如何在 SvelteKit 中使用 X?

确保你已阅读 关于集成的文档部分。如果你仍然遇到问题,下面列出了常见问题的解决方案。

如何设置数据库?

将查询数据库的代码放入 服务器路由 中 - 不要在 .svelte 文件中查询数据库。你可以创建一个 db.js 或类似的文件,立即建立连接,并将客户端作为单例在整个应用中访问。你可以在 hooks.server.js 中执行任何一次性设置代码,并将你的数据库助手导入到需要它们的任何端点中。

如何使用仅限客户端的依赖于文档或窗口的库?

如果你需要访问 documentwindow 变量,或者需要仅在客户端运行代码,则可以将其包装在 browser 检查中

ts
import { browser } from '$app/environment';
if (browser) {
// client-only code here
}

如果你希望在组件首次渲染到 DOM 后运行代码,你也可以在 onMount 中运行代码

ts
import { onMount } from 'svelte';
onMount(async () => {
const { method } = await import('some-browser-only-library');
method('hello world');
});

如果你要使用的库没有副作用,你也可以静态导入它,它将在服务器端构建中被 tree-shaken 掉,其中 onMount 将自动替换为无操作

ts
import { onMount } from 'svelte';
import { method } from 'some-browser-only-library';
onMount(() => {
method('hello world');
});

最后,你也可以考虑使用 {#await}

index.svelte
<script>
	import { browser } from '$app/environment';

	const ComponentConstructor = browser ?
		import('some-browser-only-library').then((module) => module.Component) :
		new Promise(() => {});
</script>

{#await ComponentConstructor}
	<p>Loading...</p>
{:then component}
	<svelte:component this={component} />
{:catch error}
	<p>Something went wrong: {error.message}</p>
{/await}
index.svelte
<script lang="ts">
	import { browser } from '$app/environment';
	
	const ComponentConstructor = browser
		? import('some-browser-only-library').then((module) => module.Component)
		: new Promise(() => {});
</script>

{#await ComponentConstructor}
	<p>Loading...</p>
{:then component}
	<svelte:component this={component} />
{:catch error}
	<p>Something went wrong: {error.message}</p>
{/await}

如何使用不同的后端 API 服务器?

你可以使用 event.fetch 从外部 API 服务器请求数据,但请注意,你需要处理 CORS,这会导致复杂情况,例如通常需要预检请求,从而导致更高的延迟。对单独子域的请求也可能会因额外的 DNS 查找、TLS 设置等而增加延迟。如果你希望使用此方法,你可能会发现 handleFetch 有帮助。

另一种方法是设置代理以绕过 CORS 难题。在生产环境中,你会将类似于 /api 的路径重写到 API 服务器;对于本地开发,使用 Vite 的 server.proxy 选项。

在生产环境中设置重写取决于你的部署平台。如果无法重写,你可以添加 API 路由

src/routes/api/[...path]/+server.js
ts
/** @type {import('./$types').RequestHandler} */
export function GET({ params, url }) {
return fetch(`https://my-api-server.com/${params.path + url.search}`);
}
src/routes/api/[...path]/+server.ts
ts
import type { RequestHandler } from './$types';
export const GET: RequestHandler = ({ params, url }) => {
return fetch(`https://my-api-server.com/${params.path + url.search}`);
};

(请注意,你可能还需要代理 POST/PATCH 等请求,并转发 request.headers,具体取决于你的需求。)

如何使用中间件?

adapter-node 构建了一个中间件,你可以在生产模式下将其与自己的服务器一起使用。在开发模式下,你可以使用 Vite 插件将中间件添加到 Vite。例如

ts
import { sveltekit } from '@sveltejs/kit/vite';
/** @type {import('vite').Plugin} */
const myPlugin = {
name: 'log-request-middleware',
configureServer(server) {
server.middlewares.use((req, res, next) => {
console.log(`Got request ${req.url}`);
next();
});
}
};
/** @type {import('vite').UserConfig} */
const config = {
plugins: [myPlugin, sveltekit()]
};
export default config;

有关更多详细信息,包括如何控制排序,请参阅 Vite 的 configureServer 文档

它是否适用于 Yarn 2?

某种程度上。即插即用功能,又称“pnp”,已损坏(它偏离了 Node 模块解析算法,并且 尚不支持原生 JavaScript 模块,而 SvelteKit — 以及 越来越多的包 — 使用)。你可以在 .yarnrc.yml 文件中使用 nodeLinker: 'node-modules' 来禁用 pnp,但可能更容易使用 npm 或 pnpm,它们的速度和效率类似,但没有兼容性问题。

如何与 Yarn 3 一起使用?

目前,最新 Yarn(版本 3)中的 ESM 支持被认为是 实验性的

以下内容似乎有效,尽管你的结果可能有所不同。

首先创建一个新应用程序

yarn create svelte myapp
cd myapp

并启用 Yarn Berry

yarn set version berry
yarn install

Yarn 3 全局缓存

Yarn Berry 的一个更有趣的功能是能够为包拥有一个单一的全局缓存,而不是为磁盘上的每个项目拥有多个副本。然而,将 enableGlobalCache 设置为 true 会导致构建失败,因此建议将以下内容添加到 .yarnrc.yml 文件中

yaml
nodeLinker: node-modules

这将导致包下载到本地 node_modules 目录中,但避免上述问题,并且是目前使用 Yarn 版本 3 的最佳选择。

上一个 类型
下一个 集成