>在本文中,您将学习如何构建一个GitHub跟踪器,该跟踪器通过发送推送通知在跟踪存储库上有新的问题/PR时通知用户。
如果您选择使用,添加服务工作者并将跟踪器转换为PWA
> node.js和npm已安装
生成的,但是在接收推动事件
>时会生成它们。当应用程序关闭时,推送通知工作,而常规通知要求您打开应用程序。> 通过使用所谓的服务工人,在现代网络浏览器(例如Chrome)中支持推送通知。服务工作人员是与浏览器主线程分开运行的JavaScript的小部分,因此,如果将您的应用程序安装为PWA(Progressive Web应用程序)。 >推送通知在聊天应用程序中使用以通知用户在游戏中未读消息时通知他们,以通知用户,在新闻网站中通知用户,以通知用户,以通知用户,并出于许多其他目的。 有四个步骤可以在您的应用中显示推送通知: > window.notification.requestpermission()>请求许可
>将您的应用程序转换为PWA并安装订阅推送事件
>
收到推送事件后,发送通知
接下来,CD到项目文件夹中,您可以在应用程序中添加parwindcss,并使用这些命令安装所有依赖项:
<span>npm init vite </span>
最后,在您喜欢的代码编辑器中打开项目,然后运行NPM运行DEV或YARN DEV,以在http:// localhost:3000。
跟踪器将如何工作>第一步是提示用户获取用户名。创建src/lib/usernameprompt.svelte,这将是这样做的组件。这是我的UI,但您可以根据需要进行设计:
>在app.svelte中添加此组件。
npx svelte-add tailwindcss <span># Install packages </span><span>yarn install # or npm install </span>接下来,让我们添加主跟踪器UI。创建文件src/lib/tracker.svelte并在其中添加以下代码:
测试您的组件,
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let username = ""; </span></span></span><span><span> <span>async function submit() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span> </span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Username"</span> </span></span><span> <span>aria-label<span>="Username"</span> </span></span><span> <span><span>bind:value</span><span>="{username}"</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span> </span> Submit <span><span><span></button</span>></span> </span><span><span><span></form</span>></span> </span>暂时将用户名组件换成app.svelte中的新跟踪器组件:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>import <span>UsernamePrompt</span> from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><UsernamePrompt</span> /></span> </span>
您的屏幕现在应该看起来像这样:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let repo = ""; </span></span></span><span><span> <span>function track() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span> </span></span><span><span> <span>function untrack(repo) { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>={track}</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>GitHub tracker<span><span></h1</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Enter the repository's URL"</span> </span></span><span> <span>aria-label<span>="Repository URL"</span> </span></span><span> <span><span>bind:value</span><span>={repo}</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-2 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span>Track repository<span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span><h2</span> class<span>="mt-4 text-2xl"</span>></span>Tracked repositories<span><span></h2</span>></span> </span> <span><span><span><ul</span> class<span>="m-2 list-decimal"</span>></span> </span> <span><!-- We'll use a loop to automatically add repositories here later on. --> </span> <span><span><span><li</span> class<span>="py-1 flex items-center justify-between"</span>></span> </span> <span><span><span><a</span> class<span>="text-gray-500 hover:underline"</span> href<span>="https://github.com/test/test"</span> </span></span><span> <span>></span>https://github.com/test/test<span><span></a</span> </span></span><span> <span>></span> </span> <button on:click={() => untrack("")} >Untrack<span><span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span><span><span><span></form</span>></span> </span>
>
注意:请记住将App.svelte还原到其先前的代码!步骤2:设置云功能
>
要连接到数据库,您需要连接字符串。将新用户和密码保存在某个地方,然后转到群集的概述。单击右侧的连接按钮,然后选择“连接应用程序”作为连接方法。您应该看到一个类似于下面的连接字符串。
>
>现在您拥有连接字符串,可以连接到数据库,但是首先,您需要将当前应用程序部署到Vercel。最简单的方法是使用github。
>创建一个新的github存储库,然后将代码推向它。接下来,前往您的Vercel仪表板,然后单击“新项目”按钮。导入您的github存储库,确保框架是vite的,并添加一个称为mongodb_url的环境变量。将其值设置为MongoDB数据库的连接字符串。
>部署了网站后,您需要将本地开发命令从Yarn Dev更改为Vercel Dev。运行命令后,如果您要求您链接到现有项目,请单击“是”。
>注意:如果还没有,请确保使用NPM I -G Vercel安装Vercel CLI。
像我一样,如果您遇到了与Vercel Dev一起使用Vite的问题,请确保将项目的
这将使我们能够在本地使用正确的环境变量使用云功能。
>导出连接承诺而不是主要客户端本身将阻止我们在无服务器平台上工作。
使用commonjs代替eSmodules 请注意我如何使用需要而不是导入?这是因为,从撰写本文开始,Vercel Cloud Functions
不支持JavaScript文件中的Esmodule导入语句。相反,您需要使用commonjs需要语句。<span>npm init vite </span>
>这里有一个问题。如果您看到了我们应用程序的包装。这意味着项目中的每个JavaScript文件都是Esmodule。这不是我们想要的,因此要将API目录中的所有文件标记为commonjs文件,因此我们可以使用require语句,创建api/package.json。
步骤3:添加功能 到目前为止,跟踪器
并没有真正起作用,所以让我们解决这个问题。身份验证
npx svelte-add tailwindcss <span># Install packages </span><span>yarn install # or npm install </span>>用于身份验证,我们需要存储用户在MongoDB数据库中输入的用户名。
>创建一个file /api /storeusername.js。这将是一个云功能,并将映射到http:// localhost:3000/api/storeusername。将以下代码放在其中:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let username = ""; </span></span></span><span><span> <span>async function submit() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span> </span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Username"</span> </span></span><span> <span>aria-label<span>="Username"</span> </span></span><span> <span><span>bind:value</span><span>="{username}"</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span> </span> Submit <span><span><span></button</span>></span> </span><span><span><span></form</span>></span> </span>
<span>npm init vite </span>
从请求的正文中提取用户名:
npx svelte-add tailwindcss <span># Install packages </span><span>yarn install # or npm install </span>
接下来,您需要将此用户名存储在数据库中:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let username = ""; </span></span></span><span><span> <span>async function submit() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span> </span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Username"</span> </span></span><span> <span>aria-label<span>="Username"</span> </span></span><span> <span><span>bind:value</span><span>="{username}"</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span> </span> Submit <span><span><span></button</span>></span> </span><span><span><span></form</span>></span> </span>>最后,这就是API/storeusername.js文件应看起来:
>将您的应用程序通过Vercel。将您的应用程序部署到Vercel。或推送到GitHub,您的无服务器功能应该是实时的!您可以使用此命令使用卷曲来对其进行测试:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>import <span>UsernamePrompt</span> from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><UsernamePrompt</span> /></span> </span>
这应该在用户集合中创建一个新文档,其中_id字段是我们刚刚给出的用户名。
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let repo = ""; </span></span></span><span><span> <span>function track() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span> </span></span><span><span> <span>function untrack(repo) { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>={track}</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>GitHub tracker<span><span></h1</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Enter the repository's URL"</span> </span></span><span> <span>aria-label<span>="Repository URL"</span> </span></span><span> <span><span>bind:value</span><span>={repo}</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-2 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span>Track repository<span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span><h2</span> class<span>="mt-4 text-2xl"</span>></span>Tracked repositories<span><span></h2</span>></span> </span> <span><span><span><ul</span> class<span>="m-2 list-decimal"</span>></span> </span> <span><!-- We'll use a loop to automatically add repositories here later on. --> </span> <span><span><span><li</span> class<span>="py-1 flex items-center justify-between"</span>></span> </span> <span><span><span><a</span> class<span>="text-gray-500 hover:underline"</span> href<span>="https://github.com/test/test"</span> </span></span><span> <span>></span>https://github.com/test/test<span><span></a</span> </span></span><span> <span>></span> </span> <button on:click={() => untrack("")} >Untrack<span><span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span><span><span><span></form</span>></span> </span>
>现在剩下的就是在前端获取此功能。在src/lib/usernameprompt.svelte中,在提交功能中,首先需要将请求发送到云功能,然后将用户名放入LocalStorage,因此我们知道用户已认证。您可以使用fetch函数发送请求:
>我们正在重新加载页面,因为在app.svelte中,加载页面后,我们需要检查localStorage中是否有用户名。如果有的话,我们可以跳过USERNAME PROMPT屏幕。为此,请在app.svelte的脚本标签中添加此代码:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>// import UsernamePrompt from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span> <span>import <span>Tracker</span> from "./lib/Tracker.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><!-- <UsernamePrompt /> --> </span><span><span><span><Tracker</span> /></span> </span>
>上面的代码将检查一个用户名的localStorage,并将其设置为true(如果存在)。接下来,我们要做的就是更新DOM。就在app.svelte的脚本标签下,添加以下内容:
<span>const { MongoClient } = require("mongodb"); </span> <span>const mongo = new MongoClient(process.env.MONGODB_URL); </span> <span>// Export the connection promise </span><span>export default mongo.connect(); </span>
跟踪和取消跟踪存储库
<span>{ </span> <span>"type": "commonjs" </span><span>} </span>
>,但在此之前,您需要添加更多云功能。一个可以跟踪存储库,另一个用于取消轨道,另一个用于获取用户的跟踪存储库。
>让我们一个一个一个。
>跟踪存储库创建文件API/TRACKREPO.JS。这将映射到 /api /trackRepo:
用户想要跟踪存储库时,他们将以存储库的名称及其在身体中的用户名来向此功能发送邮政请求。该功能将在用户集合的TrackEdRepos字段中添加存储库的名称。添加一些代码以从身体中获取这些字段:
<span># Don't forget to CD! </span><span>cd api </span><span>npm i mongodb # or use yarn </span>
>最后,添加代码通过将其添加到数据库中来跟踪存储库:
<span>const mongoPromise = require("../src/lib/mongo"); </span><span>// All cloud functions must export a function that takes a req and res object. </span><span>// These objects are similar to their express counterparts. </span>module<span>.exports = async (req<span>, res</span>) => { </span> <span>// TODO </span><span>}; </span>
这就是API/TRACKREPO.JS应该看起来的方式:
>module<span>.exports = async (req<span>, res</span>) => </span> <span>// Wait for the client to connect </span> <span>const mongo = await mongoPromise; </span><span>} </span>
现在是时候在跟踪器中使用此功能了。打开src/lib/tracker.svelte,然后更改track()函数:
><span>// ... </span><span>const { username } = req.body; </span> <span>// Check if the username is valid </span><span>if (typeof username !== "string" || !username.trim()) { </span> res<span>.status(400).json({ message: "Please send the username" }); </span> <span>return; </span><span>} </span>
>现在,当您在输入中输入存储库并单击轨道时,它应该保存在数据库中。
>让我们添加一个云功能以解开存储库。创建文件API/UNTRACKREPO.JS。这将映射到 /api /untrackrepo:
<span>npm init vite </span>
此云功能的请求主体将与TrackRepo函数的请求主体相同 - 用户的用户名和repo:
npx svelte-add tailwindcss <span># Install packages </span><span>yarn install # or npm install </span>
接下来,来自用户的TrackEdRepos删除存储库的代码来了:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let username = ""; </span></span></span><span><span> <span>async function submit() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span> </span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Username"</span> </span></span><span> <span>aria-label<span>="Username"</span> </span></span><span> <span><span>bind:value</span><span>="{username}"</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span> </span> Submit <span><span><span></button</span>></span> </span><span><span><span></form</span>></span> </span>
这就是API/UNTRACKREPO.JS应该看起来的方式:
><span><span><span><script</span>></span><span> </span></span><span><span> <span>import <span>UsernamePrompt</span> from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><UsernamePrompt</span> /></span> </span>
现在是时候在前端使用此云功能了。在src/lib/tracker.svelte的untrack()函数中,添加此代码:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let repo = ""; </span></span></span><span><span> <span>function track() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span> </span></span><span><span> <span>function untrack(repo) { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>={track}</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>GitHub tracker<span><span></h1</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Enter the repository's URL"</span> </span></span><span> <span>aria-label<span>="Repository URL"</span> </span></span><span> <span><span>bind:value</span><span>={repo}</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-2 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span>Track repository<span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span><h2</span> class<span>="mt-4 text-2xl"</span>></span>Tracked repositories<span><span></h2</span>></span> </span> <span><span><span><ul</span> class<span>="m-2 list-decimal"</span>></span> </span> <span><!-- We'll use a loop to automatically add repositories here later on. --> </span> <span><span><span><li</span> class<span>="py-1 flex items-center justify-between"</span>></span> </span> <span><span><span><a</span> class<span>="text-gray-500 hover:underline"</span> href<span>="https://github.com/test/test"</span> </span></span><span> <span>></span>https://github.com/test/test<span><span></a</span> </span></span><span> <span>></span> </span> <button on:click={() => untrack("")} >Untrack<span><span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span><span><span><span></form</span>></span> </span>
>您会注意到它与Track()函数非常相似,因为它实际上是相同的;只是URL已更新。您还不能真正对此进行测试,因为我们没有显示跟踪存储库的列表,所以让我们解决这个问题。
>这部分非常简单。您只需要从数据库中获取用户的跟踪存储库,然后在前端显示它。创建一个云函数API/listrepos.js,然后向其添加以下代码:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>// import UsernamePrompt from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span> <span>import <span>Tracker</span> from "./lib/Tracker.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><!-- <UsernamePrompt /> --> </span><span><span><span><Tracker</span> /></span> </span>>由于将使用HTTP获取请求来调用云功能,因此您无法将其放置在其中,因此我们使用查询字符串来传递用户名;而且由于user.trackedrepos可能为null,因此我们确保返回数组。接下来,是时候在前端使用此云功能了!在src/lib/tracker.svelte文件中创建一个称为fetchrepos的异步函数。此功能将负责使用我们刚刚创建的云功能从数据库中获取用户的跟踪存储库:
>安装组件时我们需要获取此功能。这可以使用Svelte中的OnMount钩子完成。安装组件时,我想将上述函数的返回值设置为一个称为TrackEdrepos的变量,因此我们可以在DOM中使用它:
<span>const { MongoClient } = require("mongodb"); </span> <span>const mongo = new MongoClient(process.env.MONGODB_URL); </span> <span>// Export the connection promise </span><span>export default mongo.connect(); </span>
>现在我们可以访问用户的跟踪存储库,让我们在Tracker.Svelte中更新HTML模板以显示跟踪存储库的准确列表:
<span>{ </span> <span>"type": "commonjs" </span><span>} </span>>
>我们仍然必须重新加载页面才能查看任何更改。让我们每次单击轨道或UNTRACK按钮时都更新DOM来解决该问题:
<span># Don't forget to CD! </span><span>cd api </span><span>npm i mongodb # or use yarn </span>
>这是Tracker.Svelte应该看起来的样子:
<span>const mongoPromise = require("../src/lib/mongo"); </span><span>// All cloud functions must export a function that takes a req and res object. </span><span>// These objects are similar to their express counterparts. </span>module<span>.exports = async (req<span>, res</span>) => { </span> <span>// TODO </span><span>}; </span>
>这是该应用现在应该如何显示的屏幕截图。
module<span>.exports = async (req<span>, res</span>) => </span> <span>// Wait for the client to connect </span> <span>const mongo = await mongoPromise; </span><span>} </span>
>步骤4:使应用程序可安装
>推送通知仅在
为了使应用程序可安装,您需要将其转换为渐进的Web应用程序。这是一个三步的过程:
>要添加服务工作者,您需要添加一个公开可用的JavaScript文件,例如任何CSS文件。这个名称并不重要,但通常被称为service-worker.js或sw.js。该文件应像您的CSS一样公开提供,因此将其放入公共目录中。
>, 现在,如果您>重新加载页面并打开控制台,则应查看上述消息。>
使我们的应用程序脱机 要使应用程序脱机工作,您需要使用服务工作者来缓存其内容。由于我们的应用程序提出了云功能的要求,因此当没有网络时,它实际上无法做太多。因此,我们没有显示该应用程序的缓存,无功能的版本,而是显示一个表明我们离线的页面。创建一个public/offline.html文件,并将以下代码放入其中: 使用CACHE.ADD打开缓存,并将所需的路由添加到缓存中。这发生在安装期间。 页面navigations - 也就是说,更改路由。如果请求成功,一切都很好,但是如果请求失败,我们将向用户提供脱机.html页面。这发生在获取期间。
如果完成了所有三个步骤,则访问应用程序时的地址栏上会出现一个安装按钮。
服务工作者是可以在浏览器主线程中运行的JavaScript文件。这使他们可以执行诸如脱机运行,在后台运行和下载大文件之类的事情。它们主要用于缓存请求和聆听活动,我们将要做的这两个事件。<span>npm init vite
</span>
上面的代码首先检查浏览器中的服务工作者支持,然后注册我们的服务工作者。必须指出的是,寄存器()函数中的路径是相对于您的域npx svelte-add tailwindcss
<span># Install packages
</span><span>yarn install # or npm install
</span>
的路径
>
event.waituntil()是一个类似于等待关键字的函数。 AddEventListener的回调不能异步,因此要实现该功能,我们应该使用event.waituntil()并通过它来承诺,以便期待诺言。
> self.skipwaiting()告诉浏览器我们完成了安装过程,因此请激活服务工作者。说到激活,现在添加代码以删除任何旧的缓存:<span>npm init vite </span>
>,应该将offline.html页面缓存。要仔细检查,请按
f12打开开发人员工具,然后选择“应用程序”选项卡。在侧边栏上,应该有一个缓存存储选项卡。单击它,您应该注意到 /offline.html。
npx svelte-add tailwindcss <span># Install packages </span><span>yarn install # or npm install </span>
现在,当没有网络时,剩下要做的就是服务此文件:
event.respondwith()函数将使用传递给它的任何响应对象响应网络获取请求。在这种情况下,我们首先提取请求,如果请求失败,这很可能是由于Internet问题,我们将发送earlline.html页面,该页面由服务工作者缓存。
现在刷新页面并关闭您的Wi-Fi或以太网。现在,当您刷新时,您应该看到我们的离线页面,而不是默认的Chrome“无网络”页面。不幸的是,此脱机页面没有恐龙游戏,但确实使我们可以将应用程序安装为PWA。
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let username = ""; </span></span></span><span><span> <span>async function submit() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span> </span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Username"</span> </span></span><span> <span>aria-label<span>="Username"</span> </span></span><span> <span><span>bind:value</span><span>="{username}"</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span> </span> Submit <span><span><span></button</span>></span> </span><span><span><span></form</span>></span> </span>添加清单。
链接到您的网站,就像您链接CSS文件一样。让我们为我们的应用程序添加清单。随意使用发电机:
>您需要为应用程序下载一堆图标。这些图标的大小不同,并且由不同的操作系统使用。您可以从源代码存储库或使用此链接下载它们。确保将zip文件提取到公共/图标。
>接下来,您需要将清单和图标添加到index.html文件中。您可以通过将以下代码放入其中:
的打开Chrome’d开发人员工具,然后转到灯塔选项卡并创建一个新的审核。现在,您应该在PWA部分获得“可安装”分数。这意味着您已成功将网站转换为WebApp,现在可以通过单击地址栏上的按钮来安装它。
,并且返回可以等于默认值(拒绝和授予)的A字符串。当用户按下X,按下拒绝或按NOTIFIFICAN提示符允许时,将返回这些。我们将使用app.svelte中的onmount钩子调用此功能: 创建推动消息服务器 >
要发送推送通知,您需要生成一个公共和私有VAPID密钥对。为此,请使用节点命令打开节点reve Repled并运行以下命令: 现在,我们可以开始在云功能上进行工作。创建文件api/vapidkeys.js。该文件将负责将publicvapid键发送给客户端。您应该永远不要共享私有VAPID密钥。在API/vapidkeys.js中,首先我们需要初始化web-push:
。如果打开控制台,则应查看已记录到控制台的订阅。
提供的终点对我们非常重要。此终点将使我们能够使用Web-Push通知此用户。让我们创建一个云功能以将此端点存储在数据库中。创建文件API/StoreEndpoint.js:
>让我们从身体中获取订阅和用户名:
的iSloggedIn变量时。在app.svelte中的<script>标签结束之前,添加此代码
</script><span>npm init vite
</span>
f12步骤5:订阅以推送通知
>在我们发送推送通知之前,我们需要获得用户的许可。您可以使用notification.requestpermission()方法进行此操作。此方法是
>异步npx svelte-add tailwindcss
<span># Install packages
</span><span>yarn install # or npm install
</span>
如果打开控制台,您会注意到一个错误,说applicationserverkey缺少。推送通知需要服务器来发送推送消息,并且这些服务器使用VAPID键进行身份验证。这些键标识服务器,并让浏览器知道推送消息有效。我们将使用Vercel Cloud函数发送推送消息,因此我们需要进行设置。<span><span><span><script</span>></span><span>
</span></span><span><span> <span>let username = "";
</span></span></span><span><span> <span>async function submit() {
</span></span></span><span><span> <span>// TODO
</span></span></span><span><span> <span>}
</span></span></span><span><span></span><span><span></script</span>></span>
</span>
<span><span><span><form</span>
</span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span>
</span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span>
</span></span><span><span>></span>
</span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span>
</span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span>
</span>
<span><span><span><input</span>
</span></span><span> <span>type<span>="text"</span>
</span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span>
</span></span><span> <span>placeholder<span>="Username"</span>
</span></span><span> <span>aria-label<span>="Username"</span>
</span></span><span> <span><span>bind:value</span><span>="{username}"</span>
</span></span><span> <span>/></span>
</span>
<span><span><span><button</span>
</span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span>
</span></span><span> <span>></span>
</span> Submit
<span><span><span></button</span>></span>
</span><span><span><span></form</span>></span>
</span>
>我们将使用Web-Push NPM软件包来帮助我们生成密钥并发送推送事件。要安装它,请将其CD到API文件夹并运行以下内容:请记住将CD到API文件夹,否则Web-Push软件包将安装在Svelte App中。
<span><span><span><script</span>></span><span>
</span></span><span><span> <span>import <span>UsernamePrompt</span> from "./lib/UsernamePrompt.svelte";
</span></span></span><span><span></span><span><span></script</span>></span>
</span>
<span><span><span><UsernamePrompt</span> /></span>
</span>
>复制这两个键,并将它们作为环境变量存储在Vercel上。确保称他们为令人难忘的东西,例如vapid_private_key和vapid_public_key。
<span>npm init vite
</span>
>完成此操作,您现在可以更新app.svelte中的onmount函数以首先获取云功能以获取公共密钥,然后在订阅函数中使用公共密钥:npx svelte-add tailwindcss
<span># Install packages
</span><span>yarn install # or npm install
</span>
>我们尚未订阅推送通知,我们只能获取Vapid键<span><span><span><script</span>></span><span>
</span></span><span><span> <span>let username = "";
</span></span></span><span><span> <span>async function submit() {
</span></span></span><span><span> <span>// TODO
</span></span></span><span><span> <span>}
</span></span></span><span><span></span><span><span></script</span>></span>
</span>
<span><span><span><form</span>
</span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span>
</span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span>
</span></span><span><span>></span>
</span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span>
</span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span>
</span>
<span><span><span><input</span>
</span></span><span> <span>type<span>="text"</span>
</span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span>
</span></span><span> <span>placeholder<span>="Username"</span>
</span></span><span> <span>aria-label<span>="Username"</span>
</span></span><span> <span><span>bind:value</span><span>="{username}"</span>
</span></span><span> <span>/></span>
</span>
<span><span><span><button</span>
</span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span>
</span></span><span> <span>></span>
</span> Submit
<span><span><span></button</span>></span>
</span><span><span><span></form</span>></span>
</span>
<span><span><span><script</span>></span><span>
</span></span><span><span> <span>import <span>UsernamePrompt</span> from "./lib/UsernamePrompt.svelte";
</span></span></span><span><span></span><span><span></script</span>></span>
</span>
<span><span><span><UsernamePrompt</span> /></span>
</span>
>这是最终云功能的外观:<span><span><span><script</span>></span><span>
</span></span><span><span> <span>let repo = "";
</span></span></span><span><span> <span>function track() {
</span></span></span><span><span> <span>// TODO
</span></span></span><span><span> <span>}
</span></span></span><span><span>
</span></span><span><span> <span>function untrack(repo) {
</span></span></span><span><span> <span>// TODO
</span></span></span><span><span> <span>}
</span></span></span><span><span></span><span><span></script</span>></span>
</span>
<span><span><span><form</span>
</span></span><span> <span><span>on:submit|preventDefault</span><span>={track}</span>
</span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span>
</span></span><span><span>></span>
</span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>GitHub tracker<span><span></h1</span>></span>
</span>
<span><span><span><input</span>
</span></span><span> <span>type<span>="text"</span>
</span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span>
</span></span><span> <span>placeholder<span>="Enter the repository's URL"</span>
</span></span><span> <span>aria-label<span>="Repository URL"</span>
</span></span><span> <span><span>bind:value</span><span>={repo}</span>
</span></span><span> <span>/></span>
</span> <span><span><span><button</span>
</span></span><span> <span>class<span>="mt-2 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span>
</span></span><span> <span>></span>Track repository<span><span></button</span>
</span></span><span> <span>></span>
</span>
<span><span><span><h2</span> class<span>="mt-4 text-2xl"</span>></span>Tracked repositories<span><span></h2</span>></span>
</span> <span><span><span><ul</span> class<span>="m-2 list-decimal"</span>></span>
</span> <span><!-- We'll use a loop to automatically add repositories here later on. -->
</span> <span><span><span><li</span> class<span>="py-1 flex items-center justify-between"</span>></span>
</span> <span><span><span><a</span> class<span>="text-gray-500 hover:underline"</span> href<span>="https://github.com/test/test"</span>
</span></span><span> <span>></span>https://github.com/test/test<span><span></a</span>
</span></span><span> <span>></span>
</span> <button on:click={() => untrack("")}
>Untrack<span><span><span></button</span>
</span></span><span> <span>></span>
</span> <span><span><span></li</span>></span>
</span> <span><span><span></ul</span>></span>
</span><span><span><span></form</span>></span>
</span>
>和<span><span><span><script</span>></span><span>
</span></span><span><span> <span>// import UsernamePrompt from "./lib/UsernamePrompt.svelte";
</span></span></span><span><span> <span>import <span>Tracker</span> from "./lib/Tracker.svelte";
</span></span></span><span><span></span><span><span></script</span>></span>
</span>
<span><!-- <UsernamePrompt /> -->
</span><span><span><span><Tracker</span> /></span>
</span>
>刷新页面,您应该看到当前浏览器的按下端点和键存储在订阅对象中的mongoDB数据库中。
<span>const { MongoClient } = require("mongodb"); </span> <span>const mongo = new MongoClient(process.env.MONGODB_URL); </span> <span>// Export the connection promise </span><span>export default mongo.connect(); </span>>
>让我们从数据库中获取所有用户,因此我们知道要获取什么回购:
<span>npm init vite </span>
对于每个用户,让我们查看其跟踪的存储库中的任何新问题。为了确保仅检查一个存储库一次,我们将将存储库添加到已经取方的雷神中,并将添加所有具有新问题的存储库中的存储库。为此,我们需要循环浏览用户数组中的每个用户,并获取以获取的存储库列表。这将通过检查其TrackedRepos中的任何重复项来完成。完成此操作后,我们将为每个存储库调用FetchRepo功能。 fetchrepo将返回布尔值 - 如果有新问题,则为false,否则:
>npx svelte-add tailwindcss <span># Install packages </span><span>yarn install # or npm install </span>
>由于fetchrepo会异步,所以我使用地图每次都返回承诺,并使用Promise.All等待所有诺言。这是因为for循环是异步的。如果不期待承诺,变量可能是不确定的,请务必等待承诺!
> 现在,用于fetchrepo函数。此功能将获得我们最后一次从数据库中检查GitHub API的时间。这只能从Github获取最新问题。然后,它以获取任何新问题的GitHub API,如果有的话,将返回一个布尔值:>
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let username = ""; </span></span></span><span><span> <span>async function submit() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span> </span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Username"</span> </span></span><span> <span>aria-label<span>="Username"</span> </span></span><span> <span><span>bind:value</span><span>="{username}"</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span> </span> Submit <span><span><span></button</span>></span> </span><span><span><span></form</span>></span> </span>>完成此操作后,我们需要向跟踪具有任何新问题的存储库的任何用户发送推送通知。这可以使用Web-Push完成。将这些代码行添加到导出函数的末尾:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>import <span>UsernamePrompt</span> from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><UsernamePrompt</span> /></span> </span>首先,我们需要检查任何用户的跟踪存储库是否有新问题。这可以使用阵列。一种方法。 array.some()确定指定的回调函数是否返回数组的任何元素,因此我们可以轻松地使用它来检查:
>
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let repo = ""; </span></span></span><span><span> <span>function track() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span> </span></span><span><span> <span>function untrack(repo) { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>={track}</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>GitHub tracker<span><span></h1</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Enter the repository's URL"</span> </span></span><span> <span>aria-label<span>="Repository URL"</span> </span></span><span> <span><span>bind:value</span><span>={repo}</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-2 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span>Track repository<span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span><h2</span> class<span>="mt-4 text-2xl"</span>></span>Tracked repositories<span><span></h2</span>></span> </span> <span><span><span><ul</span> class<span>="m-2 list-decimal"</span>></span> </span> <span><!-- We'll use a loop to automatically add repositories here later on. --> </span> <span><span><span><li</span> class<span>="py-1 flex items-center justify-between"</span>></span> </span> <span><span><span><a</span> class<span>="text-gray-500 hover:underline"</span> href<span>="https://github.com/test/test"</span> </span></span><span> <span>></span>https://github.com/test/test<span><span></a</span> </span></span><span> <span>></span> </span> <button on:click={() => untrack("")} >Untrack<span><span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span><span><span><span></form</span>></span> </span>>最后,我们发送通知:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>// import UsernamePrompt from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span> <span>import <span>Tracker</span> from "./lib/Tracker.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><!-- <UsernamePrompt /> --> </span><span><span><span><Tracker</span> /></span> </span>这是云功能应该看起来的方式:
<span>const { MongoClient } = require("mongodb"); </span> <span>const mongo = new MongoClient(process.env.MONGODB_URL); </span> <span>// Export the connection promise </span><span>export default mongo.connect(); </span>聆听推动事件
<span>{ </span> <span>"type": "commonjs" </span><span>} </span>>调用云功能时,也许使用卷发时,您应该在浏览器控制台中查看新问题。这真的不是很有帮助,所以让它发出通知:
>
<span># Don't forget to CD! </span><span>cd api </span><span>npm i mongodb # or use yarn </span>>从mongodb删除收集的收集,然后再次调用云功能。现在,您应该从Web浏览器中收到通知。
,也应该收到通知。
如果您没有收到通知,或者从Web推动中获得410错误,请确保在询问时允许在提示符中永远允许通知。>
>
>前往您的EasyCron仪表板,创建一个新的Cron作业。对于URL,请输入https:// your_vercel_domain/api/fetchgh,然后选择一个间隔。我每小时都会去,但请随时自定义。>
>经常询问的问题(常见问题解答)关于在Svelte
中创建带有推送通知的GitHub跟踪器我可以使用Svelte跟踪多个GitHub存储库吗?>
>我可以与其他JavaScript框架或库一起使用Svelte? JavaScript框架或库。但是,Svelte的主要优点之一是它的简单性和效率,因此将其与其他框架或图书馆一起使用可能会否定其中一些好处。如果可能的话,最好自行使用Svelte。
>使用JavaScript代码中的try/catch块可以在Svelte中进行错误处理。例如,如果从GitHub API获取数据时发生错误,则可以捕获错误并向用户显示有用的消息。
>如何在Svelte中测试我的GitHub Tracker?可以使用各种JavaScript测试库,例如开玩笑或摩卡咖啡来完成。这些库允许您为组件和反应性语句编写测试,以确保它们正常工作。
是的,您可以部署Svelte GitHub跟踪器到服务器。 Svelte将您的代码编译到普通的JavaScript,CSS和HTML,可以由任何静态文件服务器提供。
>以上是在Svelte中创建带有推送通知的GitHub跟踪器的详细内容。更多信息请关注PHP中文网其他相关文章!