跨终端离线前端应用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  徐锅  阅读(1670)  评论(0)    收藏  举报