Incomplete guide to chrome plug-in development

Angel's ass 2021-09-15 09:39:58

background

Recently, the team is building a visual buried point platform , We need to use Chrome The technology of plug-in realizes the function of clicking page elements , So I began to explore Chrome Technologies related to plug-in development .

On the other hand , To complete the front-end skill tree , Learning to develop Chrome Plug ins are one of the most important branches .

This article will summarize the common API Usage of , And use some examples to help you get started Chrome Plug-in development .

Preface

Chrome What is a plug-in ?

Website to explain :

What are extensions

Chrome The plug-in is based on Web technology , Just know JS/CSS/HTML Start developing .

Chrome The plug-in runs in a separate sandbox execution environment , Can be directly related to Chrome Browsers interact , for example : Modify network request 、 Operations tab 、 Read Cookies wait .

By using Chrome Plug in technology customizes the functions that users need , Including but not limited to :

  • Productivity tools
  • Enrich the functions of web pages
  • Information / Interface aggregation
  • Game development

Two links recommended by the official website , About the preliminary understanding Chrome plug-in unit :

To Development and debugging This section will introduce the complete plug-in development and debugging process .

Text

Chrome The key to plug-ins

The website links :

Manifest file format

manifest.json

manifest.json File is Chrome The key to plug-ins , We can read a lot of important information from the file , Here are Manifest V2 The content of , Including but not limited to .

{
// Required fields 
"manifest_version": 3, // Appoint manifest Field Version 2 perhaps Version 3.
"name": "My Extension", // The plugin name .
"version": "versionString", // Version number of the plug-in .
// Common field 
// Manifest V3
"action": {...}, // Toolbar icons , Corresponding API:chrome.action.
// Manifest V2
"browser_action": { … }, // Toolbar icons , Corresponding API:chrome.browserAction.
"page_action": { … }, // Toolbar icons , Corresponding API:chrome.pageAction.
"default_locale": "en", // 
"description": "A plain text description", // Plug-in description , Expand the page in the browser (chrome://extensions/) Can see .
"icons": {...}, // Plug in management page 、 Permission warnings and favicon, Support 128*128,48*48,16*16 The resolution of the .
// Optional fields 
"background": { // Use service_worker Background worker thread , You can listen for browser events here : Navigate to a new page 、 Remove the bookmark 、 Close tabs, etc .
// Required
"service_worker":
},
"content_scripts": [{...}], // A script that runs in the context of a web page , You can call... Here DOM API, Change of operation page, etc .
"devtools_page": "devtools.html", // It can be for chrome devtools Add functionality 
"event_rules": [{...}], // Configure some rules , According to the content of the page / Act differently 
"minimum_chrome_version": "versionString", // Support the minimum version 
"optional_permissions": ["tabs"],
"options_page": "options.html", // You can provide an options page , Customize the behavior of the plug-in , A new page opens 
"options_ui": { // Same as options_page, What opens is a pop-up page 
"chrome_style": true,
"page": "options.html"
},
"permissions": ["tabs"], // You need to request permission from the browser 
"update_url": "http://path/to/updateInfo.xml", // The plug-in automatically updates the policy 
"web_accessible_resources": [...] // Configure network resources 
}
 Copy code 

The main introduction of the field

action、page_action、browser_action

The website links :

action

page_action

brower_action

Configure the properties of the plug-in icon in the toolbar :

  • default_icon Icon image
  • default_popup Operation page
  • default_title Tips when hovering the mouse
// Manifest V2
// manifest.json
{
"browser_action": { … },
"page_action": { … }
}
// background.js
chrome.browserAction.onClicked.addListener(tab => { … });
chrome.pageAction.onClicked.addListener(tab => { … });
// Manifest V3
// manifest.json
{
"action": { … }
}
// background.js
chrome.action.onClicked.addListener(tab => { … });
 Copy code 

Through the corresponding API, Dynamic setting / obtain IconTitlePopup, Custom trigger Popup Show and hide .

usage :chrome.browserAction.*

background

The website links :

background

background It can be understood as a plug-in backstage ( Running programs in the background , Or background management page ), Is the longest running program .

To configure persistent: false, So that the background can be loaded when needed , Unloaded when idle . Such as the first installation 、 Plug in update 、 When the event monitored in the background is triggered 、content script Send it a message 、 stay Popup Call in runtime.getBackgroundPage

Can pass chrome-extension://xxx/background.html Open the background page directly , And debug its code .

By means of manifest.json To configure background Field , Configure the daemon .

// Direct configuration scripts
{
"background": {
"scripts": ["background.js"], // Array 
"persistent": false
},
}
// To configure a page, adopt script Tag load the required script :background.js
{
"background": {
"page": "background.html"
},
}
 Copy code 

Add listening in the daemon .

chrome.runtime.onInstalled.addListener(function(){})
// This will run when a bookmark is created.
chrome.bookmarks.onCreated.addListener(function() {});
 Copy code 

All listening Events , Please register in the synchronization code , If you write in asynchronous code, the registration will not take effect .

chrome.runtime.onInstalled.addListener(function() {
// ERROR! Events must be registered synchronously from the start of
// the page.
chrome.bookmarks.onCreated.addListener(function() {
// do something
});
});
 Copy code 

In some cases , Users don't want to listen to all tabs , So the plug-in allows users to filter listening Events .

chrome.webNavigation.onCompleted.addListener(function() {
alert("This is my favorite website!");
}, {url: [{urlMatches : 'https://www.google.com/'}]});
 Copy code 

By monitoring onSuspend event , Prevent the daemon from uninstalling , Cause data loss , Or do some cleaning before uninstalling , For example, log off the long connected port .

chrome.runtime.onSuspend.addListener(function() {
console.log("Unloading.");
chrome.browserAction.setBadgeText({text: ""});
});
 Copy code 

content_scripts

The website links :

content scripts

Script that runs in the context of the current page , Can be operated directly DOM object , Without conflict with the page script .

content_scripts Can be called directly Chrome API:

Other API Can't call... Directly , Need to pass through Message communication The way you send it , Let the plug-in program return the result by message .

Static injection

Static injection means , Use manifest.json The configuration file fields are defined in a way content scripts.

{
"content_scripts": [
{
"js": [
"/js/vapi.js",
"/js/vapi-client.js",
"/js/contentscript.js"
],
"matches": [
"http://*/*",
"https://*/*"
],
"run_at": "document_start"
}
],
}
 Copy code 

Custom field :

  • matches: Mandatory , Specify which pages (URL) Before you can inject this script . Similar to that exclude_matches.

  • css: Optional , Inject css The style file .

  • js: Optional , Inject js Script files .

  • run_at: Optional , Specify when the content script loads . You can specify :

    • document_idle, The default value is . It means that document_end And window.onload After the event Between . stay document_idle Listen in the running script window.onload It won't work .
    • document_start, It means that CSS After the parsing ,DOM Build and Script Before execution .
    • document_end, It means that DOM After building ,img、frame Before loading .
  • all_frames: Optional .

    • true Indicates that the content script will be injected into all pages of the current tab frames( At the same time, we need to satisfy URL requirement ).
    • false Will only be injected into the top layer frame.

Dynamic Injection

In Dynamic Injection content-script front , Need to be in manifast.json Add activeTab jurisdiction , Enables content scripts to run in the context of the currently active tab , Without specifying cross domain permissions .

{
...
"permissions": [
"activeTab"
],
...
}
 Copy code 

Not specified activeTab Call dynamic injection when permissions are API when , The following errors will be reported :

exexecuteScript-error.png

Dynamically inject script code 、 Sample code of script file :

chrome.runtime.onMessage.addListener(
function(message, callback) {
if (message == "executeScript"){
// Inject script code 
chrome.tabs.executeScript({
code: 'document.body.style.backgroundColor="orange"'
});
// Injection script file 
chrome.tabs.executeScript({
file: 'contentScript.js'
});
}
});
 Copy code 

devtools_page

The website links :

devtools_page

Can be configured by devtools_page Field , enhance Chrome Devtools The ability of . Similar to what we see on the console networksource Isoplane sheet . And you can see this panel in the console under all tabs .

For configuration devtools_page Field plug-in , It can be called a developer tool plug-in (DevTools extensions).

The developer tool plug-in can directly access DevTools APIs:

Besides ,DevTools page Generally, you cannot directly call other API, except chrome.extension.*chrome.runtime.*, So we need to communicate by message , Give Way background The page returns the calculated result to .

This is the official website backgroundcontent-scriptdevtool-page A diagram of the relationship between :

devtools-page.png

Custom developer panel related code :

devtools-panel-sidebar.png

1、 Add panels js / devtools.js

chrome.devtools.panels.create("My Panel",
null,
"panel.html",
function (panel) {
// code invoked on panel creation
}
);
 Copy code 

2、 Add sidebar js / devtools.js

chrome.devtools.panels.elements.createSidebarPane("My Sidebar",
function (sidebar) {
// sidebar initialization code here
sidebar.setPage("sidebar.html"); // Set up a page 
sidebar.setHeight("8ex");
}
);
 Copy code 

options_page、options_ui

The website links :

Give users options

Users can customize the configuration page for plug-ins , The configuration page can be accessed through Right click Plug in Icon , And then click Options open option page. If the plug-in is not configured options_pageoptions_ui Field , This option will be grayed out directly .

perhaps , adopt chrome://extensions Enter the plug-in details , Find and click Extender options open .

Usually , You can use the configuration page , Manage some background data 、 User interaction habits and other data , combination storage.sync API Use it together .

click-option-page.png

1、 Open as a page option page

manifest.json

{
"options_page": "options.html"
}
 Copy code 

2、 Open... In a pop-up mode option page

manifest.json

{
"options_ui": {
"page": "options.html",
"open_in_tab": false
}
}
 Copy code 

3、 Use Chrome API open option page

Open form , Will be based on options_page still options_ui decision . If there is no configuration , The plug-in will report the following error : Unchecked runtime.lastError: Could not create an options page.

(async () => {
chrome.runtime.onMessage.addListener(
function (message, callback) {
console.log('onMessage', message);=
} else if (message == 'optionPage') {
if (chrome.runtime.openOptionsPage) {
chrome.runtime.openOptionsPage();
} else {
window.open(chrome.runtime.getURL('options.html'));
}
}
});
})();
 Copy code 

update_url

The website links :

Autoupdating

Plug in updates can be implemented in two ways :

1、 Use Chrome Plug in platform hosting , Release the updated version through the platform , Update the plug-in .

2、 By designation update_url Field , With the browser's automatic check update mechanism ( Every few hours ), Pull xml detailed list , Decide whether to update the latest version .

It's a pity , I failed to debug locally , According to the Internet ,Chrome The update mechanism does not recognize the local file service ( Not the same as the port number 80 of ), If you are interested, you can explore for yourself .

The main API Introduce

chrome.action、chrome.pageAction、chrome.browserAction

These three API It is the same as the plug-in on the right side of the browser address bar icon of , But it's not exactly the same thing .

The relationship between the three can use a statement on the official website :

The chrome.action API replaced the browserAction and pageAction APIs in Manifest V3. By default, actions are similar to browser actions, but it is possible to emulate the behavior of a page action using the action API.

stay Manifest V3 in , Use chrome.action Instead of V2 The other two in API. chrome.action More like chrome.browserAction, meanwhile , have access to chrome.action simulation chrome.browserAction Ability in .

chrome.pageAction And chrome.browserAction The difference is :

browserAction In the name of icon In the form of , In all tabs , The behavior is the same . and pageAction Is usually used for some url/tab To show icon Scene .

chrome.browserAction relevant API

  • Methods
    • disable − browserAction.disable(integer tabId)
    • enable − browserAction.enable(integer tabId)
    • getBadgeBackgroundColor − browserAction.getBadgeBackgroundColor(object details, function callback)
    • getBadgeText − browserAction.getBadgeText(object details, function callback)
    • getPopup1 − browserAction.getPopup(object details, function callback)
    • getTitle1 − browserAction.getTitle(object details, function callback)
    • setBadgeBackgroundColor − browserAction.setBadgeBackgroundColor(object details)
    • setBadgeText − browserAction.setBadgeText(object details)
    • setIcon1 − browserAction.setIcon(object details, function callback)
    • setPopup1 − browserAction.setPopup(object details)
    • setTitle1 − browserAction.setTitle(object details)
  • Events
    • onClicked1

chrome.pageAction relevant API

  • Methods
    • getPopup1 − pageAction.getPopup(object details, function callback)
    • getTitle1 − pageAction.getTitle(object details, function callback)
    • hide − chrome.pageAction.hide(integer tabId)
    • setIcon1 − pageAction.setIcon(object details, function callback)
    • setPopup1 − pageAction.setPopup(object details)
    • setTitle1 − pageAction.setTitle(object details)
    • show − pageAction.show(integer tabId)
  • Events
    • onClicked1

chrome.runtime

chrome.runtime API Allow users to get the background program page 、manifest Information 、 Achieve message communication 、 Plug in life cycle, etc , Including but not limited to the following capabilities :

Message passing ( Commonly used )

Realization Message communication , Include connect, connectNative, sendMessage, and sendNativeMessage.

Accessing extension and platform metadata

obtain Background page ,manifest To configure , Platform parameters, etc , Include getBackgroundPage, getManifest, getPackageDirectoryEntry, and getPlatformInfo.

Managing extension lifecycle and options

Reload plug-ins , Perform an immediate update check , control option Page display, etc , Include reload, requestUpdateCheck, setUninstallURL, and openOptionsPage.

Device restart support

Restart the plug-in , But only in Chrome OS Effective on the system , Include restart, restartAfterDelay.

Helper utilities

Other tool functions , Include getURL.

of API

  • Methods
    • connect - connect(extensionId, connectInfo)
    • connectNative - connectNative(application)
    • getBackgroundPage - getBackgroundPage(callback)
    • getManifest - getManifest()
    • getPackageDirectoryEntry - getPackageDirectoryEntry(callback)
    • getPlatformInfo - getPlatformInfo(callback)
    • getURL - getURL(path)
    • openOptionsPage - openOptionsPage(callback)
    • reload - reload()
    • requestUpdateCheck - requestUpdateCheck(callback)
    • restart - restart()
    • restartAfterDelay - restartAfterDelay(seconds, callback)
    • sendMessage - sendMessage(extensionId, message, options, responseCallback)
    • sendNativeMessage - sendNativeMessage(application, message, responseCallback)
    • setUninstallURL - setUninstallURL(url, callback)
  • Events
    • onBrowserUpdateAvailable
    • onConnect
    • onConnectExternal
    • onConnectNative
    • onInstalled
    • onMessage
    • onMessageExternal
    • onRestartRequired
    • onStartup
    • onSuspend
    • onSuspendCanceled
    • onUpdateAvailable

chrome.tabs

chrome.tabs API Allow users to create new 、 edit 、 Rearrange tab , And get tab information .

The action tab needs to be in manife.json Apply for tabs jurisdiction :"permissions": [ "tabs" ].

of API

  • Methods
    • captureVisibleTab - captureVisibleTab(windowId, options, callback)
    • connect - connect(tabId, connectInfo, callback)
    • create - create(createProperties, callback)
    • detectLanguage - detectLanguage(tabId, callback)
    • discard - discard(tabId, callback)
    • duplicate - duplicate(tabId, callback)
    • executeScript - executeScript(tabId, details, callback)
    • get - get(tabId, callback)
    • getAllInWindow - getAllInWindow(windowId, callback)
    • getCurrent - getCurrent(callback)
    • getSelected - getSelected(windowId, callback)
    • getZoom - getZoom(tabId, callback)
    • getZoomSettings - getZoomSettings(tabId, callback)
    • goBack - goBack(tabId, callback)
    • goForward - goForward(tabId, callback)
    • group - group(options, callback)
    • highlight - highlight(highlightInfo, callback)
    • insertCSS - insertCSS(tabId, details, callback)
    • move - move(tabIds, moveProperties, callback)
    • query - query(queryInfo, callback)
    • reload - reload(tabId, reloadProperties, callback)
    • remove - remove(tabIds, callback)
    • removeCSS - removeCSS(tabId, details, callback)
    • sendMessage - sendMessage(tabId, message, options, responseCallback)
    • sendRequest - sendRequest(tabId, request, responseCallback)
    • setZoom - setZoom(tabId, zoomFactor, callback)
    • setZoomSettings - setZoomSettings(tabId, zoomSettings, callback)
    • ungroup - ungroup(tabIds, callback)
    • update - update(tabId, updateProperties, callback)
  • Events
    • onActivated
    • onActiveChanged
    • onAttached
    • onCreated
    • onDetached
    • onHighlightChanged
    • onHighlighted
    • onMoved
    • onRemoved
    • onReplaced
    • onSelectionChanged
    • onUpdated
    • onZoomChange

chrome.contextMenus

Generally, this is only used when you need to add some menus to the right-click panel API, You need to apply for permission to operate the right-click menu panel :"permissions": [ "contextMenus" ].

of API

  • Methods

    • create - create(createProperties, callback)
    • remove - remove(menuItemId, callback)
    • removeAll - removeAll(callback)
    • update - update(id, updateProperties, callback)
  • Events

  • onClicked

Message communication

The communication between the extender and the content script uses message passing . Both sides can listen to messages from the other side , And respond through the same channel . The message can contain any valid JSON object (null、boolean、number、string、array or object).

Short link

Mainly runtime.sendMessage or tabs.sendMessage Method .

1、 The sender

stay Content script Send request in , Or from add-in towards Content script Send a request .

chrome.runtime.sendMessage({greeting: " Hello! "}, function(response) {
console.log(response.farewell);
});
 Copy code 

towards Specify tabs Send a request in the script .

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {greeting: " Hello! "}, function(response) {
console.log(response.farewell);
});
});
 Copy code 

2、 The receiving party

chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab
" From content scripts :" + sender.tab.url :
" From the extender ");
if (request.greeting == " Hello! ")
sendResponse({farewell: " bye "});
});
 Copy code 

A long connection

Mainly runtime.connect or tabs.connect Method .

1、 The sender

stay Content script Send request in , Or from add-in towards Content script Send a request .

Once the connection is established , Both ends will get a runtime.Port object , It is used to send and receive messages through the established connection .

var port = chrome.runtime.connect({name: " Knock at the door "});
port.postMessage({joke: " Knock at the door "}); // Send a message 
port.onMessage.addListener(function(msg) { // receive messages 
if (msg.question == " Who is it? ?")
port.postMessage({answer: " ma'am "});
else if (msg.question == " Which lady ?")
port.postMessage({answer: "Bovary ma'am "});
});
 Copy code 

towards Specify tabs Send a request in the script , Use tabs.connect Replace the above runtime.connect.

2、 The receiving party

Set up a runtime.onConnect Event listener , Listen for sender calls connect after , Establish a connection and get a runtime.Port object .

chrome.runtime.onConnect.addListener(function(port) {
console.assert(port.name == " Knock at the door ");
port.onMessage.addListener(function(msg) {
if (msg.joke == " Knock at the door ")
port.postMessage({question: " Who is it? ?"});
else if (msg.answer == " ma'am ")
port.postMessage({question: " Which lady ?"});
else if (msg.answer == "Bovary ma'am ")
port.postMessage({question: " I didn't hear you clearly ."});
});
});
 Copy code 

3、 disconnect

One end monitors runtime.Port.onDisconnect event , When the other end of the connection calls runtime.Port.disconnect Or the page containing the port has ended ( For example, the tab goes to another page ) when , Ensure that this event occurs once for each port .

Non plug-in pages send messages to content scripts

Inner.html

document.getElementById("theButton").addEventListener("click",
function() {
window.postMessage({ type: "FROM_PAGE", text: "Hello from the webpage!" }, "*");
}, false);
 Copy code 

contentScript.js

var port = chrome.runtime.connect();
window.addEventListener("message", function(event) {
// We only accept messages from ourselves
if (event.source != window)
return;
if (event.data.type && (event.data.type == "FROM_PAGE")) {
console.log("Content script received: " + event.data.text);
port.postMessage(event.data.text);
}
}, false);
 Copy code 

Development and debugging

The website links :

Getting started

Debugging extensions

Preparation before development

  1. Open the extended management page through navigation :chrome://extensions

    • You can also click Chrome menu , Hover the mouse over “ More tools ” On , And then choose ” add-in ” Open up “ Extension management ” page .
  2. By clicking Developer model The next toggle switch is enabled .

  3. single click Load the unzipped extender Button and select the extended Directory .

  4. If you modify the local code , By clicking on Refresh Icon button , Reload plug-ins .

open-chrome-extensions.png

Create project (React)

Chrome The development of plug-ins can directly use native tools JS, But using native to write interactive events is really a headache .

therefore , The construction of this project is based on React + Antd As a basic technology .

  1. initialization npm
npm init -y
 Copy code 
  1. Installation dependency
# dev rely on 
npm install --save-dev @babel/core @babel/plugin-proposal-class-properties @babel/preset-env @babel/preset-react babel-loader copy-webpack-plugin clean-webpack-plugin html-loader html-webpack-plugin webpack webpack-cli webpack-dev-server
# Not dev rely on 
npm install react react-dom react-router-dom
 Copy code 
  1. add to scripts
{
...
"scripts": {
"start": "webpack-dev-server",
"build:prod": "webpack --mode=production",
"build:watch": "webpack --watch --mode=production"
}
...
}
 Copy code 
  1. establish React file

The directory structure is as follows :

src
┣ assets
┃ ┗ eye-dropper-solid.svg
┣ background
┃ ┗ index.ejs
┣ components
┣ epicker-ui
┃ ┣ api.ts
┃ ┣ index.css
┃ ┣ index.ejs
┃ ┗ index.tsx
┣ popup
┃ ┣ index.css
┃ ┣ index.ejs
┃ ┗ index.tsx
┣ declares.d.ts
┣ default.css
┣ manifest.json
┗ request.ts
 Copy code 

Because we need to insert some third-party js package , So our HTML The template adopts ejs File to write .

popup.ejs

<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<div id="popup"></div>
<%
for (let i=0; i<htmlWebpackPlugin.options.jsScripts.length; i++) {
%>
<script defer="defer" src="<%= htmlWebpackPlugin.options.jsScripts[i] %>"></script>
<% } %>
</body>
</html>
 Copy code 

epicker-ui.js

<!DOCTYPE html>
<html id="tracker-epicker" lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<div id="epicker-ui"></div>
<%
for (let i=0; i<htmlWebpackPlugin.options.jsScripts.length; i++) {
%>
<script defer="defer" src="<%= htmlWebpackPlugin.options.jsScripts[i] %>"></script>
<% } %>
</body>
</html>
 Copy code 

background.ejs

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<%
for (let i=0; i<htmlWebpackPlugin.options.jsScripts.length; i++) {
%>
<script defer="defer" src="<%= htmlWebpackPlugin.options.jsScripts[i] %>"></script>
<% } %>
</body>
</html>
 Copy code 
  1. establish Chrome Plug in files

manifest.json

{
"description": "Tracker Creator for SSC",
"manifest_version": 2,
"minimum_chrome_version": "55.0",
"name": "Tracker Creator 2",
"version": "0.0.1",
"background": {
"page": "background.html"
},
"browser_action": {
"default_icon": "img/icon.png",
"default_popup": "popup.html",
"default_title": "Tracker Creator"
},
"icons": {
"32": "img/icon.png"
},
"content_scripts": [
{
"all_frames": true,
"js": [
"/js/vapi.js",
"/js/vapi-client.js",
"/js/contentscript.js"
],
"match_about_blank": true,
"matches": [
"http://*/*",
"https://*/*"
],
"run_at": "document_start"
}
],
"content_security_policy": "script-src 'self'; object-src 'self'",
"permissions": [
"cookies",
"storage",
"tabs",
"unlimitedStorage",
"webNavigation",
"webRequest",
"webRequestBlocking",
"<all_urls>"
],
"web_accessible_resources": [
"/web_accessible_resources/*"
]
}
 Copy code 

content_scripts: Some context scripts are configured here .

permissions: You need to request permission from the browser .

web_accessible_resources: Resource file , Such as epicker-ui.html.

  1. To configure tsconfig.json
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"jsx": "react",
"lib": ["es2015", "dom"],
"module": "commonjs",
"moduleResolution": "node",
"outDir": "dist/js",
"rootDir": "src",
"sourceMap": true,
"target": "es5"
}
}
 Copy code 
  1. To configure webpack.config.js

This project development involves three pages :popup.html( Parameter panel ),epicker-ui.html( Selector panel ),background.html( backstage ).

To configure externals: {vAPI: 'vAPI', cTracker: 'cTracker', chrome: 'chrome',} To pass... In the project import Direct use of third parties API.

meanwhile , Remember to be in declares.d.ts Configuration in file :declare module 'vAPI'; declare module 'cTracker'; declare module 'chrome'; Make it impossible to report ts It's abnormal .

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
devServer: {
contentBase: path.resolve(__dirname, './src'),
historyApiFallback: true
},
entry: {
popup: path.resolve(__dirname, "./src/popup/index.tsx"),
'epicker-ui': path.resolve(__dirname, "./src/epicker-ui/index.tsx"),
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
resolve: {
mainFields: ['module', 'main', 'browser'],
alias: {
root: path.resolve(__dirname),
'@': path.resolve(__dirname, 'src'),
},
extensions: ['.js', '.tsx', '.d.ts', '.ts', '.jsx', '.json', '.css'],
},
externals: {
vAPI: 'vAPI',
cTracker: 'cTracker',
chrome: 'chrome',
},
optimization: {
...
},
module: {
...
},
plugins: [
new HtmlWebpackPlugin({
filename: 'popup.html',
template: 'src/popup/index.ejs',
chunks: ['popup'],
jsScripts: ["js/vapi.js", "js/vapi-common.js", "js/vapi-client.js"],
inject: 'body'
}),
new HtmlWebpackPlugin({
filename: 'web_accessible_resources/epicker-ui.html',
template: 'src/epicker-ui/index.ejs',
chunks: ['epicker-ui'],
jsScripts: ["../js/vapi.js", "../js/vapi-common.js", "../js/vapi-client.js", "../js/vapi-client-extra.js", "../js/lib/optimal-select.min.js"],
inject: 'body'
}),
new HtmlWebpackPlugin({
filename: 'background.html',
template: 'src/background/index.ejs',
chunks: ['background'],
jsScripts: ["js/webext.js", "js/vapi.js", "js/vapi-common.js", "js/vapi-background.js", "js/background.js", "js/cTracker.js", "js/messaging.js", "js/start.js"],
inject: 'body',
}),
new CopyWebpackPlugin({
patterns: [
{ from: 'src/manifest.json', to: '[name][ext]' },
]
}),
new CleanWebpackPlugin()
...
],
performance: {
hints: false,
},
}
 Copy code 
  1. pack
npm run build
 Copy code 

Load the unzipped extender , choice dist The result of packing .

debugging content scripts

Can be in source > Content scripts All of the plug-ins found in Content scripts, Add any breakpoint for debugging JS.

debug-conten-script.png

debugging Background

It can be in the plug-in interface , find background.html Link to , Click to open the debugging console on the background page .

debug-backgound.png

debugging Popup.js

Popup With the ordinary Web Debugging is similar to , You can right-click Toolbar plug-in icon after , Select... On the expanded content Review pop-up content , You can open Popup page Debug console for .

debug-popup.png

Reference resources

Please bring the original link to reprint ,thank
Similar articles

2021-09-15