V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
theprimone
V2EX  ›  程序员

基于 Vite + React 构建 Chrome Extension (MV3) 开发环境

  •  
  •   theprimone ·
    yunsii · 2021-04-18 17:18:11 +08:00 · 1786 次点击
    这是一个创建于 1096 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前言

    此前一直想做一个 bilibili 的弹幕插件,最近借着研究 Vite 的契机实操了一下,花了两天时间算是搭好了基于 Vite + React 的 Chrome Extension (MV3) 开发环境,核心功能如下:

    • 📦️ JS 打包成单文件
    • 🎨 自动引入 CSS
    • 🔨 打包 service worker
    • 🚀 开发环境热更新

    这里重点介绍一下当前热更新的实现,其他功能相对而言简单很多,详情可参考 theprimone/violet

    一次偶然的机会在 B 站看了 《紫罗兰永恒花园》,给人印象深刻,刚好这次打算做个 bilibili 的弹幕插件,索性就取了女主名字中的 violet 😃

    实操

    热更新大致的流程如下图所示:

    hot-reload-flow

    启动

    通过 npm run dev 同时执行三个命令:

    • tsc 编译 service worker 并监听变化
    • vite 编译 extension
    • websocket 服务监听打包后目录 /dist 的变化

    其中,由于 vite build --watch 还未发布,暂时通过自定义脚本监听源码变化,待 vite 该功能发布后可移除。

    热更新

    浏览器页面加载 content scripts 后会创建一个 websocket 链接,服务端收到请求后会开启对 /dist 目录的监听,websocket 服务监听到 /dist 的变化后主动发起通知。

    content scripts 收到需要更新 Extension 的通知,通过 chrome.runtime.sendMessage 触发 service worker 中通过 chrome.runtime.onMessage 注册的事件,依次触发 chrome.runtime.reloadchrome.tabs.reload 更新 Extension 和当前页面。实现了所写即所得,无需任何手动介入 🚀

    可能会有读者有个疑问,为什么不直接在 service worker 中监听 websocket 的通知呢?

    此前一直也是这么想的,在 Manifest V3 下使用 service worker 提倡 Thinking with events,通过 chrome.runtime.onInstalledchrome.runtime.onStartup 创建 websocket 客户端会被意外的关闭,即便是使用定时器轮询也会在执行多次之后被关闭再启动。因此,当前找到的最佳方案是在 service worker 中监听 chrome.runtime.onMessage 事件。

    这样就实现了当页面加载目标插件时才会触发热更新的流程。

    总结

    由于现在的 Chrome Extension 大多是低于 MV3 版本的,两天下来,踩了不少坑,对于此前没有接触过的浏览器插件开发也有了一定程度的了解。现在只是针对 Chrome Extension 的场景,后续会在不断完善当前场景的情况下,完成对其他浏览器插件的支持。最终应该可以封装一个浏览器插件开发的工具。

    第 1 条附言  ·  2021-04-18 21:04:37 +08:00
    ![hot-reload-graph]( https://github.com/theprimone/violet/blob/master/memo/images/chrome-extension-hot-reload.jpg?raw=true)

    重新附图,没想到 V2EX 主题管理这么秀啊 \_(:3J∠)\_
    第 2 条附言  ·  2021-04-18 21:05:49 +08:00

    hot-reload-graph

    啊这,附言默认不是 MD?我太难了

    第 3 条附言  ·  2021-04-20 12:11:52 +08:00

    补充说明:vite build --watch 在 v2.2.0 可用。changelog: v2.1.5...v2.2.0

    第 4 条附言  ·  2021-04-20 22:35:33 +08:00
    第 5 条附言  ·  2021-05-06 17:29:37 +08:00

    [email protected] watch 清空文件夹的问题已合并并发布

    5 条回复    2021-04-18 22:22:10 +08:00
    reiji
        1
    reiji  
       2021-04-18 18:05:31 +08:00   ❤️ 1
    好久没开发 chrome 插件了,感觉又有兴趣了解一下了呢
    监听事件的思想也是第一次知道还有这种原因,学到了
    theprimone
        2
    theprimone  
    OP
       2021-04-18 18:27:01 +08:00
    @reiji 懒人拯救世界,哈哈哈
    justin2018
        3
    justin2018  
       2021-04-18 22:00:29 +08:00
    下次开发插件试一试

    一直以来的做法

    yarn dev -> yarn build -> 浏览器刷新载入 -> yarn dev -> yarn build -> 浏览器刷新载入

    感觉这样 好浪费时间 索性都是小东西~
    theprimone
        4
    theprimone  
    OP
       2021-04-18 22:21:00 +08:00
    @justin2018 这样不就很难受了嘛。我就弄了两个半天,第一个半天我就疯狂手动调试,搞得我头皮发麻。今天废了九牛二虎之力搞定了热更新 😄
    theprimone
        5
    theprimone  
    OP
       2021-04-18 22:22:10 +08:00
    @justin2018 双屏的话可能还好,单屏切得难受死我了 _(:3J∠)_
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   977 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 20:14 · PVG 04:14 · LAX 13:14 · JFK 16:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.