跨终端离线前端应用PWA项目示例-Vite+Lit+Workbox+Ts

PWA项目示例

enter image description here

性能指标 PWA 原生iOS应用程序
加载速度 相对较慢 快速
响应性能 良好 优秀
功能和访问权限 受限 完全访问
离线访问 支持 需要网络连接
跨平台 支持 不支持
部署灵活性
设备硬件利用 有限 充分利用
用户体验 简化的UI 原生感觉
发布和更新 简便 通过App Store审核发布
安全性 依赖浏览器安全性 应用沙盒保护
推送通知 通过Web Push实现 原生推送通知
第三方集成 有限 丰富的原生库和SDK
性能优化 有限 可以进行更深层次优化

准备物料:

  1. OpenSSL安装包下载;主要介绍Windows 安装openSSL,来实现本地HTTPS服务器。

Mac 和 Linux 实现方式可以参考 openSSL、mkcert。

  1. 环境要求:
    node: v20.5.1
    vite: ^4.4.9

  2. npm install vite-plugin-pwa -D 命令安装 vite-plugin-pwa 插件时,-D 参数的作用是--save-dev。

    • vite-plugin-pwa 是一个用于 Vite 项目的插件,用于添加渐进式网络应用程序(Progressive Web App,PWA)的支持。它提供了一组功能,用于生成 PWA 所需的 Web App Manifest 文件、Service Worker 和缓存策略。
  3. 配置示例:

  • manifest:PWA 清单配置,用于定义应用程序的名称、简称、描述、主题颜色和图标等信息。
  • shortcuts:快捷方式配置,用于定义应用程序的快捷方式,包括名称、简称、描述、URL 和图标等信息。
  • registerType:注册类型配置,用于指定 PWA 的注册方式。这里设置为 'autoUpdate',表示自动更新注册方式。
  • devOptions:开发选项配置,用于指定开发环境下的插件选项。这里设置为 enabled: true,表示在开发模式下启用插件。
  • workbox:Workbox 配置,用于定义 Service Worker 的缓存策略。这里设置了 globPatterns,用于匹配需要缓存的文件类型。

这些配置将插件应用于 Vite 构建过程中,以生成符合 PWA 规范的输出

样板示例注释配置详解:

import { defineConfig } from 'vite';
import { VitePWA } from 'vite-plugin-pwa';

export default defineConfig({
  plugins: [
    /**
     * VitePWA 插件配置
     */
    VitePWA({
      manifest: {
        name: 'My PWA', // 应用程序名称
        short_name: 'My App', // 应用程序简称
        description: 'My Progressive Web App', // 应用程序描述
        theme_color: '#ffffff', // 主题颜色
        icons: [
          // 应用程序图标配置
          {
            src: '/icons/icon-192x192.png', // 图标路径
            sizes: '192x192', // 图标尺寸
            type: 'image/png', // 图标类型
          },
          {
            src: '/icons/icon-512x512.png',
            sizes: '512x512',
            type: 'image/png',
          },
        ],
      },
      shortcuts: [
        // 快捷方式配置
        {
          name: '快捷方式名称', 
          short_name: '快捷方式简称', 
          description: '快捷方式描述',
          url: '/about', // 快捷方式链接地址
          icons: [{ src: '/icons/about-icon.png', sizes: '192x192' }], // 快捷方式图标配置
        },
        {
          name: 'Report issue',
          short_name: 'Report',
          description: 'Open the issue report page',
          url: '/report',
          icons: [{ src: '/icons/report-icon.png', sizes: '192x192' }],
        },
      ],
      registerType: 'autoUpdate', // 注册类型配置
      devOptions: {
        enabled: true, // 开发选项配置,启用插件
      },
      workbox: {
        globPatterns: ['**/*.{js,css,html,ico,png,svg}'], // Workbox 缓存策略配置
      },
    }),
  ],
});

一、示例运行流程

1,创建项目

1, npm init vue@latest

按个人习惯启用 TypeScript、JSX、Vue Router、Pinna、ESLint、Prettier

2,npm i

3, npm i vite-plugin-pwa -D

2,修改配置

修改 vite.config.ts 文件;

import { fileURLToPath, URL } from "node:url";

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";
import { VitePWA } from "vite-plugin-pwa";

export default defineConfig({
  plugins: [
    vue(),
    vueJsx(),
    /**
     * VitePWA 插件配置
     */
    VitePWA({
      manifest: {
        name: "xuguo PWA示例", // 应用程序名称
        description: "xuguo 示例", // 应用程序描述
        theme_color: "#00bd7e", // 主题颜色
        icons: [
          // 应用程序图标配置
          {
            src: "/12.png", // 图标路径
            sizes: "192x192", // 图标尺寸
            type: "image/png", // 图标类型
          },
          {
            src: "/12.png",
            sizes: "512x512",
            type: "image/png",
          },
          {
            src: "/12.png",
            sizes: "60x60",
            type: "image/png",
          },
        ],
      },
      shortcuts: [
        // 快捷方式配置
        {
          name: "Open About", // 快捷方式名称
          short_name: "About", // 快捷方式简称
          description: "Open the about page", // 快捷方式描述
          url: "/about", // 快捷方式链接地址
          icons: [{ src: "/12.png", sizes: "192x192" }], // 快捷方式图标配置
        },
        {
          name: "Report issue",
          short_name: "Report",
          description: "Open the issue report page",
          url: "/report",
          icons: [{ src: "/12.png", sizes: "192x192" }],
        },
      ],

      registerType: "autoUpdate", // 注册类型配置
      devOptions: {
        enabled: true, // 开发选项配置,启用插件
      },
      workbox: {
        globPatterns: ["**/*.{js,css,html,ico,png,svg}"], // Workbox 缓存策略配置
      },
    }),
  ],
  resolve: {
    alias: {
      "@": fileURLToPath(new URL("./src", import.meta.url)), // 设置别名
    },
  },
});

3,配置本地Https

在openSSL安装目录执行命令;否则会报 not found openssl.cnf。

1. 生成私钥文件 (`private-key.pem`):
./openssl.exe genpkey -algorithm RSA -out private-key.pem
2. 创建证书签名请求文件 (`certificate-signing-request.csr`):
 ./openssl.exe req -new -key private-key.pem -out certificate-signing-request.csr
3. 签署证书 (`certificate.crt`):
./openssl.exe x509 -req -days 365 -in certificate-signing-request.csr -signkey private-key.pem -out certificate.crt

生成证书放入项目public文件夹内。

4, 运行项目

1. 打包:
npm run build
2. 运行服务:
npx http-server dist --ssl --cert public/certificate.crt --key public/private-key.pem

enter image description here
npx http-server dist npx 命令不需要安装 http-server 即可执行,把 dist 为服务器访问目录。

5, 访问

enter image description here

二、 其它实现

1,pwa-starter。这个项目可以非Https的环境下运行PWA安装

链接:https://caiyun.139.com/m/i?105CpNjMPcvLs
提取码:coh4
下载文件执行命令:yarn dev.

2, 文件引入

(1,根目录加入 service-worker.js

// 定义要缓存的静态资源
const cacheName = 'my-pwa-cache';
const staticAssets = [
  '/',
  '/index.html',
  '/styles.css',
  '/script.js',
  '/images/logo.png'
];

// 安装 Service Worker
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(cacheName)
      .then((cache) => {
        // 将静态资源添加到缓存
        cache.addAll(staticAssets);
      })
  );
});

// 激活 Service Worker
self.addEventListener('activate', (event) => {
  // 清理旧的缓存
  event.waitUntil(
    caches.keys()
      .then((cacheNames) => {
        return Promise.all(
          cacheNames.filter((name) => {
            return name !== cacheName;
          }).map((name) => {
            return caches.delete(name);
          })
        );
      })
  );
});

// 拦截网络请求并返回缓存的资源
self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then((response) => {
        return response || fetch(event.request);
      })
  );
});

(2,根目录加入manifest.json

{
    "name": "My PWA",
    "short_name": "PWA",
    "description": "This is my Progressive Web App",
    "start_url": "/",
    "display": "standalone",
    "background_color": "#ffffff",
    "theme_color": "#3367D6",
    "icons": [
      {
        "src": "/images/icons/192x192.png",
        "sizes": "192x192",
        "type": "image/png"
      },
      {
        "src": "/images/icons/512x512.png",
        "sizes": "512x512",
        "type": "image/png"
      }
    ]
  }

(3,载入Html link Script

        <link rel="manifest" href="/manifest.json" />
        <link rel="icon" type="image/png" sizes="192x192" href="/images/icons/192x192.png">
        <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png">
          <script>
            if ('serviceWorker' in navigator) {
              window.addEventListener('load', () => {
                navigator.serviceWorker.register('/service-worker.js')
                  .then((registration) => {
                    console.log('Service Worker registered successfully:', registration);
                  })
                  .catch((error) => {
                    console.log('Service Worker registration failed:', error);
                  });
              });
            }
          </script>

(4,运行命令,查看结果:

npx clear-npx-cache ; npx http-server .

posted @ 2023-09-18 21:18  徐锅  阅读(1081)  评论(0编辑  收藏  举报