Svelte / Sapper.js - Как инициализировать хранилище с данными localStorage? - PullRequest
1 голос
/ 17 июня 2019

Я пришел из опыта React, но я переключаюсь на Svelte и Sapper для моего следующего приложения, чтобы бороться с огромным размером пакета, который поставляется с React в эти дни. Однако у меня возникают проблемы при инициализации хранилища Svelte с данными, полученными из localStorage.

Согласно документам Sapper (https://sapper.svelte.dev/docs#Getting_started),) я создал свой проект, запустив npx degit "sveltejs/sapper-template#rollup" my-app из командной строки. Затем я установил зависимости и удалил демонстрационный код в папке src.

Затем я создал два файла: src/routes/index.svelte и src/store/index.js.

Код для обоих:

ЦСИ / магазин / index.js

import {writable} from "svelte/store";

export let userLang;

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

ЦСИ / маршруты / index.svelte

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

<p>Your Preferred Language: {$userLang}</p>

Когда я запускаю приложение и иду по маршруту index, я вижу это:

Ваш предпочтительный язык: нуль

, который затем почти немедленно обновляется и изменяется на

Ваш предпочтительный язык: en

когда в localStorage нет элемента lang, и изменяется на

Ваш предпочитаемый язык: fr

после явной установки localStorage.setItem("lang", "fr") из консоли разработчика и обновления.

Я знаю, что хранилище сначала инициализируется на сервере, где window равно undefined, а затем повторно обрабатывается на клиенте. Так что это поведение ожидается.

Итак, мой вопрос: как я могу полностью пропустить инициализацию сервера? Можно ли настроить хранилище только на клиенте (где определено localStorage), чтобы выбранный пользователем язык был сразу доступен?

Я не могу по умолчанию иметь все на английском или любом другом языке после того, как пользователь решил изменить предпочитаемый язык. Я также не могу получить пользовательский язык из браузера через navigator.language при начальной загрузке страницы, так как navigator равно undefined на сервере.

И появление вспышки пустого текста до того, как магазин перепродает, может испортить UX для моего приложения, особенно когда значение userLang будет использоваться повсеместно с переводами.

Так что любые стратегии или хаки для этого определенно приветствуются.

**** Более глубокий выпуск ****

Я бы на самом деле предпочел бы , а не вообще иметь рендеринг на стороне сервера для этого приложения, но мне нужны все другие замечательные функции, которые предоставляет Sapper, такие как маршрутизация, предварительная выборка и статическое построение сайтов.

Итак, я попытался запустить npx sapper export в соответствии с документами , чтобы создать полностью статический сайт, пытаясь удалить сервер из уравнения, но точно такая же проблема все еще возникает, даже если нет сервер используется вообще.

У кого-нибудь есть советы, как настроить Sapper и отключить SSR, но сохранить другие функции?

Спасибо!

**** Обновление ****

Согласно ответу Рича Харриса, обертка разметки с {#if process.browser} делает трюк просто отлично. Итак, я обновил файл src/routes/index.svelte примерно так:

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

{#if process.browser}
    <p>Your Preferred Language: {$userLang}</p>
{/if}

и переменная userLang немедленно устанавливается со значением от localStorage или по умолчанию en, как я и предполагал для этой простой демонстрации. Вспышки null больше нет, поэтому она ведет себя так, как будто на стороне клиента только в этот момент.

Я буду работать над реализацией своего проекта и посмотрю, не возникнет ли еще каких-либо проблем, с которыми я столкнусь. До тех пор, я думаю, что это решает мою проблему.

1 Ответ

2 голосов
/ 18 июня 2019

В настоящее время SSR не является обязательным. Есть проблема, открытая для режима SPA - https://github.com/sveltejs/sapper/issues/383 - которая будет вести себя так, как вы описываете, нам просто нужно обойти ее.

Мы также планируем иметь встроенную поддержку i18n в следующем выпуске: https://github.com/sveltejs/sapper/issues/576

В то же время вы можете подделать его, обернув всю свою разметку в {#if process.browser} - все, что внутри, не будет отображаться на сервере, но будет присутствовать, как только включится JavaScript.

...