使用React写一个简单的Chrome插件
当你手中只有一把锤子的时候,你就会把所有的问题都看成钉子。
Google Chrome,Google公司开发的一款设计简单、高效的Web浏览器。Chrome不仅页面渲染速度快,Javascript执行速度快,而且更重要的是支持开发者为其编写各种各样的扩展来扩充其功能。
这里将要描述的就是为Chrome编写一个插件:使用当前网页地址生成二维码。
给chrome编写插件还是非常容易的事情,这里会使用到react.js(使用react,仅仅是因为,我最近对它很感兴趣)。
一、新建一个基本React APP
使用create-react-app来新建React应用是一个非常不错的选择。
$ 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.
...
新建完成后生成的文件目录如下:
➜ react-qr tree -L 1
.
├── README.md
├── node_modules
├── package.json
├── public
├── src
└── yarn.lock
此时,运行命令:
$ 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的文件, 如下:
{
"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组件。 添加依赖
$ yarn add qrcode.react
现在编辑App.js, 添加二维码。
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文件中:
.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)接口。
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。
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文件夹下生成相应输出文件。
$ yarn build
此时build,会出现chrome is not defined的错误。
➜ 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识别为一个全局变量。
/*global chrome*/
import React, { Component } from "react";
import "./App.css";
import QRCode from "qrcode.react";
三、部署
在地址栏中输入"//chrome:extensions"进入chrome插件管理UI, 勾选开发者模式, 并点击“Load upacked extension…“按钮,选择插件的编译输出build目录, 此时就可以在工具栏中,看到一个新增的插件图标,点击这个图标即可生成当前页面地址的二维码。