编程导航插件话题讨论

插件

77 参与
分享

快来分享你的内容吧~

点击登录,快来和大家讨论吧~
表情
图片
话题
打卡
综合
交流
文章
问答

浏览器插件发布上线保姆级流程

## <font style="color:rgb(31, 35, 40);">✨</font>前言 Hi,我是松柏! 前几天我分享了自己做的[一个用于书签管理的浏览器小插件](https://mp.weixin.qq.com/s/m9X3hVOKTE8Q2RcH89QqdA),也是比较受大家欢迎,在我公众号没什么粉丝基础的情况下加一起有6000多的阅读: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/sZ5VmtZRorl3kCpc.webp) 那既然这样,我就想着不如把这个插件上线了,这样大家用起来更方便一些,现在已经可以在火狐浏览器的插件市场直接搜索安装使用啦: 火狐:[https://addons.mozilla.org/zh-CN/firefox/addon/bookmark-genie](https://addons.mozilla.org/zh-CN/firefox/addon/bookmark-genie) ![](https://pic.code-nav.cn/post_picture/1626574509983178753/0FNmX045wYs7KZ3H.webp) Edge 还在审核中(时间11-09): ![](https://pic.code-nav.cn/post_picture/1626574509983178753/tU01XI6Bw5VVednt.webp) (Google 浏览器发布插件要付 5 美刀😭,就没上线) 因为我也是第一次上线浏览器插件,所以就把插件上线的详细流程以及容易踩的一些坑记录了下来,通过这篇文章分享给大家,快收藏起来⭐️以备不时之需吧。 ## 发布流程 ### 火狐 > 如果有页面打不开,可以尝试换一下网络 > #### 1、注册账号 首先来到[插件市场](https://addons.mozilla.org/zh-CN/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom),点击右上角的登录: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/5a2sqF1Ulw0FUiPJ.webp) 接着就是正常的注册账号流程,大家按需注册即可: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/DwjXivEs1RcVWfIf.webp) #### 2、提交插件 注册成功之后,我们回到插件市场,然后进入开发者中心: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/CHGWzN0N09DzAH4Y.webp) 然后选择 提交新附加组件: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/f0n0GMLfu6BYoZWT.webp) 为了省事的话,可以直接选择 在此网站上: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/PcDPtxO3DygVZ7cN.webp) 选择打包后的文件: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/p0ifyiUnpKbvRxkD.webp) 这里有两个注意事项: 1)因为在开发时,我们遵守的时 google 浏览器的标准,这些标准在火狐浏览器不被完全支持或者兼容,所以我们需要修改部分 `manifest.json` 的配置,大家发布的时候可以参考我修改后的配置文件: ```json { "manifest_version": 2, "name": "书签精灵", "version": "0.0.1", "description": "使用 AI 智能搜索书签", "permissions": [ "bookmarks", "storage", "activeTab", "tabs" ], "background": { "scripts": ["background/background.js"], "persistent": false }, "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content/content.js"], "run_at": "document_end" } ], "browser_action": { "default_popup": "src/popup/index.html", "default_title": "书签精灵", "default_icon": { "16": "icons/icon.png", "32": "icons/icon.png", "48": "icons/icon.png", "128": "icons/icon.png" } }, "icons": { "16": "icons/icon.png", "32": "icons/icon.png", "48": "icons/icon.png", "128": "icons/icon.png" }, "commands": { "open-ai-chat": { "suggested_key": { "default": "Ctrl+K", "mac": "Command+K" }, "description": "打开书签精灵" } }, "web_accessible_resources": [ "assets/*" ], "browser_specific_settings": { "gecko": { "id": "2268143474@qq.com", "data_collection_permissions": { "required": ["none"] } } } } ``` 2)打包时,一定要进入文件夹内再压缩,保证解压后 manifest.json 在一级目录里,比如我这里是先进入打包后的 dist 目录内,然后全选进行压缩: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/kdaR9lidRJSRRPt9.webp) 因为如果直接在文件夹外压缩 dist 目录,解压后得到的就是一个 dist 文件夹,解析就会失败。 如果打包后的文件有问题,火狐也会给出原因,按照提示修改即可: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/thqaRSPvSnNofYXi.webp) #### 3、填写其他表单项 然后的话就是一些其他的常规表单项了,大家按照真实情况正常填写,比如: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/xyNSX4NsvZAeVAIp.webp) #### 4、完善插件信息 完成上述步骤之后,回到开发者中心,补充插件的信息: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/ZcmMsgR9jTdxvasH.webp) 比如概述、类别、标签、图标这些内容: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/VChZ1RIGoFnz7l9q.webp) 这些都是为了让用户更精准的搜索到我们的插件,所以大家可以尽可能精准、详细的描述插件的作用。 #### 5、过审 到这里基本就完成了,火狐会给我们发一封邮件告知插件正在审核中: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/MJ6QPgYONHqMRAZx.webp) 我这里审核花了4天,通过之后,同样也会有一封邮件: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/wWEGBatoHJVg7Cri.webp) 然后我们的插件就可以被正常的在插件中心搜索和安装啦: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/13HsO3aSrAgR70LE.webp) 也可以通过在线链接直接访问:[https://addons.mozilla.org/zh-CN/firefox/addon/bookmark-genie/](https://addons.mozilla.org/zh-CN/firefox/addon/bookmark-genie/),欢迎使用火狐浏览器的小伙伴安装体验,有问题也可以随时反馈给我。 到这里我们的插件就算是成功的上线到了火狐浏览器啦! ### Edge #### 1、注册账号 跟火狐一样,这里也是需要先注册一个账号,进入[扩展中心](https://microsoftedge.microsoft.com/addons/Microsoft-Edge-Extensions-Home),然后选择构建扩展: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/EniIuafxBUCVar51.webp) 进入页面之后会要求注册登录,按照要求一步步的来就好: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/hK7IB1WA7TJHqSRq.webp) 填表单的时候有一个非常坑的地方: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/CaE9Dyycj1vfW3CP.webp) **这个输入框是必填的**,但是并没有标 * 号,而且不能随便填,需要填地址的首拼,比如我这里填的是 SH (上海)。如果不填或者不合法,会出现异常: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/pr9xBorVAKENosEa.webp) 通过之后,应该会看到这样一个页面: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/ArAifOeXkBuQL4Ap.webp) 我们点击 创建新扩展 开始发布插件。 #### 2、发布插件 ![](https://pic.code-nav.cn/post_picture/1626574509983178753/dUtwltDXmsXdr5jy.webp) 发布插件的时候需要上传代码压缩包、填写表单项,跟火狐的方式大差不差,按照提示填写,我这里就不赘述了。跟火狐有一点不同的是,这里上传代码的时候配置不用修改 `manifest.json` 配置,可以我们项目的默认值保持一致。 #### 3、等待过审 都填写完成之后,就是等待过审了,Edge 的审核速度比较慢,说是七个工作日内: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/bWVWZYjsCuvPGz8Y.webp) 到写完这篇文章之前,我的插件一直没过审,所以暂时没法给大家分享成功之后的流程。 ## <font style="color:rgb(31, 35, 40);">🎯</font>结语 到这里我们就成功的把插件发布上线啦,如果有帮助的话,欢迎点赞和关注呀,下篇文章见,拜拜👋🏻!

新手也能懂!30 分钟学会如何做 Chrome 插件

想在浏览网页时快速定位关键信息?不用找现成工具,自己动手开发一个关键词高亮插件其实很简单。下面我们从 “准备材料” 到 “组装成品”,一步步带你实现这个实用小工具,全程只需要 4 个核心文件。  感兴趣的可以看看我刚开发Chrome标签页扩展网页体验版:[NBtab新标签页](https://nbtab.com/) ## 第一步:搭好插件的 “身份档案”——manifest.json 就像身份证记录个人信息,manifest.json是插件的 “官方档案”,Chrome 全靠它识别插件的功能和权限。没有这个文件,插件根本无法运行。 ### 核心信息拆解 它主要包含 3 类关键内容,我们直接看实战配置里的重点: **基础身份**:name(插件名)、version(版本号)、description(功能描述),让用户一眼知道这是个什么工具。 **交互入口**:action里的default_popup指定点击插件图标弹出的页面,default_icon设置插件在浏览器工具栏的图标。 **权限申请**:permissions声明插件需要的能力,这里activeTab是获取当前浏览的标签页,scripting是允许执行脚本 —— 这两个是实现高亮功能的关键权限,多申请没用,少了又不行。 ```json { "manifest_version": 3, "name": "关键词高亮插件", "version": "1.0", "description": "高亮网页中的指定关键词", "action": { "default_popup": "popup.html", "default_icon": "icon.png" }, "permissions": ["activeTab", "scripting"], "icons": { "16": "icon16.png", "48": "icon48.png", "128": "icon128.png" } } ``` ## 第二步:做个简单的 “控制面板”——popup.html 插件的交互全靠这个弹出窗口,我们不用做复杂设计,只要满足 “输入关键词 + 选颜色 + 触发操作” 三个核心需求就行。 ### 界面核心元素 这个页面就像一个迷你控制面板,每个元素都有明确用途: **文本输入框(id="keyword")**:让用户输入想高亮的词,比如 “数据分析”“核心结论”。 **颜色选择器(id="colorPicker")**:默认黄色,用户也能改成自己喜欢的颜色,比如用红色标重点。 **两个按钮**:“高亮关键词” 负责启动功能,“清除高亮” 负责恢复页面原样,避免高亮太多影响阅读。 **最后引入popup.js**:光有界面不行,得靠它让按钮 “动起来”。 ```html <!DOCTYPE html> <html> <head> <style> body { width: 200px; padding: 10px; } button { margin-top: 10px; } </style> </head> <body> <input type="text" id="keyword" placeholder="输入要搜索的关键词"> <input type="color" id="colorPicker" value="#FFFF00"> <button id="highlightBtn">高亮关键词</button> <button id="clearBtn">清除高亮</button> <script src="popup.js"></script> </body> </html> ``` ## 第三步:写好 “高亮魔法”——content.js 这是插件的 “核心引擎”,专门负责在网页里找关键词并加上颜色。它就像一个 “网页化妆师”,悄悄修改页面内容却不影响网页本身功能。 ### 核心逻辑拆解 它主要干两件事,而且逻辑很清晰: **高亮函数(highlightKeyword)**: 1、先 “卸妆”:每次执行前清除之前的高亮(找所有带keyword-highlight类的元素,把它们还原成普通文本),避免重复标记。 2、再 “化妆”:用TreeWalker遍历网页里所有文本节点,找到包含关键词的文本后,用<span>标签把它包起来,再给这个标签加背景色 —— 这样关键词就显眼了。 **消息监听**:通过chrome.runtime.onMessage听popup.js的指令,收到 “highlight” 就执行高亮,收到 “clear” 就清除高亮,相当于和控制面板实时通信。 ```javascript // 高亮函数 function highlightKeyword(keyword, color = "yellow") { // 清除旧的高亮 document.querySelectorAll(".keyword-highlight").forEach(el => { el.replaceWith(el.textContent); }); if (!keyword) return; // 遍历所有文本节点 const walker = document.createTreeWalker( document.body, NodeFilter.SHOW_TEXT ); while (walker.nextNode()) { const node = walker.currentNode; if (node.textContent.includes(keyword)) { const span = document.createElement("span"); span.className = "keyword-highlight"; span.style.backgroundColor = color; span.textContent = node.textContent; node.replaceWith(span); } } } // 监听来自 popup 的消息 chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === "highlight") { highlightKeyword(request.keyword, request.color); } else if (request.action === "clear") { highlightKeyword(""); // 传入空字符串清除高亮 } }); ``` ## 第四步:打通 “控制面板” 和 “引擎”——popup.js 如果说popup.html是按钮,content.js是引擎,那popup.js就是连接两者的 “导线”,负责把用户操作转成指令发给引擎。 ### 交互流程拆解 (1)整个过程就像 “按下开关→机器启动”: 1、当用户点击 “高亮关键词” 按钮: 2、先获取输入框里的关键词和颜色选择器的颜色值; 3、用chrome.tabs.query找到当前活跃的标签页; 再用chrome.tabs.sendMessage把 “highlight” 指令、关键词、颜色一起发给content.js,触发高亮。 (2)点击 “清除高亮” 时,流程类似,只是发的是 “clear” 指令,让content.js清除所有高亮标记。 ```javascript document.getElementById("highlightBtn").addEventListener("click", () => { const keyword = document.getElementById("keyword").value; const color = document.getElementById("colorPicker").value; // 向当前标签页发送高亮指令 chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { chrome.tabs.sendMessage(tabs[0].id, { action: "highlight", keyword: keyword, color: color }); }); }); document.getElementById("clearBtn").addEventListener("click", () => { // 发送清除指令 chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { chrome.tabs.sendMessage(tabs[0].id, { action: "clear" }); }); }); ``` 最后:凑齐 “零件”+ 测试 完整文件清单 一个能跑的插件,文件夹里要包含这些 “零件”,少一个都不行: **manifest.json(身份档案) popup.html(控制面板界面) popup.js(控制面板逻辑) content.js(高亮引擎)** 几个尺寸的图标(icon.png、icon16.png等,浏览器会根据不同场景自动选用) ### 3 步测试插件 1、打开 Chrome,在地址栏输入 chrome://extensions 进入插件管理页; 2、右上角开启 “开发者模式”,这时页面会出现 “加载已解压的扩展程序” 按钮; 3、点击按钮,选择你存放上述文件的文件夹 —— 搞定!现在浏览器工具栏会出现插件图标,点击就能用了。 这样一套流程走下来,你不仅有了一个能用的插件,还能搞懂每个文件的作用。如果想升级功能,比如支持多关键词高亮、记住上次的设置,也能知道该改哪个文件。 感兴趣的可以看看我刚开发Chrome标签页扩展网页体验版:[NBtab新标签页](https://nbtab.com/)

用 AI 写了个帮我管理浏览器书签的插件

前言 -- Hi,我是松柏! 我本人是浏览器书签功能的资深用户,会收藏各种我觉得可能会用到的网站: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/wqZeVbHDyEJ8vo3g.webp) 但是当我真的要用到某个网站的时候,即便我已经收藏了,也很难找到。一方面是我对这些网站的分类归纳做的比较烂;另一方面就是随着收藏的网站越来越多,从里面找东西的成本实在是太高了。 所以我就想,能不能做一个搜索功能,让我用自然语言从收藏的所有书签里快速找到我要的网站。然后我(其实代码都是 AI 写的)就写了一个 Chrome 插件——书签精灵,**开源免费**无毒畅享,地址在文末。 功能介绍 ---- 这个插件的功能非常简单,就是以对话的形式,让 AI 从所有书签中查找到需要的书签: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/CBg4IeKMXxkoQljb.webp) 另外还有一个设置页面: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/0bwstlgQUWKxQeGa.webp) 暗色模式也是支持的: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/9eOOsoedi3W6zxMI.webp) AI 相关的配置: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/5jPsvXDZbdDKHk6C.webp) 所有设置信息都存储在本地,AI 的调用不经过除了 AI 提供商之外的任何第三方服务器,所以安全性也不用担心。 这里可以很方便的配置兼容 OpenAI API 的模型,比如 阿里云百炼、DeepSeek、智谱 等等,我这里默认用智谱只是因为它最近又新送了一波 token ,绝对不是收了钱。 ![](https://pic.code-nav.cn/post_picture/1626574509983178753/DgF1qRyClvYEsxRz.webp) 技术实现 ---- 整个插件的示意图如下: ![](https://pic.code-nav.cn/post_picture/1626574509983178753/F5S6TvL3VOw4F3bZ.webp) 看起来挺花哨,其实没什么东西🐶,逻辑也比较简单,感兴趣的小伙伴可以把源码拉下来看下:[https://github.com/co-pine/bookmark-genie](https://github.com/co-pine/bookmark-genie),我这里就不浪费大家的时间过多赘述了。 快速开始 ---- 1)克隆项目并构建: ```bash git clone <repository-url> cd bookmark-genie npm install npm run build:extension ``` 2)打开 `chrome://extensions/` 3)开启"开发者模式" ![](https://pic.code-nav.cn/post_picture/1626574509983178753/368omP0MN5qOh2Xw.webp) 4)点击"加载未打包的扩展程序" ![](https://pic.code-nav.cn/post_picture/1626574509983178753/Gr0qC1JJjtVKo8bw.webp) 5)选择项目的 `dist` 目录 6)打开插件,开始配置使用,为了方便,可以点击后面的按钮固定一下 ![](https://pic.code-nav.cn/post_picture/1626574509983178753/9YDnapp7reAYXTKY.webp) 7)配置 AI 相关的参数,然后就能正常使用啦! ![](https://pic.code-nav.cn/post_picture/1626574509983178753/W5YMrp7gNa0kZMfr.webp) ![](https://pic.code-nav.cn/post_picture/1626574509983178753/NJSzN40enVlmDPU6.webp) 结语 -- 整个插件从想法到落地一共也就花了几个小时吧,再一次感叹现在 AI 做一些小工具实在是太方便了。 如果有帮助的话,麻烦点赞关注吧,拜拜👋🏻! 项目地址:[https://github.com/co-pine/bookmark-genie](https://github.com/co-pine/bookmark-genie)

浏览器插件推荐CodeBox

![image.png](https://pic.code-nav.cn/post_picture/1615892146731089921/H8By0FeKHAzUPhJZ.webp) ## github地址 https://github.com/hjbfa/code-box ## Edge浏览器 直接去扩展程序商店下载 <img src="https://pic.code-nav.cn/post_picture/1615892146731089921/Cp9sSnPHdsxjt9j3.webp" alt="image.png" width="100%" /> ## 谷歌浏览器 可以用这个网站下载 https://www.crxsoso.com/webstore/detail/acnnhjllgegbndgknlliobjlekgilbdf

我用AI助手3分钟开发了一个浏览器插件,结果令人意外...

# 1、环境搭建 ## 1.1 Node.js 介绍 Node.js是一个开源的JavaScript运行时环境,它允许开发者使用JavaScript在服务器端编写应用程序。 简单来说,Node.js让JavaScript不仅可以在浏览器中运行,也可以在服务器端运行。这意味着开发人员可以使用同一种语言(JavaScript)来编写前端和后端代码,从而提高了开发效率。 Node.js的一个关键特点是它使用了事件驱动和非阻塞I/O模型,这使得它非常适合构建高度可扩展的网络应用程序,比如Web服务器和API。 对于初学者来说,可以把Node.js想象成一个可以运行JavaScript代码的环境,就像浏览器一样,但是它是运行在服务器上而不是在浏览器中。使用Node.js,开发人员可以编写后端服务、命令行工具、甚至是桌面应用程序。 总的来说,Node.js为开发人员提供了一个强大的JavaScript运行时环境,使他们能够构建各种类型的应用程序,从而提高了开发效率和灵活性。 ## 1.2 NVM ### 1.2.1 介绍 NVM (Node Version Manager) 是一个用于管理Node.js版本的工具。它与Node.js本身有着密切的关系。 简单来说: - Node.js 是一个JavaScript运行时环境,允许开发者在服务器端使用JavaScript。 - NVM 是一个工具,可以让你在同一台机器上安装和切换不同版本的Node.js。 NVM 的主要作用是: 1. 允许你在同一台机器上安装和管理多个版本的Node.js。这在开发过程中很有用,因为不同的项目可能需要不同版本的Node.js。 2. 让你可以轻松地在不同版本的Node.js之间切换,而不需要手动安装或卸载。 3. 确保你的项目使用的Node.js版本与项目要求的版本相匹配,避免兼容性问题。 总的来说,NVM 是一个非常有用的工具,它可以帮助开发者更好地管理Node.js的版本,提高开发效率和灵活性。 ### 1.2.2 安装 #### 1 下载 下载地址:[Releases · coreybutler/nvm-windows](https://github.com/coreybutler/nvm-windows/releases) <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/zDMQWchcQxeDZFrz.webp" alt="img" width="100%" /> 点击下载安装程序。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/naIBLAulsqebav4Z.png" alt="img" width="96px" /> 下载好后直接双击安装程序即可。 #### 2 安装 > 安装位置不推荐选C盘,除非你C盘空间非常大。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/kC7fwdTo6adfW1yf.webp" alt="img" width="499px" /> <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/IMBRmOOsXbzgj6vM.png" alt="img" width="499px" /> 点击 Install,确认安装即可。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/Jk2PQFU56tulDop1.png" alt="img" width="499px" /> #### 3 检查 安装完成后在终端输入 nvm -v,能查到版本号,说明安装成功了 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/1zt9sTGOVBheEuYv.webp" alt="img" width="100%" /> <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/NI6IylsvGy8BxDh8.png" alt="img" width="100%" /> #### 4 配置下载源 安装成功后打开 nvm 的安装目录,找到 settings.txt 文件 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/h4KYzZrlPwdtPAgx.webp" alt="img" width="100%" /> ```JSON node_mirror: https://npmmirror.com/mirrors/node/ npm_mirror: https://npmmirror.com/mirrors/npm/ ``` #### 5 配置环境变量 右键此电脑,点击属性 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/GTPH93qVkuzBK34A.webp" alt="img" width="581px" /> 找到高级系统设置 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/qnPb16QWxj8Oifkw.webp" alt="img" width="100%" /> 点击环境变量 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/s29LeI8hoOjUSUwR.webp" alt="img" width="479px" /> 在系统变量中找到 > NVM_HOME NVM_SYMLINK 如果没有, 也可以点击新建环境变量。 然后我们把这两个变量配置到 path 中去。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/o4zYhzfUr0qXG2qw.png" alt="img" width="592px" /> 选中,点击编辑。 > %NVM_HOME% %NVM_SYMLINK% # 2、 使用脚手架初始化项目 ## 2.1 介绍 **为什么使用脚手架初始化项目?** 因为我们在开始编码时,很少真正从零开始写代码。使用脚手架的一个好处是它能够为开发流程设定边界。如果不对cursor进行限制,它可能会按照自己认为合适的、主流的方式生成代码,这可能会导致许多错误。 **个人经历分享:** 当我最初根据教程开发浏览器插件时,尝试让cursor从零开始创建插件。我发现它需要通过链接下载来引入依赖,这样做的问题是链接可能已经失效,而Cursor使用的大模型可能还没有意识到这一点。 **对现代前端依赖管理的看法:** 目前,前端开发普遍使用npm、pnpm等工具来管理依赖。我认为这种使用链接方式下载依赖的方式已经有些过时了。而且还可能下载不下来。 而这次我们使用的脚手架也是 AI 推荐的,我目前使用下来感觉确实还不错。 > chrome-ext 下面是 Claude的介绍 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/cLThr2YpW6HsAndx.webp" alt="img" width="100%" /> ## 2.2 初始化项目 找一个文件夹。 地址栏输入 cmd , 然后回车打开终端 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/B6jbcwcWbQpwuw91.webp" alt="img" width="100%" /> 使用命令开始初始化项目,项目名称,**推荐英文名称**,这样可以减少一些莫名其妙的bug 。 ```JSON npm create chrome-ext 项目名称 ``` 直接回车,使用默认包名即可。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/TCoGDssjJ28O6TRD.webp" alt="img" width="100%" /> 这里选择技术栈,有前端经验的可以选择自己熟悉的技术。我比较熟悉Vue ,所以我就选择了Vue。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/IW6esRnGvtHvgEUo.webp" alt="img" width="100%" /> 这里可以随意,使用JS / TS 都可以。 打开文件夹,就可以看到创建好的项目。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/j59r01AwwtKOqgEi.png" alt="img" width="100%" /> 使用 cursor 打开项目。 # 3、开发 ## 3.1 创建 .cursorrules 文件 我现在习惯在项目开发前,先创建一个 .cursorrules 文件。 > .cursorrules 是一个"指导文件”,告诉AI在不同项目里该用什么方式写代码。 比如风格,命名方式等。 我创建 .cursorrules 的方式就是 从 [Cursor Directory](https://cursor.directory/) 中去找到我自己用到的技术栈,然后丢给chat ,让它给我仿写出 类似的。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/dObqAMaB07wbQRXx.webp" alt="img" width="100%" /> <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/EaJHQwW4lGlr9eZi.png" alt="img" width="300px" /> 直接选第一个就好。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/QlIyhFqewD7ohHnp.webp" alt="img" width="100%" /> 随便找一个复制。 打开 cursor,然后新建一个对话。 将刚刚复制的 .cursorrules 内容粘贴到对话框 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/bhIgRWXVpKzeyj2K.webp" alt="img" width="100%" /> 回车,就生成好了针对我们项目的 .cursorrules 内容了。 点击复制粘贴到 .cursorrules 文件中。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/eIBwgz13U053VZUI.webp" alt="img" width="100%" /> ## 3.2 使用 Chat 生成产品需求文档 我一般刚开始开发的时候,脑海中只有一个 idea ,但是具体如何实现和展示,我是没有思路的,这个时候我会让 AI 帮我写一份产品需求文档,如果可以,我就直接使用了。 还是一样,cursor 中 新建对话。 这让就直接有了一份产品需求文档,点击复制 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/OwhnrMp7HO7w1SMv.webp" alt="img" width="100%" /> 然后把产品需求文档放到 NOTEPADS 中,方便后续使用。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/byaLKdP4TUnUiGxv.png" alt="img" width="580px" /> 将复制的内容粘贴进去。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/HMr0Mb4LEdFtCpb6.webp" alt="img" width="100%" /> 修改文档的名字 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/yMdR3cQw0ftF3Muy.webp" alt="img" width="100%" /> 这样我们就能在 对话中直接 @ 文档了。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/PedexuOKBMhq7gOU.png" alt="img" width="100%" /> ## 3.3 让Cursor 根据 产品需求文档进行开发 首先我们将模式切换到 COMPOSER ,然后选择 agent 模式。模型就使用 Claude-3.5 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/lJQmHtPBa9B7pnEF.png" alt="img" width="100%" /> 然后开始让cursor 开始进行工作。 接着,你就看到Cursor非常快速的帮我完成了相关代码文件的新建和写入了。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/pHTQJra1cjDOIYWF.webp" alt="img" width="100%" /> 同时,你也可以看出,Cursor 在完成我们的任务之后告诉我们该如何安装和测试这个插件。 这里还是要提醒一下,如果你的cursor在中间没有帮你执行打包操作,那需要你自己的手动在终端执行。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/bm9qsENv582UCQJo.webp" alt="img" width="100%" /> # 4、测试迭代 完成上面的基础代码编写后,就可以开始测试和迭代插件了。 这个时候要保持良好的心态,运气好,测试一次通过。 运气不好就只能 再把报错信息复制给cursor 进行修复了。 先在Chrome中打开「扩展程序」界面:chrome://extensions/,并且打开右上角的开发者模式。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/sWHkincbNYWjS8Er.webp" alt="img" width="100%" /> <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/WQ2unnqPqz8pEYTw.webp" alt="img" width="100%" /> 选择打包的插件。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/Qh30UxdLsGUiu0n3.png" alt="img" width="427px" /> 打开一个网站进行查看:[百度一下,你就知道](http://www.baidu.com) <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/FxHKNNpoPgFXJYeK.webp" alt="img" width="100%" /> 哎,运气比较好,居然成功了。 当然,如果大家失败了,可以直接把报错信息复制给 cursor ,让它进行修复即可。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/QwnYnb8GOS0s0chb.png" alt="img" width="519px" /> 一般如果有报错,这里都会显示错误,点击进去,就可以看到具体错误。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/kNwic9d5kNCddzLx.webp" alt="img" width="100%" /> 然后把这个报错信息截图给cursor 进行修复即可。 ## 4.1 迭代 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/BsBrJ5Lr9QaYwkqP.webp" alt="img" width="100%" /> 迭代前,一定要 使用 Git 提交一遍代码 !!!至于Git 是什么,大家可以问问Cursor <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/qQ0qmZZaVITbOwcg.webp" alt="img" width="100%" /> 这里cursor 没有帮我们执行包的构建命令,这就需要我们自己去执行一下了。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/xCUk8vQzZV8ePnJw.webp" alt="img" width="100%" /> 看看最终的效果。 感觉还不错。 <img src="https://pic.code-nav.cn/post_picture/1620630456775032833/yFRjjh7twnAyLJKW.png" alt="img" width="100%" />

24年最新 idea 插件开发教程,面试鸭插件技术实现!

大家好,我是松柏。前几天我们发布了面试鸭 JetBrains IDE 插件,其目的是帮助大家方便、隐蔽的摸鱼刷题,大家可以先安装体验一下。 <img src="https://pic.code-nav.cn/migrate_image/9032125a569837f2acccce3975114dcd.gif" alt="Kapture 2024-09-18 at 16.34.37" width="100%" /> <br><br> 为了帮助大家扩展技术的广度,今天给大家分享下这个插件的技术实现! 完整开源代码:[https://github.com/yuyuanweb/mianshiya-plugin](https://github.com/yuyuanweb/mianshiya-plugin) <br> 首先贴一下官方文档:[https://plugins.jetbrains.com/docs/intellij/welcome.html](https://plugins.jetbrains.com/docs/intellij/welcome.html) 虽然这个文档教学属性比较弱,更多是一些概念、规范,但是给了一些示例代码仓库,还是很有用的。 ## 技术选型 我们先看下使用到的技术栈: + `Gradle IntelliJ Plugin` 插件开发的核心 SDK + `lombok` 简化开发的工具包 + `hutool-core` hutool 工具包的核心模块 + `retrofit2` 网络请求工具包,OkHttp的加强版,也可以使用其他的包 除了插件的 SDK ,没有用到什么特殊的东西。这个 SDK 里的很多内容都继承自 Swing ,所以如果有过相关开发经验的话会更加容易上手,当然了,没有的话影响也不大。 这里值得一提的是,官方还提供了一个新的 SDK : [IntelliJ Platform Gradle Plugin](https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin.html),不过它不兼容较旧版本的 IDE ,个人不推荐大家用。 ## 实现 ### 定义入口 确定了需求和使用的技术之后,就可以开始编码了。 先来明确两个概念: `plugin.xml` 插件的配置文件,定义插件的元数据和配置,比如插件的入口、一些生命周期的监听器。 `tool window` 主 IDE 窗口内的一个窗格,比如 `Project`、`Commit` 都是一个个的 `tool window`。 <img src="https://pic.code-nav.cn/post_picture/1626574509983178753/ZOeqdbBWBwviUptm.webp" alt="" width="100%" /> <br> <br> 首先,我们给插件定义一个入口然后注册到`plugin.xml`中,这样就能在左侧看到我们的图标: ```java @Slf4j public class MyToolWindowFactory implements ToolWindowFactory { private static final Logger logger = Logger.getInstance(MyToolWindowFactory.class); public MyToolWindowFactory() {} @Override public void createToolWindowContent(@NotNull Project project, ToolWindow toolWindow) {} } ``` ```xml <extensions defaultExtensionNs="com.intellij"> <toolWindow canCloseContents="true" icon="/icons/favicon.svg" factoryClass="com.github.yuyuanweb.mianshiyaplugin.toolWindow.MyToolWindowFactory" id="面试鸭"> </toolWindow> </extensions> ``` 并且支持挪到其他我们想要的位置,比如底部: <img src="https://pic.code-nav.cn/post_picture/1626574509983178753/nLO2Ta0fdqO5pUn8.webp" alt="" width="100%" /> ### 顶部导航栏 接下来是顶部的导航栏: <img src="https://pic.code-nav.cn/post_picture/1626574509983178753/xhGBNwucD4qF5u9z.webp" alt="" width="100%" /> <br><br> 在插件开发中,有各种各样的 `manager`,它们用于处理特定功能或资源的管理。比如导航栏这里我们就用到了 `ActionManager`,我们会定义一系列导航行为,并注册到 `ActionManager`上: ```java OpenUrlAction webAction = new OpenUrlAction(WEB_ZH, CommonConstant.WEB_HOST, IconConstant.WEB); actionGroup.add(webAction); actionManager.registerAction(WEB, webAction); ActionToolbar actionToolbar = actionManager.createActionToolbar(ACTION_BAR, actionGroup, true); mainPanel.add(actionToolbar.getComponent(), BorderLayout.NORTH); ``` 不同的导航行为需要对`AnAction`定义不同的实现,比如上述 OpenUrlAction 的作用是用默认浏览器打开一个页面,其定义如下: ```java public class OpenUrlAction extends AnAction implements DumbAware { private final String url; // 构造函数 public OpenUrlAction(String text, String url, Icon icon) { // Action 名称 super(text, text, icon); this.url = url; } @Override public void actionPerformed(@NotNull AnActionEvent e) { // 使用默认浏览器打开指定网址 BrowserUtil.browse(url); } } ``` ### 登录功能 接下来是登录功能,在[面试鸭网页端](https://www.mianshiya.com/)已经提供了扫码登录,所以没必要在插件端再搞一套登录逻辑,不仅麻烦,还有可能负优化用户体验。借用网页端的扫码登录,我们只需要打开一个内嵌浏览器弹窗然后监听登录态并记录就可以了: ```java getJBCefClient().addLoadHandler(cefLoadHandler = new CefLoadHandlerAdapter() { @Override public void onLoadingStateChange(CefBrowser browser, boolean isLoading, boolean canGoBack, boolean canGoForward) { cefCookieManager.visitAllCookies(new CefCookieVisitor() { @Override public boolean visit(CefCookie cefCookie, int count, int total, BoolRef boolRef) { if ("SESSION".equals(cefCookie.name)) { // 记录 session } return true; } }); } }, getCefBrowser()); loadURL(); ``` 这里需要提一下,打开内嵌浏览器需要 `JCEF` 的支持,`JetBrains`系列较低的版本(比如 2021.3 以下)或者某些 IDE (比如 `<font style="color:rgba(0, 0, 0, 0.85);">Android Studio</font>`)是不支持这个功能的,也就是说,这些 IDE 将无法正常使用我们的插件。 ### 题库、题目列表 接下来是插件的核心之一:题库、题目列表的展示。这里以比较简单的题库列表为例给大家讲解。 这块分为三个部分,上面的题库分类,下面的题库列表,以及底部的分页条,其中的数据都来自接口,所以我们先来看下如何从接口获取数据。在本插件中,要用到的接口比较多并且经常会复用一些接口,所以我们选择的网络请求包是 retrofit2 ,方便统一定义、管理这些接口。 首先看下请求工具类的定义: ```java public class ApiConfig { public static MianShiYaApi mianShiYaApi; static { // 自定义 Gson 实例 Gson gson = new GsonBuilder() .registerTypeAdapter(Date.class, new DateTypeAdapter()) .create(); OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new HeaderInterceptor()) .addInterceptor(new LogInterceptor()) .addInterceptor(new ResponseInterceptor()) .build(); String mianShiYaBaseUrl = CommonConstant.API; Retrofit retrofit = new Retrofit.Builder() .baseUrl(mianShiYaBaseUrl) .addConverterFactory(GsonConverterFactory.create(gson)) .client(client) .build(); mianShiYaApi = retrofit.create(MianShiYaApi.class); } } ``` 可以看到,我们在初始化时添加了一些拦截器,用来添加请求头、输出一些日志等。 然后看下题库分类和题库列表两个接口的定义: ```java /** * 获取题库列表 */ @POST("questionBankCategory/list_questionBank") Call<BaseResponse<Page<QuestionBank>>> getQuestionBankList( @Body QuestionBankCategoryBankQueryRequest queryRequest ); /** * 获取题库分类列表 */ @POST("questionBankCategory/list") Call<BaseResponse<List<QuestionBankCategory>>> listQuestionBankCategory( @Body PageRequest pageRequest ); ``` 之后,我们就能在代码中使用 `MianShiYaApi.getQuestionBankList()` 获取数据了。 接下来看题库分类的展示,其实我们要做的就是把 `listQuestionBankCategory 接口`返回的数据展示出来,同时用插件的方式给每个分类绑定对应的事件,部分代码如下: ```java JBPanel<?> labelPanel = new JBPanel<>(new WrapLayout(FlowLayout.LEFT, 5, 5)); ApplicationManager.getApplication().executeOnPooledThread(() -> { List<QuestionBankCategory> tagList = ApiConfig.mianShiYaApi.listQuestionBankCategory(new PageRequest()).execute().body().getData(); ApplicationManager.getApplication().invokeLater(() -> { for (QuestionBankCategory tag : tagList) { JBLabel label = new JBLabel(tag.getName()); label.addMouseListener(new MouseAdapter() { // 点击事件 @Override public void mouseClicked(MouseEvent e) { // 获取数据 searchAndLoadData(queryRequest); } }); labelPanel.add(label); } }); }); ``` 题目列表的展示与之类似,不过是数据的容器从 `JBPanel` 换成了 `MTabModel`: ```java ApplicationManager.getApplication().executeOnPooledThread(() -> { Page<QuestionBank> data = this.fetchDataFromApi(queryRequest); // 创建表格数据模型 ApplicationManager.getApplication().invokeLater(() -> { tableModel = new MTabModel(); // 将数据添加到表格模型 for (QuestionBank row : data.getRecords()) { tableModel.addRow(new Object[]{row.getId().toString(), row.getTitle(), row.getTagList()}); } JBTable table = PanelUtil.createTablePanel(tableModel, (tempTable, mouseEvent) -> { // 双击某一行数据执行 }); }); }); ``` 可能有小伙伴好奇,`executeOnPooledThread`、`invokeLater` 这些东西是干嘛的,我们慢慢道来。 IDEA 整个应用的 UI 渲染都是由主线程也叫事件调度线程(Event Dispatch Thread, EDT)来处理的,一旦这个线程卡住,整个 IDEA 就会卡住,一定要注意,不是当前的插件,而是整个 IDEA 都会卡住!一些严重的异常或耗时操作甚至会导致 IDEA 卡死、卡退,这个体验是极端糟糕的。 `executeOnPooledThread` 的作用就是把操作放到线程池中去执行,防止卡住主线程。 `invokeLater` 的作用是把涉及到 UI 更新的操作放到主线程中,那为什么非要把 UI 更新操作放到主线程呢? 答案很简单,如果不放到主线程,轻则 UI 状态与实际数据状态不一致,造成用户体验不佳;重则干扰主线程的状态,导致 IDEA 卡死! ### 题目详情 为了保证阅读体验,在题目详情页中我们使用了内嵌网页的形式展示内容。 在 `JetBrains` 插件中,我们需要在编辑区打开自定义内容时,一般是以下步骤: + 实现 `FileEditorProvider` 接口:创建一个类,继承 `FileEditorProvider`,定义如何创建和管理自定义编辑器。 + 实现 `FileEditor` 接口:在自定义编辑器类中实现 `FileEditor` 接口,以定义编辑器的行为和 UI 组件。 + 注册编辑器提供者:在插件的 `plugin.xml` 文件中注册自定义的 `FileEditorProvider`,使其能够被 IntelliJ IDEA 识别和使用。 + 处理文件类型:如果需要,定义一个自定义的文件类型,以便在打开特定文件时使用自定义编辑器。 我们这里的核心诉求是 `打开一个内嵌的浏览器` ,在浏览器里展示对应的内容,由于打开的内容是需要校验登录态的,所以在打开浏览器时需要带上对应 `cookie`。 打开内嵌浏览器的简化代码如下: ```java public BrowserFileEditor(@NotNull Project project, @NotNull VirtualFile file) { this.jbCefBrowser = new JBCefBrowser(); this.panel = new JPanel(new BorderLayout()); // 浏览器 jbCefBrowser.getJBCefClient().addLoadHandler(new CefLoadHandlerAdapter() { @Override public void onLoadingStateChange(CefBrowser browser, boolean isLoading, boolean canGoBack, boolean canGoForward) { cookieManager.setCookie(CommonConstant.WEB_HOST, jbCefCookie, false); jbCefBrowser.setJBCefCookieManager(cookieManager); } }, jbCefBrowser.getCefBrowser()); jbCefBrowser.loadURL(url); } ``` 这里说一下在开发时踩的一个大坑:`setJBCefCookieManager`执行之前一定一定一定要确保`JCEF`已经初始化完成,不要直接执行,否则会导致 IDE 卡退!一般的做法是放到 `onLoadingStateChange` 等钩子里,这样就能正常打开一个内嵌网页: <img src="https://pic.code-nav.cn/post_picture/1626574509983178753/exuXiH9VS5jE7P9w.webp" alt="" width="100%" /> <br><br> 以上就是面试鸭插件的大概实现了,我们在实际开发中肯定远比这些复杂,篇幅限制,很多细节就不在这里展开了,大家可以前往 [Github](https://github.com/yuyuanweb/mianshiya-plugin) 页面搜索“mianshiya-plugin”查看源码细节。 有帮助的话欢迎点个赞,祝大家有所收获,拜拜👋🏻!

jetbrains集合v2024+激活码:https://pan.xunlei.com/s/VO55KIYuGFryThtuHpihHQDcA1?pwd=g9qu 不知道为啥放其他盘激活码老是会被违规吞掉🤐,就放迅雷云盘了,不过还好不大也就一百多K 步骤: 1:安装对应的jetbrains,例如idea 2:安装后先打开idea,首次打开会提示专业版需要激活,到这里不用管,直接将idea关闭 3:然后在激活码文件里面找到 "IDEA激活.vbs" 文件,双击打开:显示 ”Success!!! Now you can enjoy Intellilldea to 2099“ ,表示永久激活成功,然后再重新打开idea就破解好了,永久使用

懒人必备!GenCodeByDDL 插件让 Java 代码生成轻松搞定

## 前言 大家好,我是香香。 前几天不是和聪哥一起搞了一个项目嘛,SQL DOG。将鱼皮的 SQL Father 和 SQL Mother 合并在一起了,并且新增了很多功能,比如通过 SQL 慢镜分析给出优化结果、新增 UML 类图展示等等功能。 当然核心功能还就是 **生成代码** 和 **练习 SQL**。 <img src="https://pic.code-nav.cn/post_picture/1661055852716494850/2RjOqRegW5SdiBt4.webp" alt="image.png" width="100%" /> **但是我感觉,虽说可以生成(后端)代码,但是还是得自己一个一个去手动粘贴复制,稍微有一点点麻烦呀~** 我就想着有没有简单一点的方法呢?可以更简单的生成代码,甚至说直接一键生成、批量生成! ## 说干就干 提到一键生成,好像,MyBatisX 插件就有这个功能啊。 <img src="https://pic.code-nav.cn/post_picture/1661055852716494850/5hpOdRC6iVHEKsQX.webp" alt="image.png" width="215px" /> 相信用过的小伙伴肯定也都知道,点点鼠标就可以生成 model、service 等代码。但是我感觉它生成的还是太少了呀。那咋办呢? **索性直接自己搞一个!** 于是乎直接淦了整整一天半!GenCodeByDDL 横空出世!正如其名,根据 DDL 语句来生成代码。 一般我们做项目的时候,编码之前要做的肯定就是设计数据库表结构了,也就是 DDL 语句,是这样的(可以去 [SQLDog](http://124.70.210.130:8099/) 或者 [SQLFather](http://sqlfather.yupi.icu/) 去生成)。 <img src="https://pic.code-nav.cn/post_picture/1661055852716494850/PKXmP19Y7SQz9eTL.webp" alt="image.png" width="100%" /> 有了数据库表之后,接着就是开发功能了。但是很多场景下要做的就是对单表的增删改查,比如 User 用户表的登录注册、查询用户、删除用户等等操作,其实换一张表也是一样的。 那这样的话,这一类代码就相当重复了呀,反复的去写也没有什么意义。一般情况下都有一个初始化模板,星球里面也有,这一类重复的代码是已经提前写好了的。 确实!方便了不少,但是还是得你自己手动去改(手动 Ctrl + Shift + R),当然现在星球的模板中也具备生成这些代码的能力。 ## 插件用法 #### 1. 下载插件( www.xiangworld.cn ) > 复制到浏览器打开,如果打不开的话,可能是被挡了,请站在墙内。 #### 2. 安装插件 因为没有上传也不了解上传,所以只能手动安装。点击 “从磁盘安装插件” 之后导入即可。 <img src="https://pic.code-nav.cn/post_picture/1661055852716494850/S3VzFyFAsVoasRrC.webp" alt="image.png" width="100%" /> #### 3. 插件使用 插件安装完成之后,在刚刚所说的初始化库表 .sql 文件中右击鼠标(或者在左侧文件处右击鼠标)。 <img src="https://pic.code-nav.cn/post_picture/1661055852716494850/bZ0Mu4NKznaVp9ZX.webp" alt="image.png" width="100%" /> 在弹出的对话框中填写自己的包名以及勾选想要生成的代码类型,点击 “确定”。 <img src="https://pic.code-nav.cn/post_picture/1661055852716494850/r55mDRxFFIBZsatV.webp" alt="image.png" width="100%" /> <br/><br/> <img src="https://pic.code-nav.cn/post_picture/1661055852716494850/OVXfyDvoT4GTXEWn.webp" alt="image.png" width="100%" /> 这样代码就生成在了 generator 目录下。 <img src="https://pic.code-nav.cn/post_picture/1661055852716494850/NhlEv2pIWQo4Xix4.webp" alt="image.png" width="100%" /> 之后进行拖拽重构即可。 ## 支持生成的类型 - Controller / Service(Impl) / Mapper - Entity / DTO / VO - CorsConfig / Mapper.xml / Pom.xml(代码所需依赖)/ Knife4jConfig > 目前类型虽然不多,但是感觉已经足以帮助我们省去非常多的时间了。 > > 类型丰富之后甚至可以一键生成一个项目出来(bushi)。 ## 项目思路 1. 获取 sql 语句; 2. 使用正则表达式进行分离; 3. 使用 Alibaba 的 Druid 或其他 SQL 解析器进行解析封装; 4. 通过 FTL 模板进行代码生成; > 如果有更好更简单更高效的方法可以提出来。 ## 最后 虽然是可以实现代码生成,看起来和 MyBatisX 插件的功能差不太多。但是肯定肯定还是不能和人家相媲美,还是很简陋的,有人使用或者遇到 Bug 可以提出来,谢谢! 目前也还是有些不完美的,后面还会继续迭代在官网,有感兴趣的小伙伴可以持续关注! `若使用还请保证 SQL 语句正确。` GitHub:[我是 GitHub](https://github.com/xiangxiang62/genCodeByDDL)

从零写一个基于油猴脚本的 Google 辅助插件(文末附完整代码)

<html> <head></head> <body> <div class="content ql-editor"> <h2>前言</h2> <p>大家好,我是松柏!<br>不知道大家平时开发的时候喜不喜欢用快捷键呢?我本人是一个重度快捷键用户,在使用 Google 的时候发现,只能点击而不能通过快捷键选中搜索结果。<br>比如这里我想看第二个搜索结果,那只能通过点击的方式,于是我就在想能不能通过一个简单的脚本给这些搜索结果绑定上快捷键呢?<br><img src="https://pic.code-nav.cn/planet_post_image/1626574509983178753/2gxjdq54.jpeg" alt="image.png"></p> <h2>效果展示</h2> <p>首先给大家看一下最后终的效果:<br><img src="https://pic.code-nav.cn/planet_post_image/1626574509983178753/x2s954qz.jpeg" alt="image.png"><br>我这里通过 command + option + 序号就能进入特定的搜索结果,比拿起鼠标去点要快多了。<br>长期累积下来不知道省了多少时间,这些时间拿来学习(摸鱼)不香吗?</p> <h2>实现流程</h2> <h3>选择平台(框架)</h3> <p>因为我平时基本都是用 Chrome 浏览器,所以我首先想到的是写一个 Chrome 浏览器插件来实现。但是稍微了解一下之后发现需要注册开发者账号,而且开发成本有点高,跟我的需求不匹配,所以放弃了这个想法。<br>然后撇到了浏览器上的油猴插件:<br><img src="https://pic.code-nav.cn/planet_post_image/1626574509983178753/rt4dwq6q.jpeg" alt="image.png"><br>突然就觉得或许基于油猴实现会很不错,因为油猴脚本是用 JavaScript 写的,而且之前或多或少接触过,不像 Chrome 插件开发一样没怎么了解过。</p> <h3>实现思路</h3> <p>首先再明确下需求,就是给搜索结果绑定快捷键。<br>那么可以这样做:</p> <ol> <li data-list="ordered"><span class="ql-ui"></span>获取搜索结果列表</li> <li data-list="ordered"><span class="ql-ui"></span>在每个搜索结果前放一个序号</li> <li data-list="ordered"><span class="ql-ui"></span>通过特定按键+序号触发点击事件,点击对应的搜索结果</li> </ol> <h3>编码实现</h3> <p>让我们按照上述实现思路来一步步实现。<br>1)打开 F12 ,可以发现所有的搜多结果带有特定的 class 属性<code>LC20lb MBeuO DKV0Md</code>。那我们就可以通过这个属性很轻易的获取到搜索结果。</p> <div class="ql-code-block-container"> <div class="ql-code-block"> let className = 'LC20lb MBeuO DKV0Md' document.getElementsByClassName(className) </div> </div> <p>但这个时候获取到的并不是数组结构,而是 <code>HTMLCollection</code>对象(本文不深究这个对象,感兴趣可参考<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCollection" target="_blank">文档</a>了解)。<br>我们可以通过<code>Array.from</code>将其转为标准的数组对象。<br>还有一个问题,就是我们其实没有必要获取所有的搜索结果,比如我往下滑了几屏的高度,其实只需要获取到在当前屏幕内的就可以了。<br>所以我们完善一下这段代码:</p> <div class="ql-code-block-container"> <div class="ql-code-block"> // 类名 let className = 'LC20lb MBeuO DKV0Md'; const result = Array.from(document.getElementsByClassName(className)).filter(node =&gt; node.getBoundingClientRect().top &gt; 0); </div> </div> <p>2)接下来通过操作<code>DOM</code>节点的方式在每个搜索结果前加上一个序号</p> <div class="ql-code-block-container"> <div class="ql-code-block"> for (let i = 0; i &lt; result.length; i++) { const node = result[i]; let newSpan = node.parentNode.getElementsByClassName("p_no")[0]; if (newSpan) { newSpan.remove(); } // 创建一个新的 span 元素 newSpan = document.createElement("span"); newSpan.style = 'font-size: 30px;color: skyblue' newSpan.className = 'p_no' newSpan.innerHTML = i + 1; node.parentNode.insertBefore(newSpan, node);// 设置 span 元素的内容 } </div> </div> <p>3)然后监听键盘的输入事件,并触发相应的<code>click</code>事件</p> <div class="ql-code-block-container"> <div class="ql-code-block"> //获取被按下的键值 let keyNum = window.event ? e.keyCode : e.which; // 打开页面 if (e.metaKey &amp;&amp; e.altKey) { if (keyNum &gt;= one &amp;&amp; keyNum &lt;= nine) { // 类名 let className = 'LC20lb MBeuO DKV0Md'; const result = Array.from(document.getElementsByClassName(className)).filter(node =&gt; node.getBoundingClientRect().top &gt; 0); result[keyNum - 49].click() } } </div> </div> <h2>扩展</h2> <p>我最初的想法是写到这里就可以了,但是发现一个很尴尬的点:如果我可以通过快捷键选择搜索内容,但还是需要鼠标来往下滑动网页,也太抽象了吧!<br>于是我又想补充一下通过快捷键使网页往下滑动的功能,实践之后发现<code>window.scrollBy</code>的下滑是跳跃式的,就是直接往下挪了一段距离,没有鼠标往下滑的顺滑感。更尴尬的是我不知道怎么描述我的问题,没法百度。这时候就轮到 AI 出场了,于是就有了下面这段代码:</p> <div class="ql-code-block-container"> <div class="ql-code-block"> // 实现滚动动画 function scrollWithAnimation(targetPosition) { const startPosition = getScrollPosition(); // const distance = targetPosition - startPosition; const duration = 1500; // 动画持续时间,单位毫秒 let startTime; function step(timestamp) { // startTime 开始时间 // timestamp 当前时间 if (!startTime) startTime = timestamp; // 已执行时间 const progress = timestamp - startTime; // 当前进度, 0 - 1 之间 const percentage = Math.min(progress / duration, 1); const easing = easeOutQuad(percentage); window.scrollBy(0, targetPosition * easing); if (progress &lt; duration) { requestAnimationFrame(step); } } requestAnimationFrame(step); } // 线性插值函数 function easeOutQuad(t) { return -1 * t * t + 1; } </div> </div> <p>其中值得一提的是,AI 给的代码问题很多(特别是<code>线性插值函数</code>,测试了半天才搞懂这个函数和滚动动画的关系),不能直接用。但其实已经给我提供了实现方案和思路,这也就够了,稍微改一下就能用了。</p> <h2>完整代码</h2> <p>Github:<a href="https://github.com/co-pine/google-search-helper" target="_blank">https://github.com/co-pine/google-search-helper</a><br>直接把<code>index.js</code>的代码复制下来放到油猴中就能直接用啦!<br> 原文链接(阅读体验会更好一点): <a href="https://mp.weixin.qq.com/s/CMr_4OwegYr2-wnOzgHtOw" target="_blank">https://mp.weixin.qq.com/s/CMr_4OwegYr2-wnOzgHtOw</a></p> #插件开发# </div> </body> </html>

从 0 到 1 实现一个 chrome 插件

<html> <head></head> <body> <div class="content ql-editor"> <p>大家好, 我是晨光,5 年前端开发程序媛,没想到第一篇小 y 给加了精华:<a href="https://t.zsxq.com/0frC1H9z9" target="_blank">https://t.zsxq.com/0frC1H9z9</a></p> <p><br></p> <p>今天分享一篇我的技术探索,实现一个简单的 chrome 插件。</p> <p><br></p> <p>之前做需求的时候,每次都需要手动拿页面上的几个参数去拼一个新的 url,操作耗时繁琐,且没有技术含量,所以就尝试写了 chrome 插件。本次内容分为以下三个部分:</p> <ol> <li data-list="bullet"><span class="ql-ui"></span>功能介绍</li> <li data-list="bullet"><span class="ql-ui"></span>从 0 到 1</li> <li data-list="bullet"><span class="ql-ui"></span>待拓展功能</li> </ol> <p><br></p> <p><strong>一、功能介绍</strong></p> <p><strong><br></strong></p> <p>插件一般都是为了方便我们的日常工作。</p> <p>本次分享的插件功能简单,主要是减少了复制粘贴的重复工作,且人为的复制粘贴有时也会存在一些误差,而对于代码来说,就是一个简单的规则。</p> <p>只要规则没有问题,那么输出的内容大概率都是正确的。</p> <p><br></p> <p><strong>二、从 0 到 1</strong></p> <p><br></p> <p><strong>1、参考资料</strong></p> <p><strong><br></strong></p> <p>第一次写 chrome 插件,不知道怎么开始,就去百度搜索了一圈,根据 chrome 插件开发文档,一步一步模仿。</p> <p><span style="color: rgb(143, 149, 158);">参考链接:</span><a href="https://support.google.com/chrome/a/answer/2714278?hl=zh-Hans" target="_blank" style="color: rgb(143, 149, 158);">https://support.google.com/chrome/a/answer/2714278?hl=zh-Hans</a></p> <p><br></p> <p><strong>2、准备工作</strong></p> <p><strong><br></strong></p> <p>大致浏览完上面的文档,开始开发</p> <p><br></p> <p>1)创建文件夹以及相关文件,最主要的文件是 <a href="http://mainfest.json" target="_blank">mainfest.json</a> 文件,里面包含插件名称等一些插件配置相关的内容。</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1639205986650562562/8ryyuegv.jpeg"></p> <p><br></p> <p>2)准备插件 icon,注意尺寸要求,可以去阿里矢量图库里面下载,或者自己切图都可,晨光这里是从阿里矢量图库里面下载了一个大拇指。</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1639205986650562562/rtzwqzsn.jpeg"></p> <p><br></p> <p>3)实现功能代码 功能代码在 scripts/<a href="http://content.js" target="_blank">content.js</a> 里。这里的实现没有过多需要注意的地方,就正常写 js 即可</p> <p><br></p> <p><strong>3、开发过程</strong></p> <p><strong><br></strong></p> <p>大致过程,需要先获取页面元素,如果能够找到,那么开始拼接参数,参数拼接好之后,创建 a 标签,并插入到页面的某个位置中。然后就可以点击跳转到我们想去的某个链接。具体实现如下图</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1639205986650562562/cth9rdys.jpeg"></p> <p>我们把插件导入到浏览器中,只要 url 命中 <a href="http://manifest.json" target="_blank">manifest.json</a> 文件中的 matches 的url,插件就会工作</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1639205986650562562/70rff3hf.jpeg"></p> <p>但调试过程中,多次刷新页面,代码都不生效,而 copy 代码到控制台可正常执行,无 js error,并且页面也可以出现我们想要的效果。</p> <p><br></p> <p>经分析后得出,页面加载还未完成就执行了插件代码,走到 39 行,因无法找到 id=app 的 DOM 元素,因此进不到 if 语句中,并且代码不会重试,所以,就给这段代码套了一个 setTimeout,插件代码加载两秒后再执行,发现插件的功能大部分时候都可运行成功。</p> <p><br></p> <p><strong>4、投入使用</strong></p> <p>插件加载完成</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1639205986650562562/3ve948nz.jpeg"></p> <p>浏览器右上角会有一个大拇指的插件图标</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1639205986650562562/s7o8yuz6.jpeg"></p> <p>打开对应目标页面,插件执行完,页面中会插入下图的两个链接</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1639205986650562562/17sl5pzt.jpeg"></p> <p><strong>三、待拓展功能</strong></p> <p><br></p> <p>1、插件未发布,目前使用都是本地压缩包分享,对于功能完善且不涉密的内容,可以尝试发布插件</p> <p>2、插件功能单一,可尝试拓展新功能,能够解决日常浏览痛点的,但暂时没有什么好想法,有想法的也可以私我,共创~</p> <p><br></p> <p><strong>总结</strong></p> <p><br></p> <p>本次开发过程耗时半天,功能满意程度总体评分 6 分,勉强及格啦。初步试水,后面工作之余也会捣鼓捣鼓别的好玩有趣有用的东西。</p> <p><br></p> <p>感谢阅读,如果本文对你有帮助的话,点个赞再走吧~</p> </div> </body> </html>

下载 APP