当你手中只有一把锤子的时候,你就会把所有的问题都看成钉子。

Google Chrome,Google公司开发的一款设计简单、高效的Web浏览器。Chrome不仅页面渲染速度快,Javascript执行速度快,而且更重要的是支持开发者为其编写各种各样的扩展来扩充其功能。

这里将要描述的就是为Chrome编写一个插件:使用当前网页地址生成二维码。

给chrome编写插件还是非常容易的事情,这里会使用到react.js(使用react,仅仅是因为,我最近对它很感兴趣)。

一、新建一个基本React APP

使用create-react-app来新建React应用是一个非常不错的选择。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
$ create-ract-app react-qr

Creating a new React app in /Users/xiaoxiwang/Documents/demo/react-qr.

Installing packages. This might take a couple minutes.
Installing react, react-dom, and react-scripts...

yarn add v0.24.5
info No lockfile found.
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 📃  Building fresh packages...
success Saved lockfile.
success Saved 878 new dependencies.
...

新建完成后生成的文件目录如下:

1
2
3
4
5
6
7
8
➜  react-qr tree -L 1
.
├── README.md
├── node_modules
├── package.json
├── public
├── src
└── yarn.lock

此时,运行命令:

1
2
$ cd react-qr 
$ yarn start

如果顺利将可以在浏览器中,看到一个最简单的Create APP。

清除react-react-app生成的默认样式和内容,为下一步做准备。

二、新建插件

Chrome扩展是用于扩充Chrome浏览器功能的程序,是一系列文件的集合,这些文件包括HTML文件、CSS样式文件、JavaScript脚本文件、图片等静态文件以及manifest.json。扩展被安装后,Chrome就会读取扩展中的manifest.json文件。这个文件的文件名固定为manifest.json,内容是按照一定格式描述的扩展相关信息,如扩展名称、版本、更新地址、请求的权限、扩展的UI界面入口等等

添加插件配置

在public文件夹下新建一个名为manifest.json的文件, 如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
    "manifest_version": 2,
    "name": "QR Code",
    "description": "Generate QR Code",
    "version": "0.1",
    "icons": {
        "16": "./favicon.png",
        "48": "./favicon.png",
        "128": "./favicon.png"
    },
    "browser_action": {
        "default_icon": {
            "19": "./favicon.png",
            "38": "./favicon.png"
        },
        "default_popup": "index.html",
        "default_title": "Generate QRCode"
    },
    "permissions": [
        "activeTab"
    ]
}

上面的配置中,name定义的扩展名称,version定义扩展版本,description定义扩展的描述,icons则定义的扩展使用的图标及其位置。borowser_action指定了扩展在工具栏中的行为,工具栏中的图标(default_icon)、鼠标悬停插件时的标题(default_title)以及用户点击扩展时显示的页面所在位置(deafult_popup)。

添加二维码

qrcode.react是一个生成二维码的React组件。 添加依赖

1
$ yarn add qrcode.react

现在编辑App.js, 添加二维码。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import React, { Component } from 'react';
import './App.css';
import QRCode from 'qrcode.react'

class App extends Component {
  constructor(props) {
    super(props)
    this.state = { url: '' }
  }

  renderStatus(url) {
    this.setState({ url })
  }

  render() {
    const { url } = this.state
    return (
      <div>
        <div>QRCode</div>
        <div className="url">
          {url}
        </div>
        <QRCode value={url} size={270} />
      </div>
    );
  }
}
export default App;

二维码的初始值是为空, 大小为270px。文本显示的URL地址,这里使用了一个样式‘url’,定义在APP.css文件中:

1
2
3
4
5
6
7
8
.url{
  width: 270px;
  text-overflow: ellipsis;
  white-space: pre;
  overflow: hidden;
  font-size: 14px;
  color: #888
}

url宽度设置为270px,超出部分自动使用‘…’替代。

现在生成的二维码是一个空字符串,可以在插件页面渲染成功后,获取当前页面的URL地址。这里会是使用到React的componentDidMount方法,该方法会在页面渲染完成时调用一次,此时的DOM结构都已经渲染完成。为了获取到当前页面的URL,可以使用chrome.tabs.query(object queryIfon, function callback)接口。

1
2
chrome.tabs.query(object queryInfo, function callback)
Gets all tabs that have the specified properties, or all tabs if no properties are specified.

通过查询当前窗口中激活状态的tab,并选取第一个tab,即获取到了当前页面所在chrome tab。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
var queryInfo = {
      active: true,
      currentWindow: true
    }
    
    chrome.tabs.query(queryInfo, (tabs) => {
      const tab = tabs[0]
      const url = tab.url
      this.setState({ url })
    })

获取到当前页面的url后,使用setState更新状态。

打包

运行yarn buid命令,将打包react app,在build文件夹下生成相应输出文件。

1
$ yarn build

此时build,会出现chrome is not defined的错误。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
➜  react-qr yarn build
yarn build v0.24.5
$ react-scripts build
Creating an optimized production build...
Failed to compile.

./src/App.js
  Line 34:  'chrome' is not defined  no-undef

Search for the keywords to learn more about each error.

error Command failed with exit code 1.

因为ESLint无法识别chrome, 可以在App.js文件的第一行添加”/global chrome/“,来告知ESLint将chrome识别为一个全局变量。

1
2
3
4
/*global chrome*/
import React, { Component } from 'react';
import './App.css';
import QRCode from 'qrcode.react'

三、部署

在地址栏中输入”//chrome:extensions”进入chrome插件管理UI, 勾选开发者模式, 并点击“Load upacked extension…“按钮,选择插件的编译输出build目录, 此时就可以在工具栏中,看到一个新增的插件图标,点击这个图标即可生成当前页面地址的二维码。

四、Demo下载地址

Demo

参考