开发一个简单的chrome扩展

发布于 2021-04-17 13:16:44 阅读 15

每天浪费的一分钟都在哪儿?

发现问题

在本人的开发生涯中,我经常会遇到一些非常简单但又耗时的事情,比如大家经常用到的时间戳:由于时间戳都是数字,一般人看不懂,需要转换成人可以看得懂的年月日。由于我是一般人,所以之前我都是这么操作的:

  1. 打开Chrome浏览器
  2. 打开收藏夹,找到之前收藏的时间戳转换的网站(比如站长之家的时间戳转换)
  3. 打开这个时间戳转换的网站
  4. 再把我们需要的时间戳进行输入,然后点击转换。

经过这四个步骤的操作,我们终于将一个时间戳转换成了人可以看懂的时间。上面的时长取决于你的网速、你要打开的转换网站的响应速度,10s-30s不等。

分析与优化

当然,作为一名程序猿。这样的速度我是不能接受的,可不可以优化下上面的流程? 比如第三个步骤,因为外网的网页的打开速度取决于很多因素,这个无解。那么既然外网的网站速度太慢,那么我们就做一个本地的网页,不依赖网络的web应用,也就是今天所要给大家介绍的Chrome扩展。

通过本篇文章,我将带领大家开发出属于自己的Chrome扩展。

介绍+体验Chrome Extension

想必大家都肯定用过chrome扩展,比如熟知ad block。有些同学应该对于上面我说的时间戳的转换的问题应该会笑而不语,因为你们应该都在用FeHelper吧(我猜的),这个chrome扩展包含了很多的常用工具,我之前也用过,但是今天我不是来分享chrome扩展而是让你们也能开发出一款像FeHelper这样的扩展工具。

今天我将用我已经写好的扩展来给大家介绍如何开发扩展。github地址

安装

先将项目克隆下来,然后打开chrome浏览器->More Tools->Extensions->打开developer mode->Load unpacked->选择刚刚克隆下来的项目文件夹即可,此时点击浏览器的上右上方的扩展按钮,就能看到一个”知敏工具“字样的图标了。

111.png

点击图标,就会出现插件(如下图所示)

222.png

目录介绍

333.png

上图就是我们刚刚从git上克隆下来的项目,这个目录结构是被我优化过的,其实一个完整的chrome插件并不依赖这么多文件,chrome会根据manifest.json配置文件读取相应的html和js,然后加载。下面是”知敏工具“的manifest.json的配置。相应的配置的翻译我也写在注释上了。

{
  "name": "知敏工具",//当前扩展的名称
  "description": "This is zhimin chrome extension",//当前扩展的介绍
  "version": "0.0.1",//当前扩展的版本
  "manifest_version": 2,//manifest的版本
  "permissions": [//本扩展需要使用的权限,如果没有在这里写入相应的权限,在使用时则会报错
    "alarms", 
    "tabs", 
    "bookmarks", 
    "contextMenus",
    "declarativeContent",
    "notifications",
    "webRequest",
    "webRequestBlocking", 
    "storage"
  ],
  "background": {
    "page": "background.html"//浏览器打开后就会打开的html页面
  },
  "icons"://扩展的图标
    {
        "16": "src/assets/icon.png",
        "48": "src/assets/icon.png",
        "128": "src/assets/icon.png"
    },
  "content_scripts": [//每打开的网页都会将下面的js插入到网页体内,可以实现定制化的dom等操作
        {
            "matches": ["<all_urls>"],
            "js": ["js/axios.min.js", "js/content_script.js"],
            "run_at": "document_start"
        }
  ],
  "options_page": "options.html",//右键点击扩展图标,点击出现的”options“就会进入这个页面
  "browser_action": {//点击扩展会打开的页面
    "default_icon" : "src/assets/icon.png",
    "default_title": "知敏工具",
    "default_popup": "index.html"
  },
  "homepage_url": "https://github.com/zhimin-dev"//右键点击扩展图标,点击出现的第一个”知敏工具“就会打开此页面
}

其实最终的扩展只需要下面几个文件。

-rw-r--r--    1 meow.zang  staff   238B Nov 12 14:52 background.html
drwxr-xr-x    4 meow.zang  staff   128B Nov  9 13:57 css
-rw-r--r--    1 meow.zang  staff   273B Nov 12 14:05 index.html
drwxr-xr-x    8 meow.zang  staff   256B Nov 16 11:28 js
-rw-r--r--    1 meow.zang  staff   1.1K Nov 12 19:51 manifest.json
-rw-r--r--    1 meow.zang  staff   313B Nov  9 21:27 options.html
drwxr-xr-x    7 meow.zang  staff   224B Nov 16 11:28 src

但是由于原生的html按钮、输入框很丑,所以采用element-ui库来美化界面。

修改扩展

因为本文章是带大家开发属于自己的chrome扩展,所以name肯定不能叫”知敏工具“,那么我们可以先把manifest.json的name改成自己的名字,比如meow.zang,此时保存完成后,chrome是不知道有修改的,所以我们还需要到管理扩展->点击update,提醒chrome更新下manifest.json,此时工具的名字就成了最新的"meow.zang"

444.png

555.png

此时你已经入门了chrome扩展的开发,那么可以将manifest.json的icons和browser_action.default_icon换成你自己的图标,记得update,那么现在你就拥有了你自己的chrome扩展。

开发扩展

在上面我说过,chrome扩展就是一个本地的web网页,那么我们就是开发了一个html的web页面,仅此而已。前端开发这个没有什么好说的。

如果基于我这个扩展开发(使用的vue,are you ok?),那么记得npm操作来一波

npm install
npm run dev (开发 - 测试)
npm run build (生产 - 打完包记得update重新加载manifest.json)

只不过chrome提供了3个入口,每个入口提供的接口、权限都不同,我来简单介绍下。

666.png

本扩展中manifest.json中browser_action.default_popup配置的是index.html,那么点击扩展的图标就会展示index.html的页面,这个页面会根据网页的大小显示宽与高,所以如果你自己开发这个页面,那么设置一个相对合理的宽度比较重要。这个页面和我们使用的web页面一样,浏览器会限制一些操作,比如跨域。

options

777.png

options的页面需要右键扩展图标,然后点击Options才能打开。

888.png

options打开的是一个全屏的html的页面。这个options页面有一个特点,不会受到跨域的限制。如果不收跨域的限制,我们就可以做一些之前干不了的事情。比如我做一个类似postman的请求的应用。

background

background这个比较特殊,它没有界面,它在html浏览器打开的时候就会默认将manifest.json配置的js或者html加载到浏览器中,是随着浏览器的运行而在后台运行的,background也是不受跨域限制,而且background可以使用几乎所有的chrome api,比如chrome的通知的api(记得先在manifest.jsonpermissions添加notifications权限,本插件已经加了,所以直接用下面的代码)保存后记得update。

// js/background.js
chrome.notifications.create(null, {
    type: 'basic',
    iconUrl: '../src/assets/icon.png',
    title: '记得点餐',
    message: '今天还没有点餐,记得抢莎拉!!!'
});

100.png

通过chrome提供的api,我们能做的东西有很多,比如做一个定时喝水提醒?定时站立提醒?等等。

当然我们也可以通过popup页面发送消息给background,然后让popup页面做一些出格的事情。

上面就是manifest.json中三个html的区别,总结来说background最强但无界面,options可以跨域且有界面,popup只有界面,但是popup可以和background打出组合拳实现更🐂的操作。

content_scripts

上面我提到过ad block,这个是屏蔽web广告的,那么你知道这个扩展时如何实现的吗?你想自己写一个屏蔽广告的插件吗?

其实很简单,那就需要使用manifest.json中的content_scripts(本扩展读取的是js/content_script.js),它会将在执行网页的同时调用你的js,然后我们在js中屏蔽广告的dom即可。

比如众所周知,baidu的广告很多,随便输入一个士力架,都是广告,在隐身模式下,没有开本扩展的情况下,百度搜索出来的结果,左右都有广告,对于我来说这都是无效信息,那么我想过滤掉。

11-11.png

当打开我这个扩展后,上图左右两边的红框消失了!!!

12-12.png

其实这不是什么很难的事情,只要打开chrome的审查,找到广告和真正的输出的html有什么区别,拿到不同,然后将广告的去除掉即可。

代码如下:(src/script/content/www.baidu.com.js

setTimeout(() => {
  // 右侧百度热榜
  const rightObj = document.getElementById('content_right');
  if (rightObj !== undefined) { rightObj.remove(); }
  // 左侧广告
  for (let j = 1; j < 10; j += 1) {
    const tempMin = j * 1000;
    const tempMax = tempMin + 20;
    for (let i = tempMin; i < tempMax; i += 1) {
      const pObj = document.getElementById(`${i}`);
      if (pObj !== undefined && pObj !== null) {
        pObj.style.display = 'none !important';
        pObj.remove();
      }
    }
  }
}, 1000);
setInterval(() => {
  // 左侧广告
  const tuiguangPpm = document.getElementsByClassName('EC_ppim_new_gap_bottom');
  for (let i = 0; i < tuiguangPpm.length; i += 1) {
    tuiguangPpm[i].remove();
  }
  const tuiGuangObj = document.getElementsByClassName('ec_tuiguang_pplink');
  for (let i = 0; i < tuiGuangObj.length; i += 1) {
    tuiGuangObj[i].parentNode.parentNode.remove();
  }
}, 10);

上面的代码为什么需要setInterval,是因为百度有轮训机制,如果没有广告会自动加上广告,所以我这边需要加上轮训的机制解决。

当然在本扩展中,我们不需要将代码直接写在js/content_script.js(测试可以先写在这里进行测试),而是需要将你要屏蔽的网站host.js文件放在src/content/下面,上面的baidu的地址就是src/content/www.baidu.com.js 这样有人提交PR的时候只需要重新打包(npm run devnpm run build)就能自动生成js/content_script.js这个文件,还能避免冲突。

总结

通过开发chrome扩展,我确实节省了很多的1分钟,希望也可以节省你的一分钟,欢迎PR,说不定也可以节省别人的一分钟。