Chrome扩展开发实战:打造你的GPT助手(仿豆包、sider谷歌插件)

Chrome扩展开发实战:打造你的GPT助手

在当今AI快速发展的时代,GPT等大语言模型已经成为开发者的得力助手。如何将这些强大的AI能力无缝集成到我们的日常工作流程中?本文将介绍如何使用现代前端技术栈开发一个Chrome扩展,让GPT的能力触手可及。

GPT Helper是一个Chrome扩展,它允许用户在浏览网页时随时调用GPT进行交互,用户可以选择文本并让GPT进行解释、翻译或代码分析等操作,并集成必应搜索功能。

点击查看GitHub源码

功能示意图如下

  • 鼠标左键划词:

  • 解释选中文案

  • 侧边栏可集成任意网址

技术栈概览

前端技术

  • 框架:React + TypeScript
  • 构建工具:Vite
  • 样式预处理器:Less
  • 浏览器API:Chrome Extension MV3

后端服务

  • AI引擎:GPT-3.5 Turbo API
  • 搜索集成:Bing Search API
  • 通信协议:WebSocket

项目结构解析

bash 复制代码
.
├── src/
│   ├── content-scripts/            # 内容脚本核心逻辑
│   │   ├── components/             # React组件
│   │   │   ├── GptModal/           # GPT交互弹窗
│   │   │   └── Menu/               # 右键菜单组件
│   │   ├── App.tsx                 # 主应用入口
│   │   └── content.css             # 全局样式
│   ├── assets/                     # 静态资源
│   ├── manifest.json               # 扩展清单配置
│   └── popup.html                  # 扩展弹出页
├── vite-plugin/                    # 自定义Vite插件
│   └── src/
│       ├── client/                 # WebSocket客户端
│       └── index.ts                # 插件主逻辑
├── package.json
└── vite.config.ts

开发Chrome扩展的关键点

1. Manifest V3配置

Chrome扩展的核心是manifest.json文件,它定义了扩展的权限、资源和行为。在Manifest V3中,安全性和性能得到了加强,但也带来了一些开发上的变化。

2. 内容脚本与背景脚本

  • 内容脚本(Content Scripts):直接在网页上下文中运行,可以读取和修改DOM
  • 背景脚本(Background Scripts):在扩展的后台持续运行,管理全局状态和事件

3. 使用Vite构建Chrome扩展

传统的Chrome扩展开发可能使用webpack或原生JS,但使用Vite可以带来更好的开发体验:

  • 更快的热重载
  • 现代化的模块打包
  • TypeScript和React的无缝支持

我们使用了自定义的vite-plugin-crx-mv3插件来简化Chrome扩展的构建过程。

javascript 复制代码
// vite.config.ts示例
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { crx } from 'vite-plugin-crx-mv3';

export default defineConfig({
  plugins: [
    react(),
    crx({ manifest: './src/manifest.json' })
  ]
});

实现GPT交互功能

1. 划词菜单实现

当用户选中文本并右键点击时,我们需要显示自定义菜单选项:

typescript 复制代码
// 简化的菜单组件示例
const Menu = ({ position, onSelect }) => {
  const options = [
    { key: 'explain', label: '解释选中内容' },
    { key: 'translate', label: '翻译选中内容' },
    { key: 'code', label: '分析代码' }
  ];
  
  return (
    <div className="gpt-menu" style={{ top: position.y, left: position.x }}>
      {options.map(option => (
        <div 
          key={option.key} 
          className="menu-item"
          onClick={() => onSelect(option.key)}
        >
          {option.label}
        </div>
      ))}
    </div>
  );
};

2. GPT API调用

选择操作后,我们需要调用GPT API并展示结果:

typescript 复制代码
// 简化的API调用示例
const callGptApi = async (content, type) => {
  try {
    //需要填写自己的gpt接口
    const response = await fetch('you gpt url', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${API_KEY}` //需要填写自己的key
      },
      body: JSON.stringify({
        model: 'gpt-3.5-turbo',
        messages: [
          { role: 'system', content: getPromptByType(type) },
          { role: 'user', content }
        ]
      })
    });
    
    const data = await response.json();
    return data.choices[0].message.content;
  } catch (error) {
    console.error('GPT API调用失败:', error);
    return '抱歉,请求失败,请稍后再试。';
  }
};

3. 结果展示

使用可拖拽和可调整大小的模态框展示GPT的回答:

typescript 复制代码
// App.tsx中的状态管理示例
const [gptContentVisible, setGptContentVisible] = useState(false);
const [gptContent, setGptContent] = useState('');
const [curGptType, setCurGptType] = useState('');
const [bingAnswerList, setBingAnswerList] = useState([]);

const updateGptModal = (visible: boolean) => {
  setGptContentVisible(visible);
}

const updateGptConten = (content: string) => {
  setGptContent(content);
}

const updateGptType = (type: string) => {
  setCurGptType(type);
}

const updateBing = (list: any) => {
  setBingAnswerList(list);
}

开发过程中的技术挑战与解决方案

1. 内容脚本与扩展通信

Chrome扩展的不同部分(内容脚本、背景脚本、弹出页面)之间的通信是一个常见挑战。我们使用Chrome提供的消息传递API来解决:

typescript 复制代码
// 发送消息
chrome.runtime.sendMessage({ type: 'GPT_QUERY', data: { text, queryType } });

// 接收消息
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === 'GPT_RESPONSE') {
    // 处理GPT响应
    updateGptConten(message.data.content);
    setGptContentVisible(true);
  }
  return true;
});

2. 开发环境的热重载

Chrome扩展开发中,每次修改代码后都需要重新加载扩展,这大大降低了开发效率。我们使用WebSocket实现了热重载功能:

typescript 复制代码
// vite-plugin-crx-mv3中的热重载实现
export async function emitDevScript(
  context: PluginContext,
  port: number,
  manifestContext,
  reloadPage: boolean
): Promise<Record<string, any>> {
  // ...
  
  let code = `var PORT=${port},MENIFEST_NAME='${manifest.name}',RELOADPAGE=${reloadPage};`
  let contentScriptDevPath = normalizePathResolve(
    __dirname,
    'client/content.js'
  )
  let content = await getContentFromCache(
    context.cache,
    contentScriptDevPath,
    'utf8'
  )

  context.emitFile({
    type: 'asset',
    source: code + content,
    fileName: CONTENT_SCRIPT_DEV_PATH
  })
  
  // ...
}

3. Markdown渲染

GPT返回的内容通常包含Markdown格式,我们需要将其渲染为HTML:

typescript 复制代码
// 使用marked和highlight.js渲染Markdown
import { marked } from 'marked';
import hljs from 'highlight.js';

marked.setOptions({
  highlight: function(code, lang) {
    if (lang && hljs.getLanguage(lang)) {
      return hljs.highlight(code, { language: lang }).value;
    }
    return hljs.highlightAuto(code).value;
  }
});

const renderMarkdown = (content) => {
  return { __html: marked(content) };
};

// 在组件中使用
<div 
  className="markdown-content"
  dangerouslySetInnerHTML={renderMarkdown(gptContent)} 
/>

部署与发布

Chrome扩展的发布流程相对简单:

  1. 使用生产模式构建扩展:npm run build
  2. 打包生成的dist目录为zip文件
  3. 在Chrome Web Store开发者控制台上传并提交审核
  4. 审核通过后,扩展将在Chrome Web Store上线
相关推荐
H5开发新纪元4 分钟前
Vite 项目打包分析完整指南:从配置到优化
前端·vue.js
嘻嘻嘻嘻嘻嘻ys5 分钟前
《Vue 3.3响应式革新与TypeScript高效开发实战指南》
前端·后端
恋猫de小郭20 分钟前
腾讯 Kuikly 正式开源,了解一下这个基于 Kotlin 的全平台框架
android·前端·ios
2301_7994049122 分钟前
如何修改npm的全局安装路径?
前端·npm·node.js
(❁´◡双辞`❁)*✲゚*27 分钟前
node入门和npm
前端·npm·node.js
韩明君31 分钟前
前端学习笔记(四)自定义组件控制自己的css
前端·笔记·学习
tianchang42 分钟前
TS入门教程
前端·typescript
吃瓜群众i42 分钟前
初识javascript
前端
Gladiator5751 小时前
博客记录-day153-力扣
github
前端练习生1 小时前
vue2如何二次封装表单控件如input, select等
前端·javascript·vue.js