再也不用手动写 cursor: pointer 了!一个 Babel 插件帮你自动解决 99% 的手型光标问题

你有没有遇到过这种情况:

  • 写了一个可点击的 <div>,上线后被测试同学疯狂吐槽:"这个能点吗?为什么鼠标没变成小手啊!"
  • 为了避免被反复教育,你养成了"凡是加了 @click/onClick 就手动写 cursor: pointer"的强迫症
  • 结果又被 UI 同学骂:"你怎么把我的 cursor: help / wait / move 给覆盖了!"

从今天起,这些烦恼都可以彻底终结了!

我开发了一个极度"懒人福音"级别的 Babel 插件 ------ babel-plugin-pointer,已经正式发布到 npm!

项目地址:www.npmjs.com/package/bab...

💡 问题:为什么我们总忘记加 cursor: pointer

在开发中,我们经常这样写:

vue 复制代码
<!-- Vue 3 -->
<button @click="handleClick">点击我</button>
React 复制代码
<!-- React -->
<button onClick={handleClick}>点击我</button>

但结果呢?鼠标悬停时,按钮可能还是默认的箭头(cursor: default),这会让用户体验大打折扣。

更糟的是:

  • 团队新人忘记加
  • 临时修改代码时遗漏
  • 项目规范不明确
  • 设计师说:"这个按钮怎么没手型光标?"

手动维护不仅麻烦,还容易遗漏!

🔥 为什么需要 babel-plugin-pointer

我开发了这个 ​纯 Babel 插件 ​,它在编译时 自动为所有带有点击事件的元素添加 cursor: pointer,​无需任何额外代码​。

✅ 为什么说它超好用?

传统方式 babel-plugin-pointer
需要手动在每个元素加 cursor: pointer 自动添加​​,无需修改任何业务代码
容易遗漏,影响用户体验 100% 覆盖所有带点击事件的元素
无法智能判断是否已有样式 智能检测​,尊重现有样式(不会覆盖)
需要额外 CSS 代码 零运行时开销​,纯编译时处理

🧠 智能检测:为什么它不会覆盖你的样式?

这是 babel-plugin-pointer 最厉害的地方 ------ ​它不会覆盖你已有的 cursor 样式​。

插件在运行时会执行以下检查:

  1. 元素是否有内联 style.cursor? → 如果有,跳过
  2. 否则,用 window.getComputedStyle() 检查计算后的 cursor 值
  3. 只有当值为 autodefault 时,才设置 cursor: pointer

这意味着:

  • <button style="cursor: help"> → 保持 help
  • <div class="custom-cursor" @click> + .custom-cursor { cursor: move; } → 保持 move
  • 普通 <button @click> → 自动变 pointer

非侵入式设计,尊重你的每一行 CSS!

🛠️ 30 秒快速上手

1. 安装插件

scss 复制代码
npm install babel-plugin-pointer --save-dev

2. 配置(Vue 3 + Vite)

javascript 复制代码
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
  plugins: [
    vue(),
    {
      name: 'vue-babel-pointer',
      async transform(code, id) {
        if (id.endsWith('.vue')) {
          const result = await transformAsync(code, {
            plugins: ['babel-plugin-pointer/vue'],
            filename: id,
            sourceMaps: true
          });
          return result ? { code: result.code, map: result.map } : null;
        }
      }
    }
  ]
})

3. React 项目

java 复制代码
// babel.config,js
module.exports = {
  plugins: ['babel-plugin-pointer/react']
}

⚡ 为什么说它"零成本"?

  • 零运行时依赖:纯编译时转换,运行时辅助函数仅 1KB
  • 无布局抖动 :使用 setTimeout(..., 0) 延迟检查
  • TypeScript 友好:无缝集成 TS 项目
  • 无需学习成本:配置简单,开箱即用

💡 适用场景

  • 快速原型开发(省去样式细节)
  • 统一团队交互规范(避免"忘记加 cursor")
  • 遗留项目增强用户体验
  • 教学 demo(让学生专注逻辑而非样式)
  • 任何需要确保点击元素有手型光标的场景

✨ 为什么我开发了这个插件?

在开发中,我经常因为忘记加 cursor: pointer 而被 UI 评审打回。后来我意识到:为什么不能让机器自动处理这些小事?

babel-plugin-pointer 就是这种思路的实践------​让机器做机器的事,开发者只该关注创造​​。

❤️ 你的支持就是我的动力

  • Star:在 GitHub 上给这个项目点个 Star
  • 🐛 Issue:发现 bug 或有建议?欢迎提交 Issue
  • 💬 分享:把这篇文章分享给你的同事,一起告别"手型光标"烦恼
  • 持续优化:后续将支持自定义光标值、元素过滤等

让机器做机器的事,开发者只该关注创造。

相关推荐
护国神蛙1 个月前
自动翻译插件中的智能字符串切割方案
前端·javascript·babel
momo(激进版)3 个月前
babel使用及其底层原理介绍
babel
若梦plus4 个月前
Babel中微内核&插件化思想的应用
前端·babel
前端工作日常4 个月前
我学习到的babel插件移除Flow 类型注解效果
前端·babel·前端工程化
前端工作日常4 个月前
我学习到的 Babel 配置
前端·babel·前端工程化
hans7748829684 个月前
通过为前端项目接入GeoGebra,初步研究AI时代数学教案的生成方案
前端·vite·babel
_一两风4 个月前
深入浅出Babel:现代JavaScript开发的"翻译官"
前端·babel
bigyoung4 个月前
babel 自定义plugin中,如何判断一个ast中是否是jsx文件
前端·javascript·babel
Nu115 个月前
@babel/preset-env的corejs、@babel/plugin-transform-runtime的corejs之间区别
前端·babel