3
头图

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

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

2022-07-17_19-15-35.gif

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

2022-07-18_18-00-12.gif

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


查看图片
359 声望7 粉丝

描述的字数超过限制