初始化
本文使用 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({
plugins: [solidPlugin(), cssInjectedByJsPlugin()],
server: {
port: 3000,
},
build: {
target: 'esnext',
rollupOptions: {
output: {
entryFileNames: `[name].js`,
chunkFileNames: `[name].js`,
assetFileNames: `[name].[ext]`,
}
}
},
});
执行 pnpm build 命令构建项目, 产出 /dist/index.js package.json
"scripts": {
"dev": "vite",
"build": "vite build",
"w": "vite build --watch",
"serve": "vite preview"
},
新建一个油猴测试脚本
倒数第二行的 @require file:// 是关键, 把编译后的 index.js 完整路径 写到这里 如下:
@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
import { render } from "solid-js/web";
import App from "./components/app";
import { Toaster } from "solid-toast";
import { HopeProvider } from "@hope-ui/solid";
let div = document.createElement("div");
div.id = "my-solid-root";
document.body.appendChild(div);
render(
() => (
<HopeProvider enableCssReset={false}>
<App />
<Toaster />
</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", "");
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 中的所有代码都粘贴到最后, 如下:
保存 !! 完结撒花.
最终效果
非常的不错嗷… 动画也非常的丝滑 ~ ~
开发体验也非常的不错, 和 Web 开发体验一样… 除了热更新, 需要 VSCode 保存, 自动编译, 浏览器按 F5 即可 相比原生油猴那个编辑框, 开发体验好了百倍
以后还想做的话, 还能加一些功能
- 用 npm api 中获取 npm 信息
- 用 google 翻译 api , 把 npm 简介翻译成 中文 …
- 把名称弄成 github 链接, 点击直接打开对应的 Github 地址
|