截至 2024 年 12 月,Chrome 仍然是全球最受欢迎的浏览器。学习开发 Chrome 扩展程序可以为探索基于浏览器的开发提供令人兴奋的机会,并增强您对浏览器底层工作原理的理解。 Chrome 网上应用店提供了大量扩展程序,允许用户自定义浏览器的默认行为并扩展各种网站的功能。
在本博客中,我们将介绍如何设置本地开发环境,以使用 TypeScript 和 Webpack 创建 Chrome 扩展。本指南非常适合任何想要掌握 Chrome 扩展程序开发基础知识的人。最后,您将拥有一个正常运行的开发环境,可以用来试验您的第一个扩展。在深入研究之前,请确保您对 Web 技术、JavaScript 以及 JavaScript 生态系统中的常用工具有基本的了解。详细信息列于先决条件部分。
在开始设置之前,让我们简单了解一下 Chrome 扩展程序的一些关键组件:
弹出窗口 : 管理扩展程序的用户界面,但无法直接访问父网页的 DOM。
内容脚本:可以直接访问父网页的 DOM,但在单独的执行上下文中运行。这种分离意味着它无法直接访问父页面的 JavaScript 对象。
注入的脚本 : 与父网页共享相同的执行上下文,允许访问其 DOM 和 JavaScript 对象。
后台脚本 :在隔离的上下文中运行,无法直接访问父页面的 DOM 或 JavaScript 对象。
Popup、Content 和 Background 脚本在扩展的上下文中运行,而 Injected 脚本在扩展的上下文中运行父网页。父页面是指扩展程序在其上执行其功能的活动网页。对这些页面的权限和访问在manifest.json 文件中定义,我们将在本博客后面介绍。
要学习本教程,请确保您已安装以下工具:
Node.js (v18.16 LTS)
NPM(节点包管理器)
TypeScript
Webpack
VS 代码编辑器(或您选择的任何代码编辑器)
每个 Chrome 扩展程序都需要在项目根级别有一个名为 manifest.json 的文件。该文件用作扩展的配置蓝图,包含有关项目的基本详细信息。虽然总体项目结构没有严格的规则,但我们将从创建此文件开始,并按照本博客中的概述逐步构建项目。
继续之前,请确保您的计算机上已安装所有必备软件。
按照以下步骤设置您的项目及其依赖项:
为您的项目创建一个目录并进入该目录。这将是您项目的根。除非另有说明,从这里开始的所有内容都将基于您项目的根。
mkdir chrome-extension && cd ./chrome-extension
创建一个名为manifest.json的文件
{ "manifest_version": 3, "name": "My First Chrome App", "version": "1.0", "description": "A Chrome extension built with TypeScript using webpack.", "action": { "default_popup": "popup.html", "default_icon": "icon.png" } }
manifest.json 中的大部分内容都是不言自明的,除了 action 对象。 default_icon 是应用程序的图标,将显示在 Chrome 中应用程序名称旁边,default_popup 指定单击扩展程序图标时要显示为弹出窗口的 HTML 文件。
创建一个名为 popup.html 的文件,其中包含以下内容,
<html> <head> <title>First Chrome Extension</title> </head> <body> <h1>This is my app popup</h1> </body> </html>
在根目录中包含一个名为 icon.png 的图像文件。这将作为您的应用程序的图标,显示在 Chrome 工具栏中。确保图像采用受支持的格式(例如 PNG)且大小适当。
在深入研究更复杂的功能之前,让我们测试这个基本扩展以确保一切设置正确。这个初始测试将作为我们开发过程的基础,并确认我们稍后所做的更改是否按预期工作。
打开 Chrome 的扩展程序管理 :打开 Chrome 并通过在地址栏中输入 chrome://extensions/ 导航到“管理扩展程序”页面。这将带您进入“扩展”屏幕。
启用开发者模式 :找到屏幕右上角的开发者模式开关,如果尚未启用,请将其打开。启用此模式允许 Chrome 除了从 Chrome Web Store 下载的扩展程序之外还加载本地构建的扩展程序。
加载您的扩展 :点击页面顶部的加载解压按钮。浏览并选择项目的根目录。
验证安装:加载后,您的扩展应该出现在已安装扩展的列表中。
渲染弹出窗口: 单击 Chrome 右上角“管理扩展程序”按钮上方的“我的第一个 Chrome 应用程序”图标。此操作应该呈现 popup.html 文件,显示您之前定义的内容。
如果您已成功使其正常工作,那么我们的第一次测试就成功了,我们可以在此基础上继续进行。如果没有,请仔细阅读以上内容,以确保您没有错过任何一步。
下一步是创建一个 package.json 文件来管理项目依赖项。运行以下命令:
npm init -y
此命令使用默认值初始化 package.json 文件。如果您想自定义它,请省略 -y 标志并以交互方式回答提示。
默认的 package.json 文件将如下所示:
{ "manifest_version": 3, "name": "My First Chrome App", "version": "1.0", "description": "A Chrome extension built with TypeScript using webpack.", "action": { "default_popup": "popup.html", "default_icon": "icon.png" } }
现在我们可以将所有必需的依赖项安装到项目中。您可以使用以下命令来执行此操作。
npm install -D typescript — 安装 TypeScript 并将其添加到 package.json 的 devDependencies 部分
npm install -D @types/chrome — 安装 Chrome 类型并将其添加到 package.json 的 devDependencies 部分
npm install -D webpack — 将 webpack 安装到项目中并将其添加到 package.json 的 devDependencies 部分
npm install -D webpack-cli — 这是必需的,因为每当我们对代码库进行更改时,我们都会进行热重载
npm i -D copy-webpack-plugin — 需要将任何静态资源复制到输出目录或 dist 目录
npm i -D path — 这是稍后解析 webpack 配置中静态资源的路径所必需的
npm i -D @babel/core @babel/preset-env babel-loader ts-loader — 这是在 webpack 构建过程中编译代码所必需的
对于下一个测试,我们必须让这个应用程序与 typescript 和 webpack 一起使用。我们已经安装了所需的依赖项。现在我们必须创建一些配置文件并编写一些代码才能使其正常工作。
我们将创建两个配置文件,一个用于 TypeScript,另一个用于 webpack。创建一个名为 tsconfig.json 的文件,其中包含以下内容。
<html> <head> <title>First Chrome Extension</title> </head> <body> <h1>This is my app popup</h1> </body> </html>
以上是为了让TypeScript编译器正确识别.ts文件的位置并正确编译它们。根据上述配置,.ts 文件应位于 src 目录或其子目录下。转换后的 .js 文件将在 dist 目录中创建。
现在创建 webpack.config.cjs 文件,该文件将包含构建和生成编译文件以及其他静态资产所需的配置。图片
{ "name": "chrome-extension", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }
注意:CopyWebpackPlugin 将静态资源从源代码复制到 dist 目录。
现在使用以下命令创建所需的目录:
mkdir src/scripts -p
在脚本目录中,创建一个包含以下内容的简单 Typescript 文件,
src/scripts/popup.ts
{ "manifest_version": 3, "name": "My First Chrome App", "version": "1.0", "description": "A Chrome extension built with TypeScript using webpack.", "action": { "default_popup": "popup.html", "default_icon": "icon.png" } }
每当渲染弹出窗口时,上面的代码都会将消息打印到控制台。我们还必须在 popup.html 中包含此 popup.ts 文件的链接(它将被编译为 popup.js 文件)。另外,创建名为 popup-style.css 和 content-style.css 的文件。我们稍后可以使用这些文件来设计弹出窗口和其他页面的样式。那么让我们这样做吧,
在我们之前创建的 popup.html 中包含 popup-style.css 和 popup.js 的链接
popup.html
<html> <head> <title>First Chrome Extension</title> </head> <body> <h1>This is my app popup</h1> </body> </html>
创建 popup-style.css 文件:
{ "name": "chrome-extension", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }
创建 content-style.css 文件:
{ "compilerOptions": { "target": "ES6", "module": "commonjs", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "outDir": "./dist", "rootDir": "./src" }, "include": ["src/**/*"] }
现在是时候将 webpack 相关命令添加到 package.json 文件中,以便我们可以构建扩展了。
// [webpack.config.cjs] const path = require("path"); const webpack = require("webpack"); const CopyWebpackPlugin = require("copy-webpack-plugin"); module.exports = { mode: "development", // Use 'production' for production builds target: "web", devtool: "source-map", entry: { "popup": path.resolve( __dirname, "src/scripts/popup.ts" ), }, output: { filename: "[name].js", // Output file name for each entry path: path.resolve(__dirname, "dist"), // Output directory clean: true, // Clean the output directory before each build libraryTarget: "umd", // Universal Module Definition }, resolve: { extensions: [".ts", ".js"], // Resolve .ts and .js extensions }, module: { rules: [ { test: /\.ts$/, exclude: /node_modules/, use: [ { loader: "babel-loader", options: { presets: ["@babel/preset-env"], }, }, "ts-loader", ], }, ], }, plugins: [ new CopyWebpackPlugin({ patterns: [ { from: path.resolve(__dirname, "popup-style.css"), // Source directory to: path.resolve(__dirname, "dist"), // Destination directory }, { from: path.resolve(__dirname, "content-style.css"), // Source directory to: path.resolve(__dirname, "dist"), // Destination directory }, { from: path.resolve(__dirname, "icon.png"), // Source directory to: path.resolve(__dirname, "dist"), // Destination directory }, { from: path.resolve(__dirname, "popup.html"), // Source directory to: path.resolve(__dirname, "dist"), // Destination directory }, { from: path.resolve(__dirname, "manifest.json"), // Source directory to: path.resolve(__dirname, "dist"), // Destination directory }, ], }), ], }
运行以下命令开始构建过程:
npm run build
此命令监视文件中的更改并自动重建项目。
我们现在可以做另一个测试来检查我们的 webpack 相关配置是否按预期工作。但在尝试测试之前,请从您将项目根目录上传到 Chrome 的第一个测试中删除旧扩展。现在,这次我们必须上传 dist 目录,因为编译后的代码将位于该目录中,而不是项目的根目录中。上传新版本的扩展并渲染弹出窗口后,右键单击弹出窗口并打开开发控制台,然后检查是否可以从 popup.ts 中看到控制台语句。该声明应该存在,如果没有,请检查前面的步骤是否有错误。
至此,我们已经有了一个可以使用的基本版本的扩展,但我们还需要添加一些组件,以便我们可以轻松地进行本地开发。
到目前为止我们已经看到了弹出组件。现在是时候添加其他组件了。在 src/scripts 目录中创建三个文件,即injected.ts、content.ts和background.ts,内容如下:
src/scripts/injected.ts
(() => { const message:string = "This is a console statement from the popup script"; console.log(message) })();
injected.[ts|js] 是一个特殊文件,可以访问 Dom 以及父站点公开的 JavaScript 对象。我们需要使用内容脚本动态地将此文件添加到主机站点。
创建 content.ts 文件:
src/scripts/content.ts
.... <link href="popup-style.css" rel="stylesheet"/> .... <script src="popup.js"></script> ....
创建background.ts文件:
src/scripts/background.ts
{ "manifest_version": 3, "name": "My First Chrome App", "version": "1.0", "description": "A Chrome extension built with TypeScript using webpack.", "action": { "default_popup": "popup.html", "default_icon": "icon.png" } }
现在我们必须更新 webpack.config.cjs 文件以添加这三个条目作为入口点。
<html> <head> <title>First Chrome Extension</title> </head> <body> <h1>This is my app popup</h1> </body> </html>
最后一步,我们必须更新 manifest.json 文件以包含所有这些配置,以便 Chrome 环境可以检测到它们。
{ "name": "chrome-extension", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }
在上面的manifest.json中,我们配置了扩展程序以与google.com一起使用,这意味着该扩展程序仅在浏览器中加载google.com时才会执行其逻辑。您可以将其更改为您选择的任何其他网站。
我们现在可以使用增强的设置进行最终测试。在继续之前,请确保在 Chrome 中重新安装该应用程序,以避免因与旧版本代码不匹配而出现问题。要查看所有组件是否正常工作,请检查不同的 console.log 语句。请记住,我们已将 console.log 语句放入四个不同的文件中:injected.ts、background.ts、content.ts 和 popup.ts。控制台中应记录四条消息。所以,步骤如下,
在终端中停止 npm run build 命令(如果它正在运行)并再次启动它,以便它获取我们刚刚创建的新文件
删除并重新安装应用程序
从扩展设置屏幕打开弹出窗口,右键单击该弹出窗口并打开开发人员控制台。您应该在此控制台中看到来自后台脚本和弹出脚本的消息
在浏览器的另一个选项卡中打开 https://www.google.com
右键单击打开的谷歌网站并打开开发者控制台。您应该能够看到来自内容脚本和注入脚本的消息
恭喜您成功设置并运行您的第一个 Chrome 扩展程序!如果您遇到任何问题,请仔细检查您所执行的步骤,以确保一切就绪。此外,本博客末尾还提供了 GitHub 存储库的链接,供您参考。
在这篇博客中,我们学习了如何为 Chrome 扩展程序开发设置本地开发环境。以下是一些要点:
我们探索了 Chrome 扩展程序开发中涉及的主要组件。
我们学习了如何使用 TypeScript 和 Webpack 设置开发环境。
我们还介绍了如何在 Chrome 中设置和测试扩展程序。
我目前正在撰写另一个博客,我们将在其中探索 Chrome 扩展的一个简单用例,展示我们在本博客中讨论的 Chrome 开发环境的所有组件如何组合在一起创建功能扩展。
感谢您花时间阅读此博客!非常感谢您的兴趣和时间。当我继续这一旅程时,我很高兴能分享更多。快乐编码!
GitHub 链接 — https://github.com/gauravnadkarni/chrome-extension-starter-ts
本文最初发表于Medium。
以上是进入 Chrome 扩展开发:使用 TypeScript 和 Webpack 轻松设置的详细内容。更多信息请关注PHP中文网其他相关文章!