如何修复 sapper/svelte 中的 localStorage 错误

2024-01-26

import { writable } from 'svelte/store';

/** Read the current token from LocalStorage on boot */
const token = writable(localStorage.getItem('token'));
/** Store the token in LocalStorage whenever it´s updated */
token.subscribe((val) => {
  if (!localStorage) return;

  if (!val) {
    return localStorage.removeItem('token');
  }

  localStorage.setItem('token', val);
});

export default token;

当我运行时,我仍然收到 localStorage 在 sapper 中未定义的错误npm run dev


在 Sapper 中,您的代码将在浏览器和 SSR 的 Node 中运行。真正的Node,甚至不是像jsdom之类的模拟浏览器环境。 (不一定是“将”,事实上,它是“可能”,因为只有浏览器请求的第一个页面才会在服务器端呈现,但您仍然需要确保所有代码都支持这两种页面)。

在 Node 中,有很多浏览器 API,比如localStorage,不可用。

在 JS 中,你不能像这样测试变量是否存在:

if (!localStorage) ...

如果该变量不存在,您将会遇到崩溃。测试变量是否存在的安全方法如下:

if (typeof localStorage === 'undefined') ...

因此,通过重写您的商店,使您的代码与浏览器 + Node 兼容,如下所示:

const createBrowserTokenStore = () => {
  const store = writable(localStorage.getItem('token'))
  
  // Store the token in LocalStorage whenever it´s updated
  store.subscribe((val) => {
    if (!localStorage) return
    if (!val) return localStorage.removeItem('token')
    localStorage.setItem('token', val)
  })

  return store
}

// just enough to not crash in Node
const createNodeTokenStore = () => writable(null)

export const token = typeof localStorage === 'undefined'
  ? createNodeTokenStore()
  : createBrowserTokenStore()

请注意,即使在 SSR 上下文(即 Node)中,浏览器代码也会运行。页面 SSR 时的准确操作顺序如下:

  • 页面 HTML 在 Node 中呈现,并使用编译的组件ssr: true编译选项——即,仅在一次传递中渲染 HTML 字符串的组件

  • HTML 被发送到浏览器

  • 浏览器显示您的页面,因为它应该是这样的

  • 在后台加载并执行JS

  • 您的 Svelte 组件将重新运行hydratable选项,这意味着他们将尝试回收现有的 DOM 元素,而不是无条件地创建它们

  • 您的页面现在是交互式的,但在获取 HTML 和加载 JS 之间的短暂(或不那么短)间隔内它已经很好看

我想要的地方是,即使页面是由 SSR 渲染的,您的 JS 也将在浏览器中运行,并且结果将replaceSSR通证产生了什么。如果客户端 JS 组件生成与服务器完全不同的 DOM 元素,则 Svelte 将进行覆盖。

这意味着,在这种情况下,只需提供最小值以使代码不会在 Node 中崩溃就可以接受。如果您可以生成接近浏览器渲染结果的结果,那当然更好。 (另一种选择是调整代码,以便服务器在仅浏览器的情况下呈现类似“正在加载...”的内容)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何修复 sapper/svelte 中的 localStorage 错误 的相关文章

随机推荐

  • 选择计数 = 1 的位置

    Table LESSON有字段LessonDate MemberId 除其他外 但只有这两个是相关的 英语 给我一份只上过一门课的学生上这门课的日期列表 我已经尝试了很多事情 这是我的最新尝试 SELECT LessonDate FROM
  • 如何在 Azure 搜索 REST API 上使用“id”删除特定文档?

    我想知道如何删除Azure搜索索引中的特定文档 我想通过 REST API 使用 id 来删除文档 我曾寻找过 但找不到路 odata context https xxxx metadata docs value search score
  • 为什么 rake asset:precompile 在开发中会出现问题,但在我的生产环境中不会出现问题

    我已将 heroku 上的应用程序升级为 cedar stack 以便资产管道正常工作 我已按照中给出的说明进行操作Heroku 的文档 https devcenter heroku com articles rails3x asset p
  • git clone 后跟状态显示未跟踪的文件

    抱歉 我是 git 新手 尽管我非常熟悉旧的源代码控制系统 如 cvs 和 svn 我的最终目标是通过在本地克隆远程存储库 将文件添加到本地存储库 提交更改 然后将本地存储库推回远程 将文件添加到远程存储库 不在我的计算机上 我试过这个 g
  • 访问 WCF UsernamePasswordValidator 中的当前 InstanceContext

    我有一个使用自定义 UsernamePasswordValidator 的 WCF 服务 验证器需要访问我的实体框架上下文 我想为整个服务调用创建一个 ObjectContext 然后在调用结束时销毁 处置它 因此 我创建了一个提供此功能的
  • 从 C# 的 zip 文件中读取二进制文件而不解压它

    我想从 zip 文件中读取二进制文件而不解压缩它 zip 文件结构 zipFolderName subFolder BinFile 在 BinFile 中 我有 Id1 id2 value1 id1 id2 are string value
  • 从子列表中检索升序整数的所有可能组合

    我有包含子列表的列表 我想从这些列表中检索按升序排列的所有整数组合 子列表的顺序也很重要 请参阅预期输出 当函数也返回整数本身时 这并不是一件坏事 请参阅预期输出中的可选子列表 另外 当子列表具有多个值时 我也想将这些值视为单独的组合 这些
  • 在 Linux 上使用 boost::serialization 序列化 unique_ptr 的 std::vector 失败

    我在使用 std unique ptr 的 std vector 的 boost 序列化时遇到问题 unique ptr 的类型并不重要 在下面的示例中 使用整数 include
  • !!处理请求时出现意外错误:无法分配内存

    请帮助我解决这个错误 使用 ruby 脚本将记录从文本文件加载到数据库时出现此错误 如果我使用少量记录加载到数据库中 它就可以正常工作 但如果有大量记录 则失败 CSV foreach fileName do line completePa
  • Microsoft Graph API:访问控制允许来源

    我正在尝试集成 Microsoft Graph 身份验证和访问共享点以及用户的图形配置文件和图片 我遵循了他们的文件https developer microsoft com en us graph docs authorization a
  • Qt3D默认制服和属性

    我开始学习通过 QML 使用着色器 但找不到任何讨论传递给着色器的默认统一和属性值的参考资料 在某些示例中 我们可以看到其中的几个 例如顶点位置 or 模型视图投影 这也被传递为mvp 但是没有包含我们可以使用的所有变量的清晰列表 在调查
  • 跨区域小数/双精度解析

    事实上 我有多个可以生成数字数据的系统 它们以文本文件的形式存储在某些网络服务器上 有些系统使用小数点作为分数分隔符 有些系统也使用小数点逗号 应用程序 胖客户端 net 2 0 也可以在任一类型的系统上运行 因此 经过一番绊倒后 我这样做
  • Count 总是返回 1...但是它存在吗?

    我试图在创建文件名之前检查特定类别的 评论 列中是否已存在文件名 如果它已经存在 我想将今天的日期添加到名称中以使其成为唯一的文件名 我似乎无法使用计数来查找它是否存在 当我 echo checkfile 时 无论文件存在与否 它总是返回
  • 三角矩阵系数索引号的算法

    我认为这一定很简单 但我无法正确理解 我有一个 MxM 三角矩阵 其系数逐行存储在向量中 例如 M m00 m01 m02 m03 m11 m12 m13 m22 m23 m33 存储为 coef m00 m01 m02 m03 m11 m
  • 为什么 Mathematica 会打破模块中正常的作用域规则?

    正如最近的一篇文章中指出的post https stackoverflow com questions 2733239 lexical and dynamic scoping in mathematica local variables w
  • 在 Angular 4 模板中显示地图内容

    我正在尝试在我的模板中显示地图 myMap Map
  • Azure 上的静态类和多个实例

    我正在构建一个将部署在 Azure 上的应用程序 如果我使用静态类 所有实例是否都可以访问相同的静态对象 或者每个实例在生成每个实例时都会实例化自己的静态对象 static每个 AppDomain 字段都有一个值 它们显然不会在计算机之间共
  • 如何在 spmd 块中索引共分布式数组

    我正在做一个非常大的计算 大气吸收 其中有很多单独的窄峰 最后全部加起来 对于每个峰 我预先计算了峰形函数值高于我选择的阈值的范围 然后我逐行将峰添加到我的光谱中 下面给出了一个最小示例 X 1 1e7 K numel a count th
  • Javascript对函数数组执行“reduce”如何实现函数组合?

    我在中遇到了这种模式redux compose功能 我仍然不明白在下面的示例中如何从最后一个而不是从第一个开始评估函数 function f2 a return a a function f3 a return a a a function
  • 如何修复 sapper/svelte 中的 localStorage 错误

    import writable from svelte store Read the current token from LocalStorage on boot const token writable localStorage get