使用 Node.js 和 SQLite 实现离线优先应用程序
2025-09-20 12:18
}
});
几周,我们将创建人一个帖子列此表,将其存储设备在我们的资料库中亦会,稍后不宜用于此此表code相片展现出到客户端:
激活
let blogs = [
{
id: "1",
title: "How To Build A RESTAPI With Javascript",
avatar: "images/coffee2.jpg",
intro: "iste odio beatae voluptas dolor praesentium illo facere optio nobis magni, aspernatur quas.",
},
{
id: "2",
title: "How to Build an Offline-First Application with Node.js,"
avatar: "images/coffee2.jpg",
"iste odio beatae voluptas dolor praesentium illo facere optio nobis magni, aspernatur quas.",
},
{
id: "3",
title: "Building a Trello Clone with React DnD",
avatar: "images/coffee2.jpg",
intro: "iste odio beatae voluptas dolor praesentium illo facere optio nobis magni, aspernatur quas.",
},
];
我们转换系统中亦会的每个块帖子都有一个id、title、 avatar和intro字段。
今天创建人一个资料库此表名为blogs并不宜用于比如说的code相片完好我们刚在上头创建人的帖子的资讯:
激活
db.run(
于大CREATE TABLE blog (id INTEGER PRIMARY KEY AUTOINCREMENT, title text,avatar text,intro text)于大,
(err) => {
if (err) {
// console.log(err)
// Table already created
} else {
// Table just created, creating some rows
var insert = "INSERT INTO blogs (title, avatar, intro) VALUES (?,?,?)";
blogs.map((blog) => {
db.run(insert, [
于大${blog.title}于大,
于大${blog.avatar}于大,
于大${blog.intro}于大,
]);
});
}
}
);
在code相片中亦会,我们不宜用于db.run 创建人了一个此表blogs 。db.run方法有接均受一个 SQL 查询作为变量,然后我们遍历我们的帖子codice_并将它们插入到我们刚不宜用于 js map 变数创建人的 blogs 此表中亦会。
查看资料库据信今天让我们查看我们刚不宜用于Arctype创建人的据信。要不宜用于 Arctype 查看 SQLite 资料库中亦会的据信,问执行者此此表流程:
配备 Arctype 调试转换系统node index.js以创建人资料库 叫停 Arctype 并点击 SQLite 选项卡 点击 Select SQLite file按钮,认出调试服务器端时转化的db.sqlite副本。 您某种程度看到 blogs 此表和我们创建人的据信,如比如说的大屏幕截图请注意: 过场页面此时,我们已将转换系统连通到 SQLite 资料库,并在资料库中亦会插入了一些据信。今天,推开index.html副本并在比如说替换成此此表code相片:
激活
Blogger
Blogger
Home
Blog
我们在上头的副本中亦会创建人了一个有用的标示出,其中亦会都有对准我们名册的客户端,我们将在下一大部分、styles和app.js副本中亦会创建人它。
然后,我们将在index.js 副本中亦会创建人一个blogs路由,以将帖子调回到客户端。
激活
app.get("/blogs", (req, res) => {
res.status(200).json({
blogs,
});
});
在我们的public/js/app.js副本中亦会,我们将向帖子端点发送一个换取劝告,以从我们的后端换取帖子。然后我们遍历帖子,定位容器类并推断它们。
激活
let result = "";
fetch("")
.then((res) => res.json())
.then(({ rows } = data) => {
rows.forEach(({ title, avatar, intro } = rows) => {
result += 于大
${title}
${intro}
Read
于大;
});
document.querySelector(".container").innerHTML = result;
})
.catch((e) => {
console.log(e);
});
我们还将不宜用于此此表code相片在public/css/style.css 中亦会为我们的转换系统替换成一些样式:
激活
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #fdfdfd;
font-size: 1rem;
}
section {
max-width: 900px;
margin: auto;
padding: 0.5rem;
text-align: center;
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
}
ul {
list-style: none;
display: flex;
}
li {
margin-right: 1rem;
}
h1 {
color: #0e9c95;
margin-bottom: 0.5rem;
}
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
grid-gap: 1rem;
justify-content: center;
align-items: center;
margin: auto;
padding: 1rem 0;
}
.card {
display: flex;
align-items: center;
flex-direction: column;
width: 15rem auto;
background: #fff;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
border-radius: 10px;
margin: auto;
overflow: hidden;
}
.card-avatar {
width: 100%;
height: 10rem;
object-fit: cover;
}
.card-title {
color: #222;
font-weight: 700;
text-transform: capitalize;
font-size: 1.1rem;
margin-top: 0.5rem;
}
.card-link {
text-decoration: none;
background: #16a0d6e7;
color: #fff;
padding: 0.3rem 1rem;
border-radius: 20px;
margin: 10px;
}
.intro {
color: #c2c5c5;
padding: 10px;
}
.active {
color: #16a0d6e7;
}
今天推开package.json副本并替换成叫停CGI。
激活
"start": "node index.js"
自始,我们已经增设了我们的转换系统。但是当服务器端没有调试或者没有的装置用于制造时,我们未调试我们的转换系统。让我们在下一节中亦会进行增设。
优化不宜用
我们需使我们的转换系统与所有大屏幕尺寸兼容。我们还将通过在index.html 副本的 head 大部分替换成比如说的标示出来替换成都由题颜色。
激活
创建人名册
我们需叙述我们的转换系统以及它在配备在服务器端装置上时的道德上方式。我们可以通过创建人名册来做到这一点。
在单项此表单下创建人manifest副本,替换成如下配置:
激活
{
"name": "Blogger"
"short_name": "Blogger"
"start_url": "/",
"display": "standalone",
"background_color": "#0e9c95",
"theme_color": "#16a0d6e7",
"orientation": "portrait",
"icons": []
}
在我们的名册中亦会,我们定义了此此表配置:
name:这定义了转换系统的推断名称。 short_name:这定义了配备时将在转换系统可选下推断的名称。 start_url:这告知插件转换系统的棍子 URL。 display:这告知插件如何推断转换系统。 background_color: 这定义了配备时转换系统的背景颜色。 theme_color: 这定义了状态栏的颜色。 朝著: 这定义了在不宜用推断长期不宜用于的朝著。 可选: 这定义了不同微小的可选或图像用作我们的转换系统都由页可选。手动创建人我们的都由大屏幕可选意味著是一项非常复杂的任务,但并不需要担心。我们将透过名为pwa-asset-generator的第三方模块,不宜用于此此表指示从公共目录中亦会的都由转换系统可选转化不同微小的可选:
激活
#change directory to the public folder
cd public
#generate icons
npx pwa-asset-generator logo.png icons
上头的指示将在 public 副本夹中亦会创建人一个可选 副本夹,其中亦会都有我们转换系统的许多可选,以及接口上的一些JSON,我们将插入到名册中亦会的可选codice_中亦会。
我们名册中亦会的可选codice_不宜如下请注意:
激活
"icons": [
{
"src": "public/icons/manifest-icon-192.maskable.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "public/icons/manifest-icon-192.maskable.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "public/icons/manifest-icon-512.maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
},
{
"src": "public/icons/manifest-icon-512.maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
此外,该指示转化了对准转化的可选的标示出客户端。
将标示出激活并插入到public/index.html 副本中亦会标示出的 head 大部分。
增设服务教育工所作
创建人名册后,让我们增设服务教育工所作。Service Worker 是一段 JavaScript code,您的插件在后台调试在一个单独的线程中亦会,以解决问题您为将来的劝告完好的负债和资料的CPU,从而为您的转换系统启用用户端反对。
所以在public 副本夹中亦会创建人一个blogger.serviceWorker.js 副本。对于 service worker,有很多惨案(push、activate、install、fetch、message、sync),但对于本教程的演示,我们将讲解install、activate 和fetch 惨案。以前,我们需创建人一个codice_来存储设备我们在转换系统中亦会不宜用于的所有负债。
激活
const assets = [
"/",
"css/style.css",
"js/app.js",
"/images/blog1.jpg",
"/images/blog2.jpg",
"/images/blog3.jpg,"
];
然后,我们将监听install 惨案来登记并将我们的模板副本完好到插件的CPU中亦会。此过程需一些时间才能未完成。要跳过才亦会,我们将不宜用于skipWaiting()。
激活
const BLOGGER_ASSETS = "blogger-assets";
self.addEventListener("install", (installEvt) => {
installEvt.waitUntil(
caches
.open(BLOGGER_ASSETS)
.then((cache) => {
cache.addAll(assets);
})
.then(self.skipWaiting())
.catch((e) => {
console.log(e);
})
);
});
然后,我们需在 service worker 修正时清除CPU以删掉从新负债。为此,我们将收听比如说的激活 code相片:
激活
self.addEventListener("activate", function (evt) {
evt.waitUntil(
caches
.keys()
.then((keysList) => {
return Promise.all(
keysList.map((key) => {
if (key === BLOGGER_ASSETS) {
console.log(于大Removed old cache from ${key}于大);
return caches.delete(key);
}
})
);
})
.then(() => self.clients
在上头的code相片中亦会,我们在 service worker 上不宜用于了waitUntil方法有。此方法有才亦会转换未完成,然后在删掉之前健康检查我们尝试清除的负债是否是是我们近期转换系统的负债。
几周,我们需存储设备在CPU中亦会的副本才能不宜用于它们。
激活
self.addEventListener("fetch", function (evt) {
evt.respondWith(
fetch(evt.request).catch(() => {
return caches.open(BLOGGER_ASSETS).then((cache) => {
return cache.match(evt.request);
});
})
);
})
当在页面上发出劝告时,PWA 将健康检查我们的CPU并从CPU中亦会读取资料,而不是去网络服务。然后,不宜用于respondWith方法有,我们覆盖插件的默认值并让我们的惨案调回一个 Promise。CPU未完成后,我们可以调回evt.request对不宜的CPU。当CPU准备好后,我们可以调回匹配 evt.request 的CPU。
我们已经事与愿违增设了我们的 service worker。今天让我们让它在我们的转换系统中亦会可用。
登记 Service Worker
今天让我们在public/js/app.js 副本中亦会登记我们的 service worker,code相片如下:
激活
if ("serviceWorker" in navigator) {
window.addEventListener("load", function () {
navigator.serviceWorker
.register("/blogger.serviceWorker.js")
.then((res) => console.log("service worker registered"))
.catch((err) => console.log("service worker not registered", err));
});
}
在这里,我们健康检查我们的转换系统的插件是否是反对Service Worker(当然不是所有的插件都反对Service Worker),然后登记我们的Service Worker 副本。
今天不宜用于此此表指示调试转换系统:
激活
npm start
在插件中亦会转到 localhost:8000 以次访问该转换系统。
雅虎灯塔健康检查
今天让我们健康检查一下我们是否是不宜用于Google Lighthouse健康检查正确增设了 PWA 。右键点击插件并必需“健康检查”。在健康检查选项卡上,必需灯塔并点击转化通报。如果您的转换系统一切顺利,您某种程度亦会看到如下大屏幕截图中亦会的输出:
我们已经事与愿违地创建人了我们的第一个转换系统。你还可以停止服务器端以在用户端模式下测试转换系统。
论证渐进式 Web 不宜用 (PWA) 不宜用于早期 API 通过单个code库提供者增强的系统、可靠性和可配备性。它们意味着您的最终服务器端不宜用于您的转换系统,无论他们是否是有互联网连通。您某种程度随时 fork存储设备库并向单项替换成其他系统。
注解开头:Building Offline-First Apps With Node.js and SQLite
注解所作:Clara Ekekenta
。青岛牛皮癣专科医院哪好北京看白癜风到哪家医院好
南京看男科去哪里最好
重庆看皮肤病到哪个医院好
南京看男科去哪家医院
偏瘫
肛肠外科
食欲不振
急支糖浆的功效和作用
左胸疼
-
中国球迷太双标?对待0-5比0-8的态度竟截然不同,理由何在?
p 当然了说是中国人埃弗顿太十分容易满足,这其实也无论如何,如今中国人足球这个脑袋,我们远超过的奢望就是看著了努力。你怎么显然呢?欢迎朋友们在评论区一起发表意见!。a hr
-
恩怨局?考神炮轰前东家,自认队史最佳,名人堂、退役球衣都一定会
恩怨交?考神开炮从前士柏,绝非队史最佳,美国科学院、退休球鞋都打算 全因,随着NBA盖帽的完结,主队们关怀就此的季后赛也终于稍早。不过,对于有些当季来感叹,却一直较难品尝到季后赛
- 09-20太狠了!双机狂砍19分,一人罚球数远超猛龙全队!
- 09-20基德:布伦森今年夏天能赚很多买 如果他需要经纪人我愿意干
- 09-20林书豪:每天都会问自己有没有尽全力去拼 是的话就没什么后悔了
- 09-20足球巨星C罗龙凤胎儿子英年早逝!称自己心情悲痛,网友纷纷留言安慰
- 09-20落后12分,黄蜂26-8反超掘金!库里半场16分,新版五小打懵约基奇
- 09-20CCTV5直播世锦赛,丁俊晖、赵心童冲冠,颜丙涛VS黑马,吕昊天VS世锦赛
- 09-20CBA27岁外援受捧,2豪门争抢,杜锋亦同李春江成全,引援辅助易建联
- 09-20哈维:我为输球肩负主要责任,现在目标是确保下赛季欧冠资格
- 09-20只关于吐槽|比登组合给勇士整懵了;发布会还可以喝酒?科尔和约基奇赌命
- 09-20斯玛特的防守,到底爆冷在了哪