上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

教程:如何开发桌面App?PWA也许是你的答案

[复制链接]
  • TA的每日心情
    奋斗
    2025-4-23 20:09
  • 签到天数: 7 天

    [LV.3]偶尔看看II

    13

    主题

    12

    回帖

    268

    积分

    荣誉开发者

    积分
    268

    油中2周年新人报道荣誉开发者

    发表于 2025-4-29 10:28:29 | 显示全部楼层 | 阅读模式

    本帖最后由 溯水流光 于 2025-4-29 10:44 编辑

    文章的下载和备份:

    Gitee: https://gitee.com/HHandHsome/pwa-tutorial

    GitHub: https://github.com/HHsomeHand/pwa-tutorial

    如何快速开发桌面 APP?PWA 也许是你的答案

    本文是上一篇文章《如何快速开发手机 APP?PWA 也许是你的答案》的延续。是其的姊妹篇。

    上一篇我们介绍了 PWA 是什么,分析了它的优缺点,并通过 Vue + Vant + Tailwind 快速搭建了一个手机端 DEMO,并成功部署到 GitHub Pages 上, 还打包为了 apk, 体验了 PWA 的开发流程。

    上篇文章的传送门: https://bbs.tampermonkey.net.cn/thread-8537-1-1.html


    随着 Web 技术的发展,开发一个跨平台的桌面 App 已不再是难事。

    特别是对于前端开发者来说,利用现有技术栈,我们可以迅速搭建出一个桌面 Web App。

    本篇文章将延续上一篇的思路,打造一个桌面端的小工具,并通过 GitHub Actions 自动部署为 GitHub Pages。

    我们会一起完成以下几个步骤:

    1. 使用 Vite 快速初始化 Vue + Tailwind 项目, 并 git init(与上篇相同,不再赘述, 你可以直接 git clone element Plus 的最佳实践, 见下)
    2. 引入 Element Plus 并配置自动按需导入
    3. 开发一个简单的桌面小 Demo
    4. 配置 GitHub Actions 实现 CI/CD 自动部署到 GitHub Pages

    你可以直接 git clone https://github.com/sxzz/element-plus-best-practices.git

    https://github.com/sxzz/element-plus-best-practices 是 Element Plus 的最佳实践

    可以节省很多搭建环境的时间, 你也可以把你常用的模板托管在 Github 上, 这样需要的使用的时候, 再 git clone 就 OK 了!


    一、引入 Element Plus 并配置按需导入

    我们先为项目引入适用于桌面端的 UI 框架 —— Element Plus

    pnpm install element-plus

    文档: https://element-plus.org/zh-CN/guide/installation.html

    为了提升开发效率,我们还需要配置自动导入 Element Plus 的组件和函数:

    pnpm install -D unplugin-vue-components unplugin-auto-import

    文档: https://element-plus.org/zh-CN/guide/quickstart.html

    然后修改 vite.config.js

    // vite.config.js
    import {defineConfig} from 'vite'
    import vue from '@vitejs/plugin-vue'
    import AutoImport from 'unplugin-auto-import/vite'
    import Components from 'unplugin-vue-components/vite'
    import {ElementPlusResolver} from 'unplugin-vue-components/resolvers'
    import tailwindcss from '@tailwindcss/vite'
    
    // https://vite.dev/config/
    export default defineConfig({
        plugins: [
            vue(),
            AutoImport({
                imports: ['vue'],
                resolvers: [ElementPlusResolver()],
            }),
            Components({
                resolvers: [ElementPlusResolver()],
            }),
            tailwindcss(),
        ],
    })
    

    插件说明:

    AutoImport

    该插件可以扫描 <script>.js .ts, 自动导入Element Plus的全局函数

    // 你的代码
    ElMessage.success('Hello')
    
    // AutoImport 自动生成的等效代码
    import { ElMessage } from 'element-plus'
    ElMessage.success('Hello')

    imports: ['vue'],

    这行配置可以让应用程序支持自动导入 vueref watchsetup api函数

    Components

    该插件可以扫描<template>, 自动导入组件

    <template>
      <ElButton>Click me</ElButton>
    </template>
    
    <!-- 原本需要手动 -->
    <script>
    import { ElButton } from 'element-plus'
    
    </script>
    
    <!-- 使用 Components 插件后,自动生成上述代码 -->

    二、开发一个字符分割的小工具

    下面是我们要实现的桌面端小工具:

    102204ezrfpsddrzr3pzrp.png

    功能说明:

    输入一个字符串,如 hzx,输出为字符数组形式:['h', 'z', 'x'],并支持一键复制。

    虽然如今这种字符处理可以交给 AI 来完成(比如豆包),但它仍是个非常合适的练习案例。

    App.vue 核心代码如下:

    <script setup>
    const input = ref("");
    
    const result = ref("");
    
    // 输入"hzx", 输出 "{'h', 'z', 'x'}"
    function splitStringToText(str) {
      let content = str.split('') // "hzx" -> ["h", "z", "x"]
          .map(ch => `'${ch}'`) // ["h", "z", "x"] -> ["'h'", "'z'", "'x'"]
          .join(', ') // ["'h'", "'z'", "'x'"] -> "'h', 'z', 'x'"
    
      return '{' + content + '}';
    }
    
    watch(input, (newValue) => {
      result.value = splitStringToText(newValue);
    }, {immediate: true});
    
    function onCopyBtnClick() {
      copyText(result.value);
    }
    
    /**
     * 复制字符串到剪贴板,并显示提示
     * @param {string} text - 要复制的字符串
     * @returns {Promise<void>}
     */
    async function copyText(text) {
      try {
        // 检查输入是否为字符串且不为空
        if (typeof text !== 'string' || text.trim() === '') {
          throw new Error('输入的文本无效');
        }
    
        // 使用 Clipboard API 复制文本
        await navigator.clipboard.writeText(text);
    
        // 复制成功,显示成功提示
        ElMessage({
          message: '复制成功!',
          type: 'success',
          duration: 2000, // 提示显示2秒
        });
      } catch (error) {
        // 复制失败,显示错误提示
        ElMessage({
          message: '复制失败:' + error.message,
          type: 'error',
          duration: 3000, // 错误提示显示3秒
        });
      }
    }
    </script>
    
    <template>
      <div class="app">
        <div class="app__container">
          <el-input
              v-model="input"
              class="app__input"
              type="textarea"
              autosize
              placeholder="Please input"
          />
    
          <el-input
              v-model="result"
              class="app__input"
              type="textarea"
              readonly
              autosize
          />
    
          <el-button type="primary" @click="onCopyBtnClick">复制!</el-button>
        </div>
      </div>
    </template>
    
    <style scoped>
    @import "tailwindcss";
    
    .app {
      @apply w-screen h-screen flex justify-center items-center;
    }
    
    .app__container {
      @apply flex flex-col gap-3 w-50;
    }
    </style>

    三、GitHub Actions 自动部署到 GitHub Pages

    我们接下来要把项目发布到 GitHub Pages,并实现自动化 CI/CD 流程。

    1. 设置 base

    假设你的项目仓库地址是:

    https://github.com/HHsomeHand/pwa-str-separate

    那么在 vite.config.js 中配置:

    base: '/pwa-str-separate/'

    2. 安装 PWA 插件

    pnpm add -D vite-plugin-pwa

    并添加到 vite.config.js

    import { VitePWA } from 'vite-plugin-pwa'
    
    VitePWA({
      registerType: 'autoUpdate',
      devOptions: {
        enabled: false,
      },
      workbox: {
        globPatterns: ['**/*.{mjs,js,css,html,png,jpg,gif,svg,woff,woff2}'],
      },
      manifest: false
    })

    3. 设置 favicon 和图标

    可以使用 favicon.inbrowser.app 来生成图标, 并记得配置 Start URLicons 路径, 不然部署在 Github Pages 上时, 访问网页, 控制台会报 404, 找不到 PWA 的图标。


    GitHub Actions

    GitHub Actions 是一个自动化工具,它会检测你的仓库中是否存在 .github/workflows/[任意名称].yml 文件。当你将代码推送到远程仓库时,GitHub 会检查是否满足触发条件,如果是, 就会分配一台服务器给你, 来执行:

    • 下载你的代码
    • 运行 pnpm install
    • pnpm build 构建项目
    • 并将结果推送到 gh-pages 分支

    部署完成后,你可以设置仓库的 Github Pages 分支为 gh-pages, 并通过 GitHub Pages 访问你的网站。

    配置工作流

    在仓库中创建文件 .github/workflows/deploy.yml(注意 githubworkflows 拼写不能出错)。文件名可以自定义,没有强制要求。

    以下是 deploy.yml 文件的配置内容:

    name: Deploy to GitHub Pages
    
    on:
      push:
        branches: [main]
    
    jobs:
      build-and-deploy:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout
            uses: actions/checkout@v4
    
          - name: Setup Node.js
            uses: actions/setup-node@v4
            with:
              node-version: '20'
    
          - name: Setup pnpm
            uses: pnpm/action-setup@v2
            with:
              version: 8
    
          - name: Install Dependencies
            run: pnpm install
    
          - name: Build
            run: pnpm build
            env:
              VITE_BASE_URL: /pwa-str-separate/
    
          - name: Deploy
            uses: JamesIves/github-pages-deploy-action@v4
            with:
              branch: gh-pages
              folder: dist
    • ubuntu-latest 是分给你的服务器带的系统
    • Checkout 是下载你的代码
    • Setup Node.js 是安装 Node.js
    • Setup pnpm 是安装 pnpm
    • Install Dependencies 执行 pnpm install
    • Build 执行 pnpm build
    • Deploy 就是将打包结果推送到 gh-pages 分支

    配置 Github Actions 的权限

    我们需要开启 Github Actions 的权限, 使其可以正常读写我们的项目, 并让其可以正常提交内容到我们的gh-pages分支

    102306k7bdsby3jvh32b3t.png

    向下滚动:

    102316tg4kzhab3p6yakf4.png

    推送到远端服务器

    确定 Save保存后, 再git push, 推送我们的代码到服务器, 等 GitHub Actions 构建和部署完毕后, 我们设置 gh-pages 为 GitHub Pages 的展示页面。配置后, 记得点击 Save 保存, 不然配置不会生效。

    102446syalkq3q7ahzmmta.png 102500emd0duy5vv25uxvv.png

    等待几分钟, 访问https://hhsomehand.github.io/pwa-str-separate/, 再保存到桌面就OK了!

    102510ash8hocssws1wovr.png

    后续的开发中,只用执行 git push,GitHub 就会自动为你部署。

    你本地下载好的 PWA APP, 也会因为服务器的更新, 而自动更新, 如果本地没有更新, 请刷新页面并检查网络链接。

    什么是 CI? 什么是 CD?

    CI 是自动打包,如我推送代码到远端git服务器,自动触发GitHub actions,然后帮我打包好了代码。

    CD 是自动部署, 这里自动把代码写入gh-page分支,这就算自动部署了。

    粗糙地理解: CI 完整的名字是"持续集成". “集成”这个词的字面意思,就是合在一起的意思。“把代码合在一起”就是集成,“把代码合在一起” 也可以抽象地理解为 pnpm build, 因为打包也相当于把代码合在一起。CD可以自动把结果部署。


    PWA Builder 打包

    PWA Builder 仅支持打包为MSIX格式,无法生成单体 exe 文件。其需安装后才能运行,类似apk。其实我觉得通过浏览器安装到本地已经够用了, 所以这里就不讲了

    尾声

    感谢你的阅读, 如果遇到问题, 欢迎评论区讨论

    已有1人评分好评 油猫币 贡献 理由
    王一之 + 1 + 4 + 1 赞一个!

    查看全部评分 总评分:好评 +1  油猫币 +4  贡献 +1 

  • TA的每日心情
    开心
    2024-11-21 13:37
  • 签到天数: 213 天

    [LV.7]常住居民III

    308

    主题

    4521

    回帖

    4317

    积分

    管理员

    积分
    4317

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2025-4-29 10:53:48 | 显示全部楼层
    感谢哥哥分享
    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表