SvelteKit:如何在服务端$lib函数中访问locals
在SvelteKit的$lib中直接访问locals的方案
方法一:利用Node.js AsyncLocalStorage实现请求上下文共享
这种方法能让你在任意服务端运行的$lib代码中直接获取当前请求的locals,且保证请求之间的上下文隔离。
- 创建
$lib/server/locals.ts,封装AsyncLocalStorage:
// $lib/server/locals.ts import { AsyncLocalStorage } from 'node:async_hooks'; // 可根据你的实际类型定义替换,比如从app.d.ts中导入 import type { Locals } from '$lib/types'; export const localsStorage = new AsyncLocalStorage<Locals>(); export function getLocals() { const locals = localsStorage.getStore(); if (!locals) { throw new Error('只能在服务端请求上下文中调用此方法'); } return locals; }
- 修改
hooks.server.ts,用localsStorage包裹请求处理:
// hooks.server.ts import type { Handle } from '@sveltejs/kit'; import { localsStorage } from '$lib/server/locals'; export const handle: Handle = async ({ event, resolve }) => { event.locals.user = { name: 'Bob the Cat' }; // 将当前请求的locals注入上下文 return await localsStorage.run(event.locals, async () => { return resolve(event); }); };
- 在$lib任意服务端代码中调用:
// $lib/server/your-deep-function.ts import { getLocals } from '$lib/server/locals'; export async function processUser() { const locals = getLocals(); console.log('当前用户:', locals.user); // 输出 { name: 'Bob the Cat' } }
方法二:服务端Store注入(适合依赖load流程的场景)
如果你的$lib代码依赖页面load流程,可以通过服务端Store传递locals:
- 创建服务端专属Store:
// $lib/server/stores.ts import { writable } from 'svelte/store'; import type { Locals } from '$lib/types'; export const serverLocals = writable<Locals | null>(null);
- 在根布局的服务端load中初始化Store:
// src/routes/+layout.server.ts import type { LayoutServerLoad } from './$types'; import { serverLocals } from '$lib/server/stores'; export const load: LayoutServerLoad = async ({ locals }) => { serverLocals.set(locals); return {}; };
- 在$lib中访问Store:
// $lib/server/another-deep-function.ts import { serverLocals } from '$lib/server/stores'; export function getCurrentUser() { let locals; // 立即订阅获取当前值 serverLocals.subscribe(value => { locals = value; })(); if (!locals) { throw new Error('请确保在服务端load完成后调用此方法'); } return locals.user; }
注意事项
- 两种方法均仅适用于服务端运行的$lib代码(比如放在
$lib/server目录下,或通过import { server } from '$app/environment'判断环境后调用)。 - 优先推荐方法一,AsyncLocalStorage是Node.js原生的请求上下文管理方案,能避免并发请求间的上下文污染问题。
内容的提问来源于stack exchange,提问作者Ben Quan
相关产品推荐
相关产品推荐

