Svelte / Sapper.js-如何使用localStorage数据初始化存储?

ano*_*one 5 javascript state server-side-rendering svelte sapper

我来自React的背景,但是我要切换到Svelte和Sapper来开发我的下一个应用程序,以应对这些天React随附的庞大捆绑包规模。但是,我无法使用从localStorage检索的数据初始化Svelte的存储。

根据Sapper文档(https://sapper.svelte.dev/docs#Getting_started),我是通过npx degit "sveltejs/sapper-template#rollup" my-app从命令行运行来创建项目的。然后,我安装了依赖项,并删除了src文件夹中的演示代码。

然后,我创建了两个文件:src/routes/index.sveltesrc/store/index.js

两者的代码:

src / store / index.js

import {writable} from "svelte/store";

export let userLang;

if(typeof window !== "undefined") {
    userLang = writable(localStorage.getItem("lang") || "en");
} else {
    userLang = writable(null);
}
Run Code Online (Sandbox Code Playgroud)

src / routes / index.svelte

<script>
    import {userLang} from "../store";
</script>

<p>Your Preferred Language: {$userLang}</p>
Run Code Online (Sandbox Code Playgroud)

当我运行应用程序并点击index路由时,我看到以下内容:

您的首选语言:null

然后几乎立即更新并更改为

您的首选语言:zh

langlocalStorage中没有项目时,更改为

您的首选语言:fr

localStorage.setItem("lang", "fr")开发者控制台中明确设置并刷新之后。

我知道,这家店是在服务器上初始化第一地方windowundefined,然后在客户端上复水。因此,此行为是预期的。

所以我的问题是:如何完全跳过服务器初始化?是否可以只在客户端(localStorage定义位置)上设置商店,以便用户选择的语言立即可用?

用户选择更改其首选语言后,我不能默认使用英语或其他任何语言。我也无法通过navigator.language初始页面加载从浏览器获取用户语言,因为navigatorundefined也在服务器上。

并且在商店重新发布之前出现一小段空文本会破坏我的应用程序的UX,尤其是当翻译的值userLang将在整个地方都使用时。

因此,对此肯定有任何策略或技巧。

**** 更深的问题 ****

我真的宁愿具备服务器端呈现在所有的这个应用程序,但我确实需要的所有其他优秀的功能,工兵提供,如路由,预取和静态网站建设。

因此,我尝试npx sapper export按照文档运行以生成一个完全静态的站点,以尝试从公式中删除服务器,但是即使根本没有使用服务器,也仍然会出现完全相同的问题。

是否有人对如何配置Sapper和关闭SSR但保留其他功能有任何建议?

谢谢!

**** 更新 ****

根据Rich Harris的回答,使用标记包装标记{#if process.browser}就可以了。所以我src/routes/index.svelte像这样更新了文件:

<script>
    import {userLang} from "../store";
</script>

{#if process.browser}
    <p>Your Preferred Language: {$userLang}</p>
{/if}
Run Code Online (Sandbox Code Playgroud)

userLang立即按照我在此简单演示中的预期将变量设置为localStorage或默认en为。不再有Flash的出现null,因此从本质上来说,它的行为仅是在客户端。

我将继续充实我的项目,看看是否还有其他问题。直到那时,我认为这解决了我的问题。

Ric*_*ris 18

目前,SSR 是非可选的。有一个针对 SPA 模式的问题 - https://github.com/sveltejs/sapper/issues/383 - 会像你描述的那样表现,我们只需要解决它。

我们还计划在未来版本中内置对 i18n 的支持:https : //github.com/sveltejs/sapper/issues/576

与此同时,你可以通过包装你所有的标记来伪造它{#if process.browser}——里面的任何东西都不会被服务器渲染,但是一旦 JavaScript 启动就会出现。