如何在Sapper.js中使离线数据存储有效?

问题描述

我想实现的目标

我想使用Sapper.js构建一个可脱机工作但还具有服务器端渲染功能的Web应用程序。为此,我需要两种数据存储实现:一种在浏览器中工作,另一种在服务器上工作。

我怎么想这会起作用

我认为在client.jsserver.js中,我可能可以导入商店的相应实现,然后将其作为道具传递给我的页面组件,类似于:

// server.js
// [some more imports here]
import DataStore from "./my/backend/datastore"

polka()
    .use(
        sapper.middleware({
            pageProps: {DataStore}
        })
    )
    .listen(PORT,err => {/* other stuff */});
// client.js
import * as sapper from '@sapper/app';
import DataStore from "./my/frontend/datastore"

sapper.start({
    target: document.querySelector('#sapper'),pageProps: {DataStore}
})
<!-- page.svelte -->
<script>
    export let DataStore;
    let item;

    if (!item) {
        DataStore.getItem().then(i => item = i);
    }
</script>

<p>{item}</p>

但是,似乎没有办法将道具从两个入口点传递到页面中。
尽管使用全局变量而不是props,但https://stackoverflow.com/a/49085459/9236140上问题#3的答案也允许做同样的事情。但是,由于我还没有设法从组件内部访问windowglobal,所以它似乎不再起作用。

我(很高兴)如何工作

// routes/server/route/exposing/get_item.js
import DataStore from "./my/backend/datastore"

export async function get(req,res,next) {
    res.end(await DataStore.getItem());
}
<!-- page.svelte -->
<script context="module">
    export async function preload(page,session) {
        const response = await this.fetch(`/server/route/exposing/get_item`);
        return {
            item: await response.text()
        }
    }
</script>

<script>
    import {onMount} from 'svelte';

    export let item;
    
    let DataStore;

    onMount(async () => {
        // Dynamically import DataStore so I can use it later,e.g. in on click handlers.
        const module = await import("./my/frontend/datastore");
        DataStore = module.default;
    }
</script>

<p>{item}</p>

为什么该解决方案不能令人满意

  1. 考虑到svelte是编译器,这是很多样板,应该避免。
  2. 每次浏览页面时都会调用preload中的page.svelte函数
    但是在前端,我希望发生这种情况,因为我想先检查本地脱机存储中的数据。

我的问题

  1. 是否有一种方法可以避免这些问题中的一个或两个?
    (也许参与开发的人可以回答其他两个问题:)
  2. 不让道具从两个入口点文件传递到页面的背后是什么原因?
  3. 里奇·哈里斯(Rich Harris)最近宣布即将取代Sapper换人吗?

非常感谢您的阅读。所有指针表示赞赏。 :)

//编辑:

摆弄一些东西之后,我发现了一种方法,可以在preload函数中区分服务器和客户端,并至少在前端上导航时防止AJAX调用,但是它感觉很hacky,并增加了一些样板:

// server.js
// [imports here]

polka()
    .use(
        sapper.middleware({
            session: (req,res) => ({environment: "server"})
        })
    )
    .listen(PORT,err => {/* other stuff */});
<!-- page.svelte -->
<script context="module">
    export async function preload(page,session) {
        if (session.environment === "server") {
            session.environment = "client"

            const response = await this.fetch(`/server/route/exposing/get_item`);
            return {
                item: await response.text()
            }
        } else {
            const module = await import("./my/frontend/datastore");
            return {
                item: await module.default.getItem()
            };
        }
    }
</script>

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...