附录
常见问题
在 GitHub 上编辑此页面其他资源永久链接
请参阅 Svelte FAQ 和 vite-plugin-svelte
FAQ,以获取有关这些库中衍生问题的答案。
我可以用 SvelteKit 制作什么?永久链接
SvelteKit 可用于创建大多数类型的应用程序。开箱即用,SvelteKit 支持许多功能,包括
- 使用 load 函数和 API 路由 的动态页面内容。
- 使用 服务器端渲染 (SSR) 的对 SEO 友好的动态内容。
- 使用 SSR 和 表单操作 的用户友好的渐进增强交互式页面。
- 使用 预渲染 的静态页面。
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-hmr
的 preserveLocalState
标志。此标志现在默认关闭,因为它可能导致意外行为和极端情况。但别担心,您仍然可以使用 SvelteKit 获得 HMR!如果您想保留本地状态,可以使用 svelte-hmr 页面上记录的 @hmr:keep
或 @hmr:keep-all
指令。
如何将 package.json 中的详细信息包含在我的应用程序中?永久链接
您无法直接要求 JSON 文件,因为 SvelteKit 希望 svelte.config.js
是一个 ES 模块。如果您想在应用程序中包含应用程序的版本号或来自 package.json
的其他信息,则可以像这样加载 JSON
ts
import {readFileSync } from 'node:fs';import {fileURLToPath } from 'node:url';constpath =fileURLToPath (newURL ('package.json', import.meta.url ));constpkg =JSON .parse (readFileSync (path , 'utf8'));
如何修复我在尝试包含包时遇到的错误?永久链接
与包含库相关的大多数问题都是由于打包不正确造成的。你可以通过在publint 网站中输入库来检查库的打包是否与 Node.js 兼容。
在检查库是否打包正确时,需要记住以下几点
exports
优先于其他入口点字段,例如main
和module
。添加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 问题跟踪器和相关库的跟踪器。有时可以通过修改optimizeDeps
或ssr
配置值来解决问题,尽管我们建议仅将其作为短期解决方法,以修复相关库。
如何在 SvelteKit 中使用视图过渡 API?永久链接
虽然 SvelteKit 并未与 视图过渡 进行任何特定集成,但你可以在 onNavigate
中调用 document.startViewTransition
以在每次客户端导航时触发视图过渡。
ts
import {onNavigate } from '$app/navigation';Property 'startViewTransition' does not exist on type 'Document'.2339Property 'startViewTransition' does not exist on type 'Document'.onNavigate ((navigation ) => {if (!document .startViewTransition ) return;return newPromise ((resolve ) => {document .startViewTransition (async () => {resolve ();awaitnavigation .complete ;});});});
更多信息,请参阅 Svelte 博客上的 "解锁视图过渡"。
如何在 SvelteKit 中使用 X?永久链接
确保你已阅读 关于集成的文档部分。如果你仍然遇到问题,下面列出了常见问题的解决方案。
如何设置数据库?永久链接
将查询数据库的代码放入 服务器路由 中 - 不要在 .svelte 文件中查询数据库。你可以创建一个 db.js
或类似的文件,立即建立连接,并将客户端作为单例在整个应用中访问。你可以在 hooks.server.js
中执行任何一次性设置代码,并将你的数据库助手导入到需要它们的任何端点中。
如何使用仅限客户端的依赖于文档或窗口的库?永久链接
如果你需要访问 document
或 window
变量,或者需要仅在客户端运行代码,则可以将其包装在 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}
块
<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}
<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 路由
ts
/** @type {import('./$types').RequestHandler} */export functionGET ({params ,url }) {returnfetch (`https://my-api-server.com/${params .path +url .search }`);}
ts
import type {RequestHandler } from './$types';export constGET :RequestHandler = ({params ,url }) => {returnfetch (`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} */constmyPlugin = {name : 'log-request-middleware',configureServer (server ) {server .middlewares .use ((req ,res ,next ) => {console .log (`Got request ${req .url }`);next ();});}};/** @type {import('vite').UserConfig} */constconfig = {plugins : [myPlugin ,sveltekit ()]};export defaultconfig ;
有关更多详细信息,包括如何控制排序,请参阅 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 的最佳选择。