React+Antd开发chrome插件教程

1,703 阅读9分钟

💡 为什么是免费试读版?

付费阅读的大环境,一方面很好保护了创作者的知识产权,另一方面提高了创作者的写作动力和内容质量。

本人的文章分为「免费版」和「付费版」。「免费版」主要为短平快的日常经验技巧技术分享,「付费版」篇幅较长,编排更加系统化,内容更加详实。

无论「免费版」和「付费版」,本人都是精心准备,反复验证校对,保证内容质量,坚持做好原创。

如果您对「免费试读版」的内容感兴趣,请关注作者微信公众号「卧梅又闻花」,阅读该付费文章。

❤️原创写作不易,您的支持是对作者最大的支持鼓励❤️

🌷🌷------试读开始------🌷🌷

Chrome浏览器插件众所周知了,我们在使用chrome的时候,或多或少都会安装一些插件以便更高效地开展工作。那么这些插件是怎么开发的呢?官方的教程篇幅不长,难度也不大。但官方教程主要讲解了chrome的开发规范,在jquery早已被抛弃的当今,我们已习惯了react、vue等MVVM模式,本教程将详细讲述如何基于react开发chrome extension。

本次分享Demo的主要依赖包版本:

react 16.13.1

antd 4.2.0

※注:本文代码区域每行开头的“+”表示新增,“-”表示删除,“M”表示修改;代码中的“...”表示省略。

目录 - 先睹为快

先来看看本次分享都包含哪些干货:

1 初始化项目

  • 1.1 使用create-react-app新建项目

  • 1.2 精简项目

2 Chrome Extension基础

  • 2.1 Chrome Extension的组成

  • 2.2 规划build生成的目录结构

  • 2.3 配置manifest.json

3 开发结构设计及build配置

  • 3.1 开发架构设计

  • 3.2 配置webpack

  • 3.2.1 暴露webpack

  • 3.2.2 支持stylus

  • 3.2.3 设置路径别名

  • 3.2.4 设置多入口

  • 3.2.5 固定build生成的文件名

  • 3.2.6 设置popup只引入自己的index.js

4 引入Ant Design

  • 4.1 安装Ant Design

  • 4.2 实现按需加载

5 Popup开发

  • 5.1 安装react-router-dom

  • 5.2 页面构建

  • 5.3 查看popup效果

6 build项目并载入插件

7 background script开发

8 content script开发

  • 8.1 向目标页面注入悬浮球

  • 8.2 使用Ant Design开发content script

  • 8.3 查看content组件效果

9 解决Ant Design样式对目标页面的污染问题

  • 9.1 抽离antd全局reset样式

  • 9.2 content引入抽离的antd-diy样式

  • 9.3 单独引用Ant Design组件的js和css

10 在开发环境调试content script

11 API请求

  • 11.1 准备工作

  • 11.2 使用mock.js模拟请求

  • 11.3 封装axios

  • 11.4 委托background script完成请求

  • 11.5 完成popup的登录请求

  • 11.6 完成content的API请求

  • 11.7 取消mock.js模拟请求

12 其他说明

  • 12.1 permission权限配置

  • 12.2 插入目标页面的js

  • 12.3 背景页调试

  • 12.4 精简最终build文件

13 结语

下面正式开始本次超详细手把手教程!

1 初始化项目

1.1 使用create-react-app新建项目

npx create-react-app react-crx

命令最后的react-crx是项目的名称,可以自行更改。

稍等片刻即可完成安装。安装完成后,可以使用npm或者yarn启动项目。

进入项目目录,并启动项目:

cd react-crx
yarn start  (或者使用npm start)

如果没有安装yarn,可以前往yarn中文网站安装:

yarn.bootcss.com/

启动后,可以通过以下地址访问项目:

http://localhost:3000/

1.2 精简项目

接下来,删除一般项目中用不到的文件,最简化项目。

    ├─ /node_modules
    ├─ package.json
    ├─ /public
    |  ├─ favicon.ico
    |  ├─ index.html
-   |  ├─ logo192.png
-   |  ├─ logo512.png
    |  ├─ mainfest.json
-   |  └─ robots.txt
    ├─ README.md
    ├─ /src
-   |  ├─ App.css
    |  ├─ App.js
-   |  ├─ App.test.js      
-   |  ├─ index.css
-   |  ├─ index.js
-   |  ├─ logo.svg
-   |  ├─ serviceWorker.js
-   |  └─ setupTests.js
    └─ yarn.lock

以上文件删除后,页面会报错。这是因为相应的文件引用已不存在。需要继续修改代码。

现在目录结构如下,清爽许多:

    ├─ /node_modules
    ├─ package.json
    ├─ /public
    |  ├─ favicon.ico
    |  ├─ index.html
    |  └─ manifest.json
    ├─ README.md
    ├─ /src
    |  ├─ App.js
    |  └─ index.js
    └─ yarn.lock

逐个修改以下文件:

src/App.js

import React from 'react'

function App() {
  return (
    <div className="App">
      <h1>This is React App.</h1>
    </div>
  )
}

export default App

src/index.js

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
)

public/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

运行效果如下:

2 Chrome Extension基础

2.1 Chrome Extension的组成

简单来说,开发Chrome Extension主要涉及以下四个部分:

  1. manifest.json (插件配置文件)
  2. popup (点击插件图标弹出的页面)
  3. content script (插入到目标页面中执行的js)
  4. background script (在chrome后台中运行的程序)

【manifest.json】

manifest.json必须放在插件项目根目录,里面包含了插件的各种配置信息,其中也包括了popup、content script、background script等路径。

【popup】

作为一个独立的弹出页面,有自己的html、css、js,可以按照常规项目来开发。

【content script】

content script是驻入到目标页面中执行的js脚本,可以获取目标页面的Dom并进行修改。但是,content script的JavaScript与目标页面是互相隔离的。也就是说,content script与目标页面不会出现互相污染的问题,同时,也不能调用对方的方法。

注意,以上只是js作用域的隔离,通过content script向目标页面加入的DOM会是可以使用目标页面的css,从而造成css互相污染。

【background script】

background script 常驻在浏览器后台运行,没有实际页面(当然也可以通过manifest.json指定一个页面,如果不设置,chrome会自动生成一个),它的生命周期随着浏览器打开而开始,随着浏览器关闭而结束。一般把全局的、需要一直运行的代码放在这里。重要的是,background script的权限非常高,除了可以调用几乎所有Chrome Extension API外,还可以跨域发请求。

2.2 规划build生成的目录结构

在了解Chrome Extension的基本组成后,需要按照Chrome Extension官方开发文档以及manifest.json的要求,按以下结构build最终的目录。

    ├─ favicon.ico         <--这个没有也行,用不到
    ├─ index.html          <--popup入口页面
    ├─ insert.js           <--插入到目标页面执行的js(非必须,视业务需求而定)
    ├─ manifest.json       <--插件的配置文件
    ├─ /static
    |  ├─ /css
    |  |  ├─ content.css   <--content页面样式(会与目标页面互相污染)
    |  |  └─ main.css      <--popup页面样式(不会与目标页面互相污染)
    |  ├─ /js
    |  |  ├─ background.js <--background script
    |  |  ├─ content.js    <--content script
    |  |  └─ main.js       <--popup script
    |  └─ /media           <--项目的图片资源存放目录

接下来就是如何实现build出这样的目录结构。

2.3 配置manifest.json

在开发Chrome Extension之前,要先配置好manifest.json。

public/manifest.json

{
  "name": "Chrome插件Demo",
  "version": "1.0",
  "description": "React开发chrome插件Demo。",
  // 图标,图省事的话,所有尺寸都用一个图也行
  "icons": {
    "16": "images/icon.png",
    "48": "images/icon.png",
    "128": "images/icon.png"
  },
  // manifest.json的文件版本,必须是2
  "manifest_version": 2,
  // popup页面配置
  "page_action": {
    // 浏览器插件按钮的图标
    "default_icon": "images/icon.png",
    // 浏览器插件按钮hover显示的文字
    "default_title": "React CRX",
    // popup页面的路径(根目录为最终build生成的插件包目录)
    "default_popup": "index.html"
  },
  // background script配置
  "background": {
    // background script路径(根目录为最终build生成的插件包目录)
    "scripts": [
      "static/js/background.js"
    ],
    // 官方强烈建议这里为false,乖乖写就行了
    "persistent": false
  },
  // content script配置
  "content_scripts": [
    {
      // 应用于哪些页面地址(可以使用正则,<all_urls>表示匹配所有地址)
      "matches": [
        "<all_urls>"
      ],
      // 注入的css,注意不要污染样式
      "css": [
        "static/css/content.css"
      ],
      // 注入的js
      "js": [
        "static/js/content.js"
      ],
      // 代码注入的时间,可选document_start、document_end、document_idle(默认)
      "run_at": "document_end"
    }
  ],
  // 权限申请(需要background发起跨域请求的url也放在这里)
  "permissions": [
    // 标签
    "tabs",
    // 根据定制的网页规则,采取相应的措施(例如只在baidu.com启动组件)
    "declarativeContent",
    // 插件本地存储
    "storage",
    // 通知
    "notifications"
  ],
  // 如果向目标页面插入js,需要在这里声明下才能获得执行的权限
  "web_accessible_resources": ["insert.js"]
}

manifest的配置项还有很多,可前往官网查阅:

manifest:developer.chrome.com/extensions/…

manifest_version:developer.chrome.com/extensions/…

background script:developer.chrome.com/extensions/…

content script:developer.chrome.com/extensions/…

permissions:developer.chrome.com/extensions/…

3 开发结构设计及build配置

为了实现最终build生成的目录及文件,接下来要做两件事:一是设计好项目的开发目录结构;二是针对build要求修改webpack配置。

3.1 开发架构设计

本文按照以下目录结构进行开发,后续章节的webpack配置也是基于此目录结构。

    ├─ /config              <--配置目录(由eject生成)
    ├─ /public              <--popup入口页面
    |  ├─ /images           <--图片目录
    |  |  ├─ icon.png       <--插件图标
    |  ├─ favicon.ico       <--这个没有也行,用不到
    |  ├─ index.html        <--popup入口页面
    |  ├─ insert.js         <--插入到目标页面执行的js(非必须,视业务需求而定)
    |  ├─ manifest.json     <--插件的配置文件
    ├─ /scripts             <--项目构建运行脚本(由eject生成)
    ├─ /src                 <--开发目录
    |  ├─ /api              <--API公用目录
    |  |  ├─ index.js   
    |  ├─ /background       <--background script开发目录
    |  |  ├─ index.js   
    |  ├─ /common           <--公用资源目录
    |  |  ├─ /js            <--公用js目录
    |  |  └─ /stylus        <--公用样式目录(本demo使用stylus)
    |  ├─ /content          <--content script开发目录
    |  |  ├─ /components    <--content 组件目录
    |  |  ├─ /images        <--content 图片目录
    |  |  ├─ content.styl   <--content 样式
    |  |  └─ index.js       <--content script主文件
    |  ├─ /popup            <--popup开发目录
    |  |  ├─ /pages         <--popup 页面目录
    |  |  ├─ /components    <--popup 组件目录
    |  |  ├─ index.js       <--popup 主文件
    |  ├─ index.js          <--项目主文件,也是popup入口文件
    ├─ pakeage.json

这种目录结构设计,将background script、content script、popup分别建立独立的目录,并且设置了api、common等公用目录,方便多人协作开发,便于后续维护。

【说明】

  1. 由于content是在目标页面的基础上执行,并不是独立的页面,因此不能使用router,无需page目录。

  2. popup是独立的页面,可以按照常规react项目设定相应的目录。

3.2 配置webpack

现在执行yarn build生成的工程是无法被chrome加载的。这是因为在manifest.json里设置了popup、background script、content script的路径,而现在build出来的工程并不符合Chrome Extension的要求,所以需要对webpack进行配置。

🌷🌷------试读结束------🌷🌷

如果您对本次分享感兴趣,请关注我的微信公众号「卧梅又闻花」,继续阅读《React+Antd开发chrome插件教程》。

🎈后续精彩章节-试读结束

3.2.1 暴露webpack

3.2.2 支持stylus

3.2.3 设置路径别名

3.2.4 设置多入口

3.2.5 固定build生成的文件名

3.2.6 设置popup只引入自己的index.js

4 引入Ant Design

4.1 安装Ant Design

4.2 实现按需加载

5 Popup开发

5.1 安装react-router-dom

5.2 页面构建

5.2.1 src/index.js

5.2.2 src/popup/index.js

5.2.3 src/popup/popup.styl

5.2.4 src/popup/pages/login/index.js

5.2.5 src/popup/pages/home/index.js

5.3 查看popup效果

6 build项目并载入插件

7 background script开发

8 content script开发

8.1 向目标页面注入悬浮球

8.2 使用Ant Design开发content script

8.3 查看content组件效果

9 解决Ant Design样式对目标页面的污染问题

9.1 抽离antd全局reset样式

9.2 content引入抽离的antd-diy样式

9.3 单独引用Ant Design组件的js和css

10 在开发环境调试content script

11 API请求

11.1 准备工作

11.2 使用mock.js模拟请求

11.3 封装axios

11.4 委托background script完成请求

11.5 完成popup的登录请求

11.6 完成content的API请求

11.7 取消mock.js模拟请求

12 其他说明

12.1 permission权限配置

12.2 插入目标页面的js

12.3 背景页调试

12.4 精简最终build文件

13 结语

如果您对本次分享感兴趣,请关注我的微信公众号「卧梅又闻花」,继续阅读《React+Antd开发chrome插件教程》。