朱焱伟 发表于 2022-10-8 00:00:10

基于vite和rollup的两种油猴工程化方案

本帖最后由 朱焱伟 于 2022-10-8 00:07 编辑

# vite和rollup的两种油猴工程化方案
## 两种油猴工程化脚手架的使用
### 基于vite的(https://github.com/lisonge/vite-plugin-monkey)
```sh
pnpm create monkey
pnpm install
pnpm run dev
```
在`pnpm run dev`之前,最好在vite.config.js里把match的地址改下
```
match: ['https://www.google.com/']
// e.g 改成 match: ['https://www.baidu.com/']
```
比如把默认的谷歌改成百度,然后去看效果。

具体设置,阅读[油猴脚本工程化在vite的最佳实践](https://segmentfault.com/a/1190000042187217)

### 基于rollup的(https://github.com/curly210102/create-tampermonkey)
```sh
npx create-tampermonkey helloworld
cd helloworld
pnpm install
pnpm run dev
```
- 打开Tampermonkey油猴插件的选项Allow access to file URLs
[油猴设置界面chrome://extensions/?id=dhdgffkkebhmkfjojejmpbldmpobfkfo](chrome://extensions/?id=dhdgffkkebhmkfjojejmpbldmpobfkfo)
`Manage Extensions>tampermonkey>Details 'Allow access to file URLs'`=>打开
- 复制命令行中dev.user.js的地址,在油猴里点击安装

具体设置,阅读(https://juejin.cn/post/7022654292880424991#heading-4)

## 已知的几种油猴工程化方案
- viteのmonkey (https://github.com/lisonge/vite-plugin-monkey)
- curlyのrollup插件 (https://www.npmjs.com/package/create-tampermonkey)
- 脚本猫王のwebpack插件 (https://github.com/scriptscat/scriptcat-webpack-plugin)
- Kishedのwebpack插件 (https://bbs.tampermonkey.net.cn/thread-2840-1-1.html)
- 暴力猴のrollup插件 (https://violentmonkey.github.io/guide/using-modern-syntax/)

目前油猴脚本工程化解决方案很多,我知道的有上面几种,其中油中的老哥们造了两个基于webpack的轮子,给油猴工程化带来了多样性。

## 可读性和关键词提升
个人有个痛点,就是我希望托管在脚本猫站上的脚本具有可读性,不是大型脚本的话开个github的仓库不是很有必要。没有可读性,也可以,如果能从user.js大概还原出整个工程,我也满足了。
有没有一种可能,使用rollup打包,只通过一个user.js还能还原出整个工程?
一之哥在[暴力猴脚本工程化](https://bbs.tampermonkey.net.cn/thread-3380-1-1.html)的帖子回复里告诉我,webpack有一个devtool = 'source-map'的选项,可以打包出一个勉强可读的脚本文件,rollup里应该也有类似的。

rollup里确实有类似的,在rollup.config.js里设置`sourcemap: 'inline'`:
```
function devConfigs() {...
return defineConfig({...
    output: {...
       sourcemap: 'inline'
    }
}
}
```
这样设置sourcemap为'inline'后,就会在输出的user.js后的最后一行加上一行sourceMappingURL的base64编码的注释(一行,很长)
```
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjo...
```
通过这个注释,就能实现编译后的user.js,映射到真正的多个文件的源代码。在脚本match后的网站开F12的sources,在油猴文件夹下,能看到src目录里面原来的代码,这样就通过一个user.js还原出了整个工程的源代码。

我并不会设置rollup,知道这个是因为上面所说的,基于rollup的(https://www.npmjs.com/package/create-tampermonkey)这个工具,默认开箱生成的user.js就帮我们把这个工作做了。不仅如此,这个(https://www.npmjs.com/package/create-tampermonkey)还内置自动生成 UserScript Header的功能。

之前`笑尘天雨`老哥在做rollup自动提升关键字插件,大概功能是通过写注释的方法把提取到头部注释UserScript中;而(https://github.com/curly210102/create-tampermonkey)构建工具内置(https://www.npmjs.com/package/rollup-plugin-tampermonkey-header)插件,可以达到不写注释,直接写GM\_*函数,就直接在编译出来的user.js文件头生成`// @grant GM_*`的效果。这个过程,对脚本作者来说,是透明的,并不需要关心。我试了下,搭配(https://marketplace.visualstudio.com/items?itemName=darxeal.tampermonkey-snippets),写个GM_出来提示补全,同时自动在user.js生成文件头,确实很舒适。

所以: 代码提示上,可以通过vscode补全插件tampermonkey-snippets实现GM_*代码补全;关键词提升上,(https://github.com/curly210102/create-tampermonkey)也能帮我们生成user.js的文件头;可读性上,自动生成的`//# sourceMappingURL=`可以帮我们从一个user.js还原整个工程。
在这几个方面,我对基于rollup的(https://www.npmjs.com/package/create-tampermonkey)的评价是,十分满意。

## jsx语法和框架支持

但是`create-tampermonkey`对jsx语法和框架支持上,并不能开箱可用。可以开箱即用的,是基于vite的(https://github.com/lisonge/vite-plugin-monkey),这个`monkey`脚手架用起来,可以支持hmr,体验更加好,推荐使用。从(https://esbuild.github.io/)上的动图,可以看到vite的esbuild具有速度优势。关于preact/react/svelte/vanilla/vue/solid,这个脚手架还提供了一些例子:(https://github.com/lisonge/vite-plugin-monkey/tree/main/packages/create-monkey),可作为参考。好处不多说,与正常 vite 项目开发体验一致。

## 优缺点和改进
create-tampermonkey的优缺点:
- 好处是可读性,可还原性,rollup能自动提升关键字
- 缺点是jsx语法和框架支持不能开箱即用
- 同步代码方法和脚本猫有冲突

vite-plugin-monkey的优缺点:
- 好处是速度快,jsx语法,丰富的框架支持,模块热替换hmr,开箱即用,自动注入脚本配置头部注释
- 缺点是可读性(个人需要)

### create-tampermonkey的改进
create-tampermonkey在跑起来之后,勾选油猴管理器的`Allow acess to file URLs`选项,就能打开user.js自动弹出安装界面。这个安装界面安装的是一个空脚本(`dev.user.js`),其唯一作用就是require本地即时编译的`main.dev.user.js`,这是它的代码同步到浏览器的方法。
而脚本猫vscode插件同时也监测到user.js变化并同步到浏览器,这样就可能出现两个相同脚本的情况,摧毁小猫咪之后,可能会出现端口占用的情况.能用,但有点麻烦。
另外,它并不能开箱就支持jsx,作为一个基于rollup的脚手架,暴力猴脚手架支持jsx,那能不能把这个功能加进来?理论可行,但需要配置babel.config.json.暴力猴能用jsx,是因为(https://violentmonkey.github.io/vm-dom/)和(https://github.com/violentmonkey/vm-ui),以及babel翻译。
```js
// @require https://cdn.jsdelivr.net/npm/@violentmonkey/dom@2
// @require https://cdn.jsdelivr.net/combine/npm/@violentmonkey/dom@2,npm/@violentmonkey/ui@0.7
```
这可以在`src/meta.json`里去设置
```json
"@require":["某url1","某url2","某url3"]
```
设置之后,可以使用`document.body.append(VM.m(VM.h("div", null, "hello, world")));`语句,但仍然不可用jsx语法,因为还没有设置babel来翻译。这在暴力猴脚手架里是这样设置`babel.config.js`的:
```js
// 暴力猴的babel.config.js
plugins: [
    ['@babel/plugin-transform-react-jsx', {
      pragma: 'VM.h', // use 'VM.hm' if you don't need SVG support and don't want to call VM.m
      pragmaFrag: 'VM.Fragment',
    }],
],
```
我们只需用同样的方法,在`create-tampermonkey`生成的工程里这样去设置`babel.config.json`应该就能支持jsx。
(然而,我并不知道怎样去设置`babel.config.json`。。。)
### vite-plugin-monkey的改进
可读性可能并不是这个脚手架本身的缺点,只是我个人想让他也能像`create-tampermonkey`那样具有可还原源码的功能,如果这个问题解决了,这个vite脚手架就完美了。经过对sourcemap的设置,我开始先得到:
```
//# sourceURL=chrome-extesnion:/xxxx/user.js
```
从这个url点进去,是在油猴管理器里查看编译之后的user.js,这个没什么用。再尝试,得到:
```
//# sourceMappingURL=data:application/json;charset=utf-8;base64,xxxx
```
这次点进去看,得到源码了,但是是vite起的本地服务器里面的源码,还是没什么用。
(不知道怎么设置vite的sourcemap选项,以得到具有可还原性的sourceMappingURL,让user.js和其他东西解耦)
## sourcemap还原
`create-tampermonkey`生成的user.js可以还原工程源码,还有一个简单的判断方法,就是在[在线source-map-visualization](http://sokra.github.io/source-map-visualization/)网站,点击`custom`按钮,把`dist/main.dev.user.js`上传,然后你就能看到整个工程的源码。还有个相应的(https://github.com/lydell/source-map-visualize)命令行工具,但没跑成功,似乎是这个cli工具依赖在线网站。
## 总结
vite的油猴脚手架是最好用的,的确属于最佳实践,可以一试,rollup的油猴脚手架次之。
本文留下两个关于怎么配置的问题:
- 配置`create-tampermonkey`生成的工程,使之支持jsx语法
- 配置`vite-plugin-monkey`生成的工程,让他生成完整可用的sourcemap

具体一点,就是让rollup脚手架支持jsx的语句;让vite脚手架生成`//# sourceMappingURL=`的注解,使之编译出的user.js放到在线网站上能看到源码。这两个问题,我搞不定,看看有没有什么方法。
## 相关资料
- [油猴脚本工程化在vite的最佳实践](https://segmentfault.com/a/1190000042187217)
- (https://github.com/lisonge/vite-plugin-monkey)
- (https://juejin.cn/post/7022654292880424991#heading-4)
- (https://github.com/curly210102/create-tampermonkey)
- (https://www.npmjs.com/package/rollup-plugin-tampermonkey-header)
- [笑尘天雨のrollup-plugin-tampermonkey-auto-meta](https://www.npmjs.com/package/rollup-plugin-tampermonkey-auto-meta)
- [在线还原油猴脚本sourcemap的source-map-visualization](http://sokra.github.io/source-map-visualization)
- (https://github.com/Eished/douyu-helper)
- (https://marketplace.visualstudio.com/items?itemName=darxeal.tampermonkey-snippets)
- [在线source-map-visualization](http://sokra.github.io/source-map-visualization/)
- (https://resultfor.dev/431514-how-to-use-sourcemaps-to-restore-the-original-file)

王一之 发表于 2022-10-8 00:48:07

哥哥用心了,资料很全!没想到之前写的webpack的插件哥哥也找到了

不过也只是一个拼接油猴header的插件,算不上什么工程化,原本还想搞脚手架的,看了有挺多轮子就无限延期了

wwwwwllllk 发表于 2022-10-8 11:00:13

ggnb!!!!!!!!!!!!!!!!!

shabby 发表于 2022-10-14 11:04:49

你好,我是 vite-plugin-monkey 的作者,首先谢谢你推荐我写的工具
1.关于你说的 “有没有一种可能,使用rollup打包,只通过一个user.js还能还原出整个工程?”

这是完全可以的,你之所以没有看到 sourcemap,这是因为我在 https://github.com/lisonge/vite-plugin-monkey/blob/724c5786ac86a565fd9e252142d2c37e80793ffd/packages/vite-plugin-monkey/src/node/index.ts#L313 把它关掉了

我关掉它是因为我认为脚本运行的时候实际上是被一个 warpper 函数包裹运行的,并不是直接运行单个文件, 另外 sourcemap 会使得构建的 dist.user.js 文件大小增加,另外开发的时候是在 serve 模式下

这些都使得 build 模式下的 sourcemap 意义不大

但是你这个想法是很好的,我后续会在插件里让它支持 sourcemap


2.关于你说的 “个人有个痛点,就是我希望托管在脚本猫站上的脚本具有可读性,不是大型脚本的话开个github的仓库不是很有必要。”

实际上,你可以把多个小型脚本放在单个仓库管理, pnpm monorepo 是最适合这种项目结构的 ,也可以看这个其他人写的这个示例 https://github.com/pionxzh/userscripts.git



朱焱伟 发表于 2022-10-14 13:01:09

shabby 发表于 2022-10-14 11:04
你好,我是 vite-plugin-monkey 的作者,首先谢谢你推荐我写的工具
1.关于你说的 “有没有一种可能,使用rol ...

非常感谢作者大佬给我们写出这么好用的工具,没想到得到亲自回复了。
1.关于sourcemap
老哥的这个回答就是我想得到的,之前一直不明白。认同'sourcemap在build模式下意义不大',对我个人来说,油猴下sourcemap作用不是开发调试,只是想在发布脚本时能看到源码。(自己写的脚本没什么价值,可能发布之后就扔了,但怕之后不好维护)

2.monorepo
我密切关注老哥的动向,在发帖之后,我在v2ex也看到了相关回复,正准备用monorepo:
(https://www.v2ex.com/t/851687)
> 我认为 `单个仓库里有多个油猴脚本的项目结构` 其实很适合 我这个插件使用的 pnpm ( https://juejin.cn/post/6944877410827370504) ,这个和用 vite 还是 webpack 构建没有关系。

老哥很热心肠,帮别人用重构了项目:(https://github.com/duanluan/tampermonkey-scripts/pull/1)

shabby 发表于 2022-10-17 20:29:15

(https://github.com/lisonge/vite-plugin-monkey/blob/v2.8.0/packages/vite-plugin-monkey/CHANGELOG.md) 已支持为 build.user.js 生成正确的 sourcemap 映射

在正确的配置下,devtools 控制台输出记录显示右侧的代码行将是正确的原始行

关于这块的代码注释说明见 (https://github.com/lisonge/vite-plugin-monkey/blob/30b7f9fe9fa658ec7778c3759a62e0a6d6aebe6a/packages/vite-plugin-monkey/src/node/types.ts#L309-L335)

朱焱伟 发表于 2022-10-17 20:37:37

shabby 发表于 2022-10-17 20:29
(https://github.com/lisonge/vite-plugin-monkey/blob/v2.8.0/packages/vite-plugin-monkey/C ...

从v2.8.0-alpha.0版已经试用,很好用!

13728741411 发表于 2022-11-19 22:45:55

ggnb!!!

wwwwwllllk 发表于 2022-12-1 20:21:06

shabby 发表于 2022-10-14 11:04
你好,我是 vite-plugin-monkey 的作者,首先谢谢你推荐我写的工具
1.关于你说的 “有没有一种可能,使用rol ...

又看了一遍,哥哥牛逼

wwwwwllllk 发表于 2022-12-1 21:13:21

shabby 发表于 2022-10-17 20:29
(https://github.com/lisonge/vite-plugin-monkey/blob/v2.8.0/packages/vite-plugin-monkey/C ...

发现确实有了映射了,但是我见过build以后的代码也可以进行source-map映射(就是打包上传的代码,我记得谷歌工具下面点击sourcemap就可以点到没有压缩的代码的位置了),不知道是怎么设置的
页: [1] 2
查看完整版本: 基于vite和rollup的两种油猴工程化方案