>在本文中,您將學習如何構建一個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>
測試您的組件,
<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>
>
注意:請記住將App.svelte還原到其先前的代碼!步驟2:設置雲功能
>我們需要有一個後端服務器將推動事件發送到我們的應用程序。這意味著您需要創建一個新的(也許)ExpressJS項目,然後單獨部署。對於僅嘗試使用推送通知的人來說,這都是頭痛。>
要連接到數據庫,您需要連接字符串。將新用戶和密碼保存在某個地方,然後轉到群集的概述。單擊右側的連接按鈕,然後選擇“連接應用程序”作為連接方法。您應該看到一個類似於下面的連接字符串。
>
>現在您擁有連接字符串,可以連接到數據庫,但是首先,您需要將當前應用程序部署到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>
>創建一個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>
>將您的應用程序通過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>
>
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>
>
<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>
>安裝組件時我們需要獲取此功能。這可以使用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,現在可以通過單擊地址欄上的按鈕來安裝它。
步驟5:訂閱以推送通知 ,並且返回可以等於默認值(拒絕和授予)的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>
>在我們發送推送通知之前,我們需要獲得用戶的許可。您可以使用notification.requestpermission()方法進行此操作。此方法是
>異步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>
請記住將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>
<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>
<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>
<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>
<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>
<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>
使用Vercel部署應用程序。或通過推動GitHub,將應用程序作為PWA安裝,然後通過訪問https:// your_vercel_app/api/fetchgh來運行雲功能,即使您尚未打開應用程序!
,也應該收到通知。
如果您沒有收到通知,或者從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中文網其他相關文章!