SQLite
 sql >> база данни >  >> RDS >> SQLite

Създаване на първо офлайн приложение с Node.js и SQLite

„Първо офлайн“ е парадигма за разработка на приложения, при която разработчиците гарантират, че функционалността на приложението не се влияе от временна загуба на мрежова свързаност. Прогресивните уеб приложения, които се чувстват като родни приложения, но работят като уеб приложения, често са изградени върху тази парадигма.

Този урок ще ви научи как да изградите първо офлайн приложение с Node.js и база данни SQLite. Нека започнем с въведение в прогресивните уеб приложения.

Въведение в PWA

Прогресивните уеб приложения (PWA) са уеб приложения, които използват обслужващи работници, манифести и други функции на уеб платформата и прогресивно подобрение, за да предоставят на потребителите изживяване, сравнимо с родните приложения.

PWA понякога могат да превъзхождат родните приложения по отношение на ефективност. Те работят при поискване и винаги са налични, без да консумират ценна памет или данни на смартфона. Потребителите консумират по-малко данни, когато избират PWA пред оригинална версия на същото приложение. Те все още могат да запишат PWA на началния си екран; може да се инсталира, без да е необходимо пълно изтегляне.

Какво изграждаме?

За да демонстрираме силата на прогресивните уеб приложения, ще изградим просто приложение за блог.

Потребителят ще може да взаимодейства с него като други PWA, като Twitter PWA. Нека да преминем направо към него.

Инициализирайте приложението NodeJs

Да си изцапаме ръцете. За да започнем, ще създадем папката на нашия проект с командата по-долу:

mkdir PWA && cd PWA

След това ще инициализираме приложение Node.js с командите по-долу:

npm init -y

Горната команда създава package.json файл за приложението.

След това създайте следната структура на папките в папката на нашия проект:

Настройте експресен сървър

С настройката на нашето приложение, нека инсталираме Express, за да създадем нашия Node.js сървър с командата по-долу:

npm install express

След това ще създадем няколко папки и файлове в публичната папка:

  • css/style.css файл
  • js/app.js файл

След това създайте index.js файл в основната директория на проекта със следните кодови фрагменти по-долу:

const express = require("express");
const path = require("path");
const app = express();
app.use(express.static(path.join(__dirname, "public")));

app.get("/", function (req, res) {
  res.sendFile(path.join(__dirname, "public/index.html"));
});
app.listen(8000, () => console.log("Server is running on Port 8000"));

В кодовия фрагмент ние импортираме експресно за да създадем нашия сървър и пъта модул. Конфигурирахме нашето приложение да изобразява нашите статични файлове с помощта на express.static метод, който отвежда пътя към статичната папка (публична), създадохме основния маршрут на нашето приложение и изобразихме index.html файл. След това конфигурирахме приложението да слуша порт 8000 .

Свържете се с базата данни SQLite

С настройката на сървъра за нашето приложение, нека създадем и свържем нашето приложение, за да запазим подробностите за нашия блог. За да започнете, изпълнете командата по-долу, за да инсталирате зависимостта sqlite3.

npm install sqlite3

След това във входната точка index.js файл, добавете кодовия фрагмент по-долу, за да създадете и свържете приложението към база данни на SQLite.

const db = new sqlite3.Database("db.sqlite", (err) => {
  if (err) {
    // Cannot open database
    console.error(err.message);
    throw err;
  } else {
    console.log("Connected to the SQLite database.");
  }
});

След това ще създадем списък с блогове, които ще съхраняваме в нашата база данни и ще изобразим по-късно на клиентската страна с кодовия фрагмент по-долу:

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 ,заглавие ,аватара , ивъведение полета.

Сега създайте таблица на база данни с име блогове и запазете подробностите за блога, които току-що създадохме по-горе с кодовия фрагмент по-долу:

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}`,
        ]);
      });
    }
  }
);

В кодовия фрагмент създадохме таблица блогове с помощта на db.run. db.run Методът приема SQL заявка като параметър, след което преминаваме през нашия масив от блогове и ги вмъкваме в таблицата с блогове, която току-що създадохме с помощта на функцията js map.

Преглед на записи в базата данни

Сега нека разгледаме записите, които току-що създадохме с помощта на Arctype. За да видите записите във вашата SQLite база данни с помощта на Arctype, следвайте стъпките по-долу:

  • Инсталиране на Arctype
  • Изпълнете приложението с node index.js за създаване на база данни
  • Стартирайте Arctype и щракнете върху раздела SQLite

  • Щракнете върху Избор на SQLite файл бутона и намерете db.sqlite файл, генериран при стартиране на сървъра.
  • Трябва да видите таблицата с блогове и записите, които създаваме, както е показано на екранната снимка по-долу:

Изобразете страницата

В този момент ние свързахме приложението към база данни на SQLite и също така вмъкнахме някои записи в базата данни. Сега отворете index.html файл и добавете следните кодови фрагменти по-долу:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="stylesheet" href="css/style.css" />
    <title>Blogger</title>
    <link rel="manifest" href="manifest" />
  </head>
  <body>
    <section>
      <nav>
        <h1>Blogger</h1>
        <ul>
          <li>Home</li>
           <li class="active">Blog</li>
        </ul>
      </nav>
      <div class="container"></div>
    </section>
    <script src="js/app.js"></script>
  </body>
</html>

Създадохме проста маркировка с връзки към нашия манифест в горния файл, който ще създадем в следващия раздел, стилове и app.js файлове.

След това ще създадем блогове маршрут в нашия index.js файл, за да върнете блоговете от страна на клиента.

...
app.get("/blogs", (req, res) => {
  res.status(200).json({
    blogs,
  });
});
...

В нашия public/js/app.js файл, ще изпратим заявка за получаване до крайната точка на блога, за да получим блоговете от нашия бекенд. След това преглеждаме блоговете, насочваме към контейнера клас и ги покажете.

let result = "";
fetch("http://localhost:8000/blogs")
  .then((res) => res.json())
   .then(({ rows } = data) => {
    rows.forEach(({ title, avatar, intro } = rows) => {
      result += `
       <div class="card">
            <img class="card-avatar" src="/${avatar}"/>
            <h1 class="card-title">${title}</h1>
            <p class="intro">${intro}</p>
            <a class="card-link" href="#">Read</a>
        </div>
       `;
    });
    document.querySelector(".container").innerHTML = result;
  })
  .catch((e) => {
    console.log(e);
  });

Ще добавим и малко стилизиране към нашето приложение в 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 файл и добавете стартовия скрипт.

"start": "node index.js"

На този етап настроихме нашето приложение. Но не можем да стартираме нашето приложение, когато сървърът не работи или когато няма мрежова връзка за производство. Нека го настроим в следващия раздел.

Оптимизиращо приложение

Трябва да направим нашето приложение съвместимо с всички размери на екрана. Ние също така ще добавим цвят на темата, като добавим маркирането по-долу в секцията head на нашия index.html файл.

<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#16a0d6e7"/>

Създайте манифест

Трябва да опишем нашето приложение и как трябва да се държи, когато е инсталирано на устройството на потребителя. Можем да направим това, като създадем манифест.

Създайте манифест файл в основната директория на проекта и добавете следните конфигурации:

{
    "name": "Blogger"
    "short_name": "Blogger"
    "start_url": "/",
    "display": "standalone",
    "background_color": "#0e9c95",
    "theme_color": "#16a0d6e7",
    "orientation": "portrait",
    "icons": []
}

В нашия манифест дефинирахме следните конфигурации:

  • име :Това дефинира екранното име на приложението.
  • short_name :Това определя името, което ще се показва под иконата на приложението при инсталиране.
  • start_url :Това казва на браузъра основния URL адрес на приложението.
  • дисплей :Това указва на браузъра как да показва приложението.
  • background_color: Това определя цвета на фона на приложението, когато е инсталирано.
  • цвят_тема: Това определя цвета на лентата на състоянието.
  • ориентация: Това определя ориентацията, която да се използва по време на показване на приложението.
  • икони: Това определя иконите или изображенията с различни размери, които да се използват като начални икони на нашето приложение.

Ръчното създаване на икони на началния ни екран може да бъде много сложна задача, но не се притеснявайте. Ще се възползваме от модул на трета страна, известен като pwa-asset-generator, за да генерираме икони с различни размери от нашата основна икона на приложението в публичната директория с командата по-долу:

#change directory to the public folder
cd public
#generate icons
npx pwa-asset-generator logo.png icons

Горната команда ще създаде икони папка в публичната папка с много икони за нашето приложение, заедно с някои JSON на терминала, който ще поставим в нашия масив от икони в манифеста.

Масивът от икони в нашия манифест трябва да изглежда така:

"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 файл.

Работници за настройка

Със създаден нашия манифест, нека настроим обслужващите работници. Service Worker е част от JavaScript код, който браузърът ви изпълнява във фонов режим в отделна нишка, за да обработва кеша за активи и данни, които запазвате за бъдещи заявки, за да активирате офлайн поддръжката за вашето приложение.

Затова създайте blogger.serviceWorker.js файл в публичния папка. За сервизния работник има много събития (натискане, активиране, инсталиране, извличане, съобщение, синхронизиране), но за демонстрацията в този урок ще разгледаме инсталиране, активиране, иизвличане събития. Преди това трябва да създадем масив за съхраняване на всички активи, които използвахме в нашето приложение.

const assets = [
  "/",
  "css/style.css",
  "js/app.js",
  "/images/blog1.jpg",
  "/images/blog2.jpg",
  "/images/blog3.jpg,"
];

След това ще чуем инсталирането събитие, за да регистрирате и запишете нашите статични файлове в кеша на браузъра. Този процес отнема известно време, за да завърши. За да пропуснем чакането, ще използваме 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);
      })
  );
});
...

След това трябва да изчистим кеша, за да премахнем старите активи всеки път, когато обслужващият работник се актуализира. За това ще чуем активирането кодов фрагмент по-долу:

...
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.claim())
  );
});

В горния кодов фрагмент ние използваме waitUntil метод на обслужващия работник. Този метод изчаква действието да приключи и след това проверяваме дали активите, които се опитваме да изчистим, са активите на текущото ни приложение, преди да ги изтрием.

След това се нуждаем от файловете, съхранявани в нашия кеш, за да ги използваме.

self.addEventListener("fetch", function (evt) {
  evt.respondWith(
    fetch(evt.request).catch(() => {
      return caches.open(BLOGGER_ASSETS).then((cache) => {
        return cache.match(evt.request);
      });
    })
  );
})

Когато се направи заявка на страницата, PWA ще провери нашия кеш и ще прочете от него дали има данни в кеша, вместо да отиде в мрежата. След това с помощта на отговори с метод, ние отменяме настройките по подразбиране на браузъра и караме нашето събитие да връща обещание. Когато кешът приключи, можем да върнем кеша, съответстващ на evt.request. Когато кешът е готов, можем да върнем кеша, който съответства на evt.request.

Успешно настроихме нашия сервизен работник. Сега нека го направим достъпен в нашето приложение.

Регистрирайте Service Worker

Сега нека регистрираме нашия обслужващ работник в нашия public/js/app.js файл с кодовия фрагмент по-долу:

...
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));
  });
}

Тук проверяваме дали браузърът на нашето приложение поддържа обслужващи работници (разбира се, не всички браузъри поддържат обслужващи работници), след което регистрираме нашия файл за обслужващи работници.

Сега стартирайте приложението с командата по-долу:

npm start

Отидете на localhost:8000 в браузъра си, за да получите достъп до приложението.

Проверка на Google Lighthouse

Сега нека проверим дали правилно сме настроили нашия PWA с помощта на проверка на Google Lighthouse. Щракнете с десния бутон върху браузъра си и изберете "проверка". В разделите за проверка изберете фар и щракнете върху генериране на отчет. Ако всичко е минало добре с приложението ви, трябва да видите изход като този на екранната снимка по-долу:

Успешно създадохме първото си приложение. Можете също да спрете сървъра, за да тествате приложението в офлайн режим.

Заключение

Прогресивните уеб приложения (PWA) използват съвременни API, за да осигурят подобрени възможности, надеждност и възможност за инсталиране с една кодова база. Те позволяват на крайния ви потребител да използва приложението ви, независимо дали има интернет връзка или не. Чувствайте се свободни да разклоните хранилището и да добавите допълнителни функции към проекта. Успех!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да прочетете номера на версията от файл с база данни в Android, който е поставен в папка с активи

  2. SQLite заявка:да получите всички колони на ред (android)?

  3. Свързване на таблици с помощта на база данни за стаи в Android Studio

  4. Android – Трябва ли да проверя дали таблицата съществува в SqliteHelper.onCreate()?

  5. listview показва данните от базата данни в android