设计和实现一个 Chrome 插件提升登录效率

大家好,我是若川。最近组织了源码共读活动,感兴趣的可以点此加我微信ruochuan12 进群参与,每周大家一起学习200行左右的源码,共同进步。已进行4个月了,很多小伙伴表示收获颇丰。

前言

在我们的工作过程中,每当需要排查问题、跑冒烟用例、看测试环境的效果时,经常需要在浏览器环境中切换登录账号,另外,在开发的过程中,也需要在编辑器 VS Code 里切换代理登录的账号。

以政采云的业务开发为例:访问测试、预发等不同环境要切账号,切换不同角色身份、不同地理区划、甚至查看有特殊数据时也要切账号……这让我们的工作中充斥了大量的输入账号密码的无效时间,也需要我们额外维护账号文档,非常苦恼。

关于在 VS Code 编辑器里快捷切换账号的工具,我们已经有同学设计开发过,在后续的文章中会向大家展示。

37b748b5ddecf94402c3146f8f287b17.png

本文将讲述一下如何在浏览器环境,扩展 Chrome 浏览器原有的“记住密码”功能,实现快捷登录、隔离账号信息以及备注标签等方便使用的功能,同时分享给测试、后端、产品等其他的伙伴,提高大家的效率,希望这次探索能给更多的人带来启发。

需求分析

  • 支持账号录入和一键登录,节约输入时间

  • 对账号进行个性化的 tag 标记,支持增删改查

  • 隔离不同环境下的账号,解决混用的干扰

  • 方便查看和数据维护

  • 友好的 UI 界面

最终效果预览

主要演示一下插件的位置,其中,删除和置顶是常见功能,就不在这里演示了

一键登录

3d0ce0483706e1a0c32d7e9d9dc04bf8.gif

账号录入

b5a3ab4f945e0a4fc3ed39ff4aec95f5.gif

Tag 标记和搜索

0c05ea878e1355adc6b18a0e2b4f335c.gif

弹层里的传送门

传送门编写在 popup/index.html 目录下,用于提供快捷进入不同环境登录页的入口,用颜色清晰地区别开测试、预发等环境,以及记录辅助系统鲁班的地址。

d52951011fa0343d8723b1ead6d3f2d8.png

前期设计

Chrome 扩展程序

既然是代替用户进行浏览器页面的登录,我们当然可以选择 Chrome Extension (扩展程序)(https://developer.chrome.com/docs/extensions/) 来解决这一难题。

扩展是基于 Web 技术构建的,例如 HTML、JavaScript 和 CSS。它们在单独的沙盒执行环境中运行,并与 Chrome 浏览器交互。

扩展允许您通过使用 API 修改浏览器行为和访问 Web 内容来“扩展”浏览器。

Chrome 浏览器将会识别包含 manifest.json 文件的目录为扩展文件,所以我们可以开发一个 Chrome Extension 项目来解决这一问题。

前端技术栈

本次 Chrome 插件选用 React 框架开发,其他开发者也可以根据自己的偏好进行技术选型。

第一版本的插件能力暂时不接入后端,数据都存在本地。

  • 优点

    • 天然实现隔离不同域名环境下的数据,避免了测试、预发等环境混用的缺陷。

    • 如果不手动删除数据,可支持前端长久保存,并随时可以在控制台中查看,分享给其他合作者。

  • 缺点

    • 统一使用者针对不同浏览器访客角色无法实现账号打通的能力,这一缺陷将在下次接入后端时弥补。

    • 清除本地缓存时,会误删数据。

美观的 UI 选型

由于原政采云登录页面是用内部基于 AntD 开发的组件库,为了保持视觉风格的统一,我选择了继续使用我们内部的组件库,每个团队也可以根据自己情况选择自己的组件库,或者开源的组件库,如 ant design,element ui 等。

更便捷的交互设计

既然可以访问 Web 内容,那么最简便的操作就是不用触发任何其他的按钮打开弹层,直接 识别登录页面,在原有登录页面的空白处中 插入我们的组件 DOM 元素,就可以实现最便捷的操作。我们得到一个登录账号列表,不必透出密码,根据我们自己打的标签判断当前需要登录的账号,一键登录,代替手动操作。

c2e72604738294cf60cd5ab58e897dc8.png

项目搭建

我们建一个空项目,配置必要的 .babelrc 、.gitignore、webpack.config.js 文件,使得文件可以支持 Babel、Git、Webpack 的正常使用,安装 Less 以及相关的 loader 方便我们的开发,目录结构大致如下:

目录结构

.├── README.md ├── package-lock.json├── package.json├── src│   ├── assets # 存放扩展程序的标志图片│   ├── contentScript # 对 Web 文件的操作│   ├── manifest.json # Chrome Extension 的清单文件│   └── popup # 用于存放弹出层└── webpack.config.js

清单文件 manifest.json

这里是用来配置扩展程序的基础信息的文件

  • name:扩展名,显示在我的扩展文件中

  • manifest_version:标记 manifest.json 文件的版本号。从 Chrome 18 版本起, manifest_version 需不小于 2, 并且,由于 manifest_version 为 3 的部分语法仅在 Chorme 88 以上支持,Edge、Firefox等其他浏览器都不支持,所以 manifest_version 为 2 是更多扩展程序的选择。

  • icons:扩展程序显示在右上角的图标,需要配置不同规格的图片,适应不同的显示需要。

{"name": "Account Saver","description" : "zcy 账号管理小精灵~", "version": "1.0", "manifest_version": 2, "icons": { "16": "./assets/icon.png", "48": "./assets/icon.png","96": "./assets/icon.png","128": "./assets/icon.png"},"browser_action": {"default_icon": "./assets/icon.png", // 插件加载在浏览器右上角时的图标"default_title": "账号管理小精灵~", // hover 图标的提示文字"default_popup":"/popup.html" // 默认点击图标时弹出的浮层},"permissions": ["tabs","activeTab","storage","notifications"],"background": {"persistent": false,"scripts": ["./background.js"]},"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'","content_scripts": [{"matches": ["http://*/*","https://*/*"],"js": [ // content script 文件"/popupListener.js"],"run_at": "document_idle"}]}

webpack.config.js

如下代码配置 webpack ,可以帮助我们编译打包 HTML、JavaScript 和 Less 编写的样式文件,打包静态资源,执行npm run build 获得打包好的 dist 文件,就可以分享到团队中了。

const path = require('path');const webpack = require('webpack');const CopyWebpackPlugin = require('copy-webpack-plugin');const CleanWebpackPlugin = require('clean-webpack-plugin');const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {mode: 'development',context: path.resolve(__dirname, './src'),entry: {popup: './popup/index.js',background: './background/index.js',popupListener: './contentScript/popupListener.js',},output: {path: path.resolve(__dirname, './dist'),publicPath: '/',filename: '[name].js',},module: {rules: [{test: /\.css$/,use: ['style-loader', 'css-loader'],},{test: /\.less$/,use: ['style-loader','css-loader','less-loader'],},{test: /\.(js|jsx)$/,exclude: /node_modules/,use: {loader: 'babel-loader',options: {babelrc: false,presets: [// 添加 preset-react 识别 react 代码 require.resolve('@babel/preset-react'),require.resolve('@babel/preset-env'),{plugins: ['@babel/plugin-proposal-class-properties'],},],cacheDirectory: true,},},},],},plugins: [new HtmlWebpackPlugin({title: 'popup',template: './popup/index.html',inject: true,chunks: ['popup'],filename: 'popup.html',}),new webpack.HotModuleReplacementPlugin(),new CleanWebpackPlugin(['./dist/', './zip/']),new CopyWebpackPlugin([{ from: 'assets', to: 'assets' },{ from: 'manifest.json', to: 'manifest.json', flatten: true },]),],};

核心代码

Content Script

Content Scripts 是运行在Web页面的上下文的 JavaScript 文件。通过标准的 DOM,Content Scripts 可以操作(读取并修改)浏览器当前访问的Web页面的内容,并将信息传递给父扩展。

插入浮层

在此我们通过原生 JavaScript 的 createElement()append() 方法向 body 中追加元素,插入浮层。

const { domain } = document;const isZcy = domain.indexOf('zcy') !== -1;const userDom = document.getElementsByName('username')[0];if (isZcy && userDom) {// 域名为政采云域名,且存在 name = username 的元素(输入框)时,在页面左侧插入一个浮层const body = document.getElementsByTagName('body')[0];const panelWrapper = document.createElement('div');ReactDOM.render(<AccountPanel />, panelWrapper);body.append(panelWrapper);}

一键登录

Event()

  • 构造函数,创建一个新的事件对象 Event (https://developer.mozilla.org/zh-CN/docs/Web/API/Event)。该方法 IE 浏览器不支持。

event = new Event(typeArg, eventInit);
// typeArg 是DOMString 类型,表示所创建事件的名称。
// eventInit 可选,接受以下字段:
// bubbles 是否支持冒泡,cancelable:能否被取消,composed:事件是否会触发shadow DOM(阴影DOM)根节点之外的事件监听器

target.dispatchEvent(event)

  • 向一个指定的事件目标派发一个事件,从而触发监听函数的执行。该方法返回一个布尔值,只要有一个监听函数调用了 target.dispatchEvent 则返回 false,否则返回 true。

const usernameDom = document.getElementById('username');const passwordDom = document.getElementById('password');const { accountList } = this.state;const { username, password } = accountList.find((item) => item.username === handleUsername);// 未来可能会废弃的写法// const evt = document.createEvent('HTMLEvents');// evt.initEvent('input', true, true);// ie 不支持const evt = new Event('input', { bubbles: true });// 将值填入 dom 输入框里usernameDom.value = username;usernameDom.dispatchEvent(evt);passwordDom.value = password;passwordDom.dispatchEvent(evt);// 模拟用户点击登录按钮const loginBtn = document.getElementsByClassName('login-btn')[0];loginBtn.click();

开发辅助

一键重载:Extensions Reloader

即使 Webpack 配置了热更新,插件打包出来的 JavaScript 代码更新后也是不能热加载的,我们可以访问 chrome://extensions/ 点击下图中的小按钮重新加载,或者安装 Extensions Reloader (https://chrome.google.com/webstore/detail/extensions-reloader/fimgfedafeadlieiabdeeaodndnlbhid?hl=zh-CN) 插件,点击按钮进行重新加载。

084c5098371a8b6eb48d2df65cbbac20.png637d3ac3fb887f272ce0b9f3e4d88c9c.png

安装扩展文件

Chrome 允许安装 Chrome 应用市场本地文件两种来源的扩展文件。访问 chrome://extensions/,打开 开发者模式,点击 加载已解压的扩展程序,就可以选中我们本地的文件了,Edge 等浏览器也可以用。

下一阶段

目标

  • 将数据存储到后端,避免数据丢失问题。

  • 将数据共享到前端 VSCode 插件上,提供给快速本地代理使用。

  • 新增用户登录功能,打通同一使用者访客身份数据共用问题。

  • 隔离业务小组,避免 Tag 混用、全量账号查找不便问题。

  • 一键打开 Chrome 访客身份并登录,同时操作多个账号,方便测试使用。

设计方向:对插件的使用者增加登录功能,登录通过 域账号-密码-业务小组 圈定一个范围,同一个 业务小组共享 测试账号、绑定的业务标签、业务小组关联的应用。前端本地开发时,项目获得的账号通过当前应用所属的业务小组拉取。

63b1ff642ba421f9f382da3c16a21171.png

E-R 图设计

77d543192ca797cd62dba74d4e5ecc4e.png

参考文档

Chrome Developers (https://developer.chrome.com/docs/extensions/mv3/getstarted/)

最近组建了一个湖南人的前端交流群,如果你是湖南人可以加我微信 ruochuan12 私信 湖南 拉你进群。

推荐阅读

整整4个月了,尽全力组织了源码共读活动~
我历时3年才写了10余篇源码文章,但收获了100w+阅读

老姚浅谈:怎么学JavaScript?

我在阿里招前端,该怎么帮你(可进面试群)

3b82f5450fae8fa157102cc0dd4cecc8.gif

················· 若川简介 ·················

你好,我是若川,毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列》10余篇,在知乎、掘金收获超百万阅读。
从2014年起,每年都会写一篇年度总结,已经写了7篇,点击查看年度总结。
同时,最近组织了源码共读活动,帮助1000+前端人学会看源码。公众号愿景:帮助5年内前端人走向前列。

ba7e1c91a2e8306260f72ed62ec50bab.png

识别方二维码加我微信、拉你进源码共读

今日话题

略。分享、收藏、点赞、在看我的文章就是对我最大的支持~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/275162.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

qq空间网页设计_网页设计中的负空间

qq空间网页设计重点 (Top highlight)Because screens are limited, web design is also limited. It can be said that in the small box of the screen, each pixel is a piece of real estate.由于屏幕有限&#xff0c;因此网页设计也受到限制。 可以说&#xff0c;在屏幕的小…

时隔一年半,我,一个卑微的前端菜鸡,又来写面经了

大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以点此加我微信ruochuan12 进群参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。已进行4个月了&#xff0c;很多小伙伴表示收获颇丰。作者&#xff1a;刮涂层_赢大奖原文地址…

用户体验与可用性测试_可用性作为用户体验的原则

用户体验与可用性测试Every UX Designer has his views and best practices. We all have a guide book created through time and experience. I want to share mine with you.每个UX设计器都有他的观点和最佳实践。 我们都有一本通过时间和经验编写的指南。 我想和你分享我的…

Jenkins插件之Deploy

deploy插件&#xff1a; Deploy Plugindeploy插件支持将War/Jar部署到远程的应用服务器上&#xff0c;例如Tomcat,JBoss,Glassfish。正在寻找或开发.NET web 应用的自动发布插件。如何回滚或重新部署先前的build&#xff1a;0&#xff09; 需要被deploy的job的结果要存档&#…

受美国法律保护美国妞_为什么美国法律有效地要求所有软件设计都要响应

受美国法律保护美国妞Smashing Magazine defines “responsive design” as an approach where design responds to the user’s behavior and environment based on screen size, platform, and orientation. In responsive design, a breakpoint is the “point” at which a…

源码群友问:你这么多项目是怎么进行技术选型的?

大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以点此加我微信ruochuan12 进群参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。已进行4个月了&#xff0c;很多小伙伴表示收获颇丰。源码群有群友提问我是怎么找到那么多npm…

iOS开发之打包上传报错: ERROR ITMS-90087/ERROR ITMS-90125

制作好的framework在打包上传至AppStore如果出现以下错误&#xff0c;则说明这个SDK里面包含了x86_64, i386 架构&#xff0c;当然这个AppStore是不允许的&#xff0c;所以会在上传的时候报错&#xff0c;解决办法就是要这个SDK剔除掉x86_64, i386这两个架构 解决办法&#xff…

ios 动画设计_动画和讲故事在设计中的力量

ios 动画设计As human beings, we’ve always been fond of storytelling. Just think of campfire stories, Santa Claus, or that thrilling book you just finished. Here’s how you can use the power of storytelling to make your designs better.作为人类&#xff0c;我…

poj 2696 A Mysterious Function

A Mysterious FunctionTime Limit: 1000MS Memory Limit: 65536KTotal Submissions: 3517 Accepted: 2398Description For any integers p and q with q > 0, define p mod q to be the integer r with 0 < r < q −1 such that p−r is divisible by q. For example,…

面试官:能不能手写一个 Promise?

大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以点此加我微信ruochuan12 进群参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。已进行4个月了&#xff0c;很多小伙伴表示收获颇丰。以下问题你是不是在哪里听过&#xff1f…

设计图像素和开发像素_游戏开发的像素艺术设计

设计图像素和开发像素Pixel art is a large part of the legacy of game development. Every Pokemon game up until their X/Y series was rendered entirely with pixel art, Ragnarok Online (2000) was one of the first commercial works to feature 3D rendering along s…

深入浅出Nintex——更新PeopleandGroup类型的Field

转载于:https://www.cnblogs.com/mingle/archive/2011/11/25/2263199.html

从 vue-cli 源码中,我发现了27行读取 json 文件有趣的 npm 包

1. 前言大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。已进行四个月了&#xff0c;很多小伙伴表示收获颇丰。想学源码&#xff0c;极力推荐订阅我写…

自定义view示例_自定义404页的10个示例(从最佳到最差)

自定义view示例自定义404页面 (Custom 404 pages) To customize or not to customize your 404 page? I hope by now you know the answer is that, yes, under essentially all circumstances you should customize your 404 page. 404 errors occur when someone attempts t…

BTF:实践指南

本文地址&#xff1a;BTF&#xff1a;实践指南 | 深入浅出 eBPF 1. BPF 的常见限制 1.1 调试限制1.2 可移植性2. BTF 是什么&#xff1f;3. BTF 快速入门 3.1 BPF 快速入门3.1 BTF 和 CO-RE4. 结论 BPF 是 Linux 内核中基于寄存器的虚拟机&#xff0c;可安全、高效和事件驱动…

python 混入类MixIn

写在前面 能把一件事情说的那么清楚明白&#xff0c;感谢廖雪峰的官方网站。 1.为什么要用混入类&#xff1f;&#xff08;小白入门&#xff09; 继承是面向对象编程的一个重要的方式&#xff0c;因为通过继承&#xff0c;子类就可以扩展父类的功能。 step1: 回忆一下Animal类层…

估计很多前端都没学过单元测试~

大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。已进行四个月了&#xff0c;很多小伙伴表示收获颇丰。想学源码&#xff0c;极力推荐订阅我写的《学习…

xd可以用ui动效效果吗_通过动画使UI设计栩栩如生:Adobe XD和After Effects

xd可以用ui动效效果吗Note — If you don’t fancy splashing out on an Adobe license, you can trial their products for 14 days each. That should give you more than enough time to play, check it out.注意—如果您不愿意花钱购买Adobe许可证&#xff0c;则可以分别试…

第十二周编程总结

这个作业属于那个课程C语言程序设计II这个作业要求在哪里https://pintia.cn/problem-sets/1127748174659035136/problems/1127749414029729792我在这个课程的目标是更好的学习函数这个作业在那个具体方面帮助我实现目锻炼了我的编程能力参考文献c语言程序设计26-1 计算最长的字…

可能是全网首个前端源码共读活动,诚邀加入学习

大家好&#xff0c;我是若川。从8月份到现在11月结束了。每周一期&#xff0c;一起读200行左右的源码&#xff0c;撰写辅助文章&#xff0c;截止到现在整整4个月了。由写有《学习源码整体架构系列》20余篇的若川【若川视野公众号号主】倾力组织&#xff0c;召集了各大厂对于源码…