IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 使用 Vite + 前端框架 (SolidJsReactSvelteVue) 来开发 油猴脚本 -> 正文阅读

[JavaScript知识库]使用 Vite + 前端框架 (SolidJsReactSvelteVue) 来开发 油猴脚本

初始化

本文使用 SolidJs 举例, 你也可以使用其他的框架

Solid 拥有 React TypeScript 的开发体验, 还解决了 React 的缺点
还可以编译为 原生JS 体积非常的小, 还拥有 原生 JS 一样的性能.

创建项目

用官方模版创建一个 SolidJs 的 TypeScript 项目, 用 VSCode 打开项目

npx degit solidjs/templates/ts youhou-solid

配置 vite

  • 安装 pnpm i -D vite-plugin-css-injected-by-js 插件, 可以把 CSS 全部打包到 JS 中.
  • 设置 build.rollupOptions.output 中的 3 个 name , 改为原文件名输出 (去掉 vite 默认的 hash 后缀)
  • 配置这两项, 打包后 所有 CSS 与 JS 就会在一个 index.js 中
import { defineConfig } from 'vite';
import solidPlugin from 'vite-plugin-solid';
import cssInjectedByJsPlugin from "vite-plugin-css-injected-by-js";
export default defineConfig({

  // 使用插件 把 css 放入 js
  plugins: [solidPlugin(), cssInjectedByJsPlugin()],

  server: {
    port: 3000,
  },
  build: {
    target: 'esnext',
    
    // 关键点
    rollupOptions: {
      output: {
        entryFileNames: `[name].js`,
        chunkFileNames: `[name].js`,
        assetFileNames: `[name].[ext]`,
        // manualChunks: undefined
      }
    }
  },
});

执行 pnpm build 命令构建项目, 产出 /dist/index.js
package.json

"scripts": {
  "dev": "vite",
  "build": "vite build",
  "w": "vite build --watch",
  "serve": "vite preview"
},

新建一个油猴测试脚本

倒数第二行的 @require file:// 是关键,
把编译后的 index.js 完整路径 写到这里
如下:

// ==UserScript==
// @name         SolidJs-Test
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  测试
// @author       You
// @include      *
// @icon         https://www.google.com/s2/favicons?sz=64&domain=bing.com
// @grant        none
// @require      file://E:\Work\SolidProject\youhou-solid\dist\index.js
// ==/UserScript==

@include * 是匹配所有网站, 测试环境用,
全部编写完毕后,再新建一个正规一些的油猴脚本,

配置好后,
使用 pnpm w 来执行配置好的 vite build --watch 命令
只要保存代码,就会重新编译 , 耗时基本上都在 1 秒左右, 非常的快嗷~~
浏览器执行脚本只需要 F5 刷新页面,
最新的代码就会生效了.

配置 SolidJs

安装 UI 组件库 hope-ui
https://github.com/hope-ui/hope-ui/tree/v0.6.3
还有一个 solid-toast 也挺好用

"devDependencies": {
  "typescript": "^4.8.2",
  "vite": "^3.0.9",
  "vite-plugin-css-injected-by-js": "^2.1.0",
  "vite-plugin-solid": "^2.3.0"
},
"dependencies": {
  "@hope-ui/solid": "^0.6.7",
  "@stitches/core": "^1.2.8",
  "solid-js": "^1.5.1",
  "solid-toast": "^0.3.5",
  "solid-transition-group": "^0.0.11"
}

index.tsx

这段代码有两个关键点:

  • body 添加一个 id 为 my-solid-root 的 div
  • 配置 hope-ui 禁止规范化 CSS
    • 因为会添加全局规范化 CSS, 对整个页面有影响
    • TailWindCss 也不建议用, 因为也需要各种类名.
    • 如果想用 Tailwind 可以试一试 module.css 中 使用 @apply 写 tailwind
/* @refresh reload */
import { render } from "solid-js/web";
import App from "./components/app";
import { Toaster } from "solid-toast";
import { HopeProvider } from "@hope-ui/solid";

// 给 body 添加一个 div
let div = document.createElement("div");
div.id = "my-solid-root"; // 把 Solid 都放入这个 div 中
document.body.appendChild(div);

render(
  () => (
    // 非常重要!! : 配置 hope-ui 禁止 规范化 css
    <HopeProvider enableCssReset={false}>
      <App />
      <Toaster /> // 配置 solid-toast 
    </HopeProvider>
  ),
  document.getElementById("my-solid-root") as HTMLElement
);

app.tsx

可以用 module.css ,
可以使用组件库 , 可以自己封装子组件,
可以用任何的 Web 开发库
禁止 hope-ui 规范化 CSS 后, 也对原来页面没有任何的影响.

这里使用 "获取 github package.json 依赖" 为例

import { Component, createSignal, For, onMount, Show } from "solid-js";
import cssModule from "./app.module.css";
import {
  Button,
  Table,
  Thead,
  Tr,
  Th,
  Tbody,
  Td,
  Drawer,
  DrawerBody,
  DrawerCloseButton,
  DrawerContent,
  DrawerFooter,
  DrawerHeader,
  DrawerOverlay,
  createDisclosure,
} from "@hope-ui/solid";

interface IPackageJson {
  dependencies: { [key: string]: string };
  devDependencies: { [key: string]: string };
}
interface IPkg {
  name: string;
  version: string;
}

const App: Component = () => {
  const { isOpen, onOpen, onClose } = createDisclosure();

  const [devDepList, setDevDepList] = createSignal<IPkg[]>();
  
  const [depList, setDepList] = createSignal<IPkg[]>();

  let fetchPackageJson = async () => {
    // 获取左上角仓库链接中的项目地址
    let sel = document.querySelector<HTMLAnchorElement>(
      "#repository-container-header > div.d-flex.flex-wrap.flex-justify-end.mb-3.px-3.px-md-4.px-lg-5 > div > div > strong > a"
    );

    let name = sel?.href!;
    if (name == undefined) {
      return;
    }

    console.log(name);
    name = name.replaceAll("https://github.com", "");

    // createResource 没有 TanStack-Query 好用 (暂时只支持 React ), 还是不做 请求状态管理 了.
    // github 文件有 5 分钟的 disk cache
    let filePath = `https://raw.githubusercontent.com/${name}/main/package.json`;

    // 报错默认抛出
    let apiResult: IPackageJson = await fetch(filePath).then((r) => r.json());

    if (apiResult != undefined) {
      // 运行时依赖
      let depList = apiResult.dependencies;
      let depArr: IPkg[] = [];
      for (const key in depList) {
        if (Object.prototype.hasOwnProperty.call(depList, key)) {
          const value = depList[key];
          depArr.push({ name: key, version: value });
        }
      }
      setDepList(depArr);

      // 开发依赖
      let devDepArr: IPkg[] = [];
      let devDepList = apiResult.devDependencies;

      for (const key in devDepList) {
        if (Object.prototype.hasOwnProperty.call(devDepList, key)) {
          const value = devDepList[key];
          devDepArr.push({ name: key, version: value });
        }
      }
      setDevDepList(devDepArr);
    }
  };

  let openDrawer = () => {
    isOpen() ? onClose() : onOpen();
    fetchPackageJson();
  };

  // 组件加载完毕执行
  onMount(() => {});

  return (
    <div>
      <Button class={cssModule.myButton} css={{ position: "fixed" }} onClick={openDrawer}>
        Open
      </Button>
      <Drawer opened={isOpen()} placement="top" size="lg" onClose={onClose}>
        <DrawerOverlay />
        <DrawerContent>
          <DrawerCloseButton />
          <DrawerHeader>查看项目依赖</DrawerHeader>

          <DrawerBody>
            <div style={{ display: "flex", "justify-content": "center" }}>
              <div>
                <Show when={depList()?.length ?? 0 > 0}>
                  <h1>dependencies</h1>
                  <Table>
                    <Thead>
                      <Tr>
                        <Th>名称</Th>
                        <Th>版本</Th>
                      </Tr>
                    </Thead>
                    <Tbody>
                      <For each={depList()}>
                        {(item) => {
                          return (
                            <Tr>
                              <Td>{item.name}</Td>
                              <Td>{item.version}</Td>
                            </Tr>
                          );
                        }}
                      </For>
                    </Tbody>
                  </Table>
                </Show>
              </div>
              <div>
                <h1>devDependencies</h1>
                <Show when={devDepList()?.length ?? 0 > 0}>
                  <Table>
                    <Thead>
                      <Tr>
                        <Th>名称</Th>
                        <Th>版本</Th>
                      </Tr>
                    </Thead>
                    <Tbody>
                      <For each={devDepList()}>
                        {(item) => {
                          return (
                            <Tr>
                              <Td>{item.name}</Td>
                              <Td>{item.version}</Td>
                            </Tr>
                          );
                        }}
                      </For>
                    </Tbody>
                  </Table>
                </Show>
              </div>
            </div>
          </DrawerBody>

          <DrawerFooter>
            <Button variant="outline" mr="$3" onClick={onClose}>
              Cancel
            </Button>
            <Button>Save</Button>
          </DrawerFooter>
        </DrawerContent>
      </Drawer>
    </div>
  );
};

export default App;

app.module.css

.myButton {
  bottom: 12px;
  right: 12px;
  z-index: 10;
}

代码写完了, 执行 pnpm build
新建一个正规的油猴脚本
指定 @name@match
/dist/index.js 中的所有代码都粘贴到最后,
如下:

// ==UserScript==
// @name         github 查看 package.json 依赖
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://github.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=github.com
// @grant        none
// ==/UserScript==


// 把 index.js中的所有代码粘贴到这里

保存 !! 完结撒花.

最终效果

非常的不错嗷… 动画也非常的丝滑 ~ ~

开发体验也非常的不错,
和 Web 开发体验一样…
除了热更新,
需要 VSCode 保存, 自动编译, 浏览器按 F5 即可
相比原生油猴那个编辑框, 开发体验好了百倍

以后还想做的话, 还能加一些功能

  • 用 npm api 中获取 npm 信息
  • 用 google 翻译 api , 把 npm 简介翻译成 中文 …
  • 把名称弄成 github 链接, 点击直接打开对应的 Github 地址

在这里插入图片描述

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-24 20:47:38  更:2022-09-24 20:47:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/11 14:46:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码