Oil monkey plugin
Oil monkey plug-in refers to Tampermonkey, Violentmonkey, Greasemonkey and other browser extensions that inject js into pages
By injecting specific js when the web page is loaded by the browser extension to change the page layout effect, etc. everything js can do
These extensions also provide some APIs that web pages do not have, so that the injected js can break through the default restrictions of web pages and realize other functions
Existing oil monkey script development mode
The existing oil monkey script generally has two development modes
Extended built-in editor
This is pure handwriting, only native js can be written, no code hints, no concept of modules, only the library of npmjs.com can be used through @require
Since there is no engineering concept and no hot module replacement, when there is any change in the code, the host page must be refreshed to view the effect.
And the code can only be in a single file, the function is less, but the function and project are slightly larger, it is completely unsuitable for editing
This is a completely backward way, and the efficiency and development experience are extremely low
webpack/rollup/uglify-js/esbuild
This kind of development method is a great improvement compared to the former. With the concept of modularization and packaging, the development method has also been changed from a simple editor to vscode, code hints, and typescript are not a problem
The developer should write the bridging code in the extension editor in advance, for example, write path/dist/js in @require of userscript, or write dynamically added script src=path/dist/js under userscript
However, rollup/uglify-js/esbuild does not support hot module replacement (hmr), only webpack supports it
Just imagine, if there is no module hot replacement of your code, every time you change your code in vscode, you have to manually refresh the host page, and manually click to restore the state of the page just now, which is not a little bit worse than the experience when developing vue/react.
However, the hot module replacement of webpack also has problems in this code injection mode, because 代码的来源
and 代码的运行环境
are not a source, and the webpack dev server is designed only considering the same source Case
And webpack dev server is a plug-in, not a core function. For example, if I want to intercept requests from any path in the form of middleware, I can't do it.
As a result, the existing webpack-based oil monkey script plug-in development experience is indescribable
Advantages of vite
Compared with webpack, vite's biggest improvement is speed and out-of-the-box use. I believe that those who have used vite can experience its advantages.
Two of the advantages of vite over webpack are that it clearly distinguishes development mode from build mode, and exposes the api of the local development server for external use
Plugins can register a middleware to generate intermediate bridge code without generating files or manually filling in code each time
Another point is that vite's hmr server is in the /@vite/client
module. In development mode, vite injects <script type="module" src="/@vite/client"></script>
into index.html
Plugins can modify this code to make vite compatible with two host scenarios
Develop with plugins
Next, we use the vite-plugin-monkey plugin to develop the oil monkey script
Features offered
- Additional scaffolding to initialize various templates with one click vue/react/vanilla/svelte/preact
- Script-assisted development with support for Tampermonkey, Violentmonkey and Greasemonkey
- Package automatic injection script configuration header comments
- Automatically open script installation in default browser when first started or when script configuration comments are changed
- A friendly solution to the cdn of the @require configuration library, which greatly reduces the size of the build script
- Complete Typescript and Vite development experience, such as hot module replacement, second start
The basic configuration is as follows, please see the documentation for details https://github.com/lisonge/vite-plugin-monke
export interface MonkeyOption {
/**
* 脚本文件的入口路径
*/
entry: string;
userscript: MonkeyUserScript;
format?: Format;
server?: {
/**
* 当 第一次启动 或 脚本配置注释改变时 自动在默认浏览器打开脚本
* @default true
*/
open?: boolean;
/**
* 开发阶段的脚本名字前缀,用以在脚本安装列表里区分构建好的脚本
* @default 'dev:'
*/
prefix?: string | ((name: string) => string);
};
build?: {
/**
* 打包构建的脚本文件名字 应该以 '.user.js' 结尾
* @default (package.json.name||'monkey')+'.user.js'
*/
fileName?: string;
/**
* @example
* {
* vue:'Vue',
* // 你需要额外设置脚本配置 userscript.require = ['https://unpkg.com/vue@3.0.0/dist/vue.global.js']
* vuex:['Vuex', 'https://unpkg.com/vuex@4.0.0/dist/vuex.global.js'],
* // 插件将会自动注入 cdn 链接到 userscript.require
* vuex:['Vuex', (version)=>`https://unpkg.com/vuex@${version}/dist/vuex.global.js`],
* // 相比之前的,加了版本号,当依赖升级的时候,cdn 链接自动改变
* vuex:['Vuex', (version, name)=>`https://unpkg.com/${name}@${version}/dist/vuex.global.js`],
* // 还可以加依赖名字,不过各个依赖的 cdn basename 都不尽一致, 导致可能没什么用
* }
*
*/
externalGlobals?: Record<
string,
string | [string, string | ((version: string, name: string) => string)]
>;
/**
* 自动识别代码里用到的 浏览器插件api,然后自动配置 GM_* 或 GM.* 函数到脚本配置注释头
*
* 识别依据是判断代码文本里有没有特定的函数名字
* @default true
*/
autoGrant?: boolean;
};
}
Scaffolding initialization
vite has the official scaffolding create-vite, and there are plugins as well, and they are used in exactly the same way
pnpm create monkey
# npm create monkey
# yarn create monkey
Then you can choose from the following templates
- vue
- vue-ts
- react
- react-ts
- preact-preact
- svelte
- svelte-ts
- vanilla (native js)
- vanilla-ts (native ts)
After selecting, enter the directory to install dependencies, just like starting a normal vite project
pnpm run dev
The default browser installation script will be automatically opened. The developer only needs to click 安装
, and then open the injected webpage to see the effect
The vite.config.ts initialized in the example above is as follows
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import monkey from 'vite-plugin-monkey';
export default defineConfig({
plugins: [
vue(),
monkey({
entry: 'src/main.ts',
userscript: {
icon: 'https://vitejs.dev/logo.svg',
namespace: 'npm/vite-plugin-monkey',
match: ['https://www.google.com/'],
},
build: {
externalGlobals: {
vue: [
'Vue',
(version) =>
`https://cdn.jsdelivr.net/npm/vue@${version}/dist/vue.global.prod.js`,
],
},
},
}),
],
});
Module hot swap
An example of hot module replacement, consistent with the normal vite project development experience
Construct
The build command is consistent with the normal vite project development experience
pnpm run build
After the build is complete, a xxx.user.js will appear in the dist directory, and the file header information is as follows
// ==UserScript==
// @name vite-project
// @namespace npm/vite-plugin-monkey
// @version 0.0.0
// @icon https://vitejs.dev/logo.svg
// @match https://www.google.com/
// @require https://cdn.jsdelivr.net/npm/vue@3.2.37/dist/vue.global.prod.js
// ==/UserScript==
// use vite-plugin-monkey@1.0.0 at 2022-07-18T10:14:55.580Z
The configuration of the plugin was automatically injected into the header comments after the build
Summarize
vite provides speed and out of the box, vite-plugin-monkey is responsible for handling the relationship between oil monkey script and vite
To ensure that the development of the oil monkey script is consistent with the development of the normal vite project, welcome issues
and star
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。