Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- 📝 Only used `@grant`s in the production build
- 📦 Built-in types for Tampermonkey, Greasemonkey and Violentmonkey
- 📄 Virtual module with script metadata
- 🧵 Support Web Workers

## Getting started

Expand Down Expand Up @@ -107,6 +108,14 @@ import './style.css'
> [!NOTE]
> Do not put userscript assets in `public/` — those URLs hit the host site and 404. Import the file so Vite inlines it.

## Web Workers

HMR serve rewrites `import Worker from './w?worker'` (and `?worker&inline`) to a data-URI module worker that imports Vite's `?worker_file`. The host page cannot load `/src/w.ts?worker_file` from localhost.

`vite build` and `server.file` keep Vite's worker emit. A plain `?worker` is a separate file the match site cannot serve — use `?worker&inline`. `?worker&url` and `?sharedworker` stay as Vite emits them.

See [examples/web-worker](./examples/web-worker).

## HTML pages

`index.html` is a normal Vite app next to the userscript. `vite` serves it at `/`. `vite build` writes it to `dist/` beside `{fileName}.user.js`.
Expand Down Expand Up @@ -184,6 +193,7 @@ In serve mode the header lists every grant. In production the plugin scans the b
| [sourcemap](./examples/sourcemap) | Inline map, HTML page, virtual module. |
| [serve-file](./examples/serve-file) | `server.file`, install `.user.js` or the proxy from the printed URLs. |
| [external-cdn](./examples/external-cdn) | `@types/jquery` only; runtime `$` from a CDN `@require`. |
| [web-worker](./examples/web-worker) | `?worker&inline`, data-URI bridge in HMR. |

## FAQ

Expand Down
12 changes: 5 additions & 7 deletions examples/basic/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"paths": {
"vite-userscript-plugin": ["../../src/index.ts"]
}
},
"include": ["src/**/*", "vite.config.ts"]
"extends": "../tsconfig.base.json",
"include": [
"src",
"vite.config.ts"
]
}
13 changes: 5 additions & 8 deletions examples/external-cdn/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"paths": {
"vite-userscript-plugin": ["../../src/index.ts"]
},
"allowSyntheticDefaultImports": true
},
"include": ["src/**/*", "vite.config.ts"]
"extends": "../tsconfig.base.json",
"include": [
"src",
"vite.config.ts"
]
}
12 changes: 5 additions & 7 deletions examples/multiple-entries/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"paths": {
"vite-userscript-plugin": ["../../src/index.ts"]
}
},
"include": ["src/**/*", "vite.config.ts"]
"extends": "../tsconfig.base.json",
"include": [
"src",
"vite.config.ts"
]
}
13 changes: 6 additions & 7 deletions examples/react/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
{
"extends": "../../tsconfig.base.json",
"extends": "../tsconfig.base.json",
"compilerOptions": {
"jsx": "react-jsx",
"paths": {
"vite-userscript-plugin": ["../../src/index.ts"]
},
"types": ["vite-userscript-plugin/types/tampermonkey"]
"jsx": "react-jsx"
},
"include": ["src/**/*", "vite.config.ts"]
"include": [
"src",
"vite.config.ts"
]
}
12 changes: 5 additions & 7 deletions examples/serve-file/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"paths": {
"vite-userscript-plugin": ["../../src/index.ts"]
}
},
"include": ["src/**/*", "vite.config.ts"]
"extends": "../tsconfig.base.json",
"include": [
"src",
"vite.config.ts"
]
}
13 changes: 5 additions & 8 deletions examples/sourcemap/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"paths": {
"vite-userscript-plugin": ["../../src/index.ts"],
"vite-userscript-plugin/virtual": ["../../virtual.d.ts"]
}
},
"include": ["src/**/*", "vite.config.ts"]
"extends": "../tsconfig.base.json",
"include": [
"src",
"vite.config.ts"
]
}
12 changes: 5 additions & 7 deletions examples/svelte/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"paths": {
"vite-userscript-plugin": ["../../src/index.ts"]
}
},
"include": ["src/**/*", "vite.config.ts"]
"extends": "../tsconfig.base.json",
"include": [
"src",
"vite.config.ts"
]
}
9 changes: 9 additions & 0 deletions examples/tsconfig.base.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"paths": {
"vite-userscript-plugin": ["../src/index.ts"],
"vite-userscript-plugin/virtual": ["../src/virtual.ts"]
}
}
}
12 changes: 5 additions & 7 deletions examples/vue/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"paths": {
"vite-userscript-plugin": ["../../src/index.ts"]
}
},
"include": ["src/**/*", "vite.config.ts"]
"extends": "../tsconfig.base.json",
"include": [
"src",
"vite.config.ts"
]
}
12 changes: 12 additions & 0 deletions examples/web-worker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Web Worker example

Vanilla userscript that reverses text in a module worker via `import Worker from './echo.ts?worker&inline'`.

HMR serve wraps `?worker` / `?worker&inline` in a data-URI so the host page can start the worker. `pnpm build` needs `&inline` — a plain `?worker` emits a separate file the match site cannot serve.

```bash
pnpm dev
pnpm build
```

Install the printed `*.dev.user.js` URL. HTTPS and `public/` notes: [FAQ](../../README.md#faq).
15 changes: 15 additions & 0 deletions examples/web-worker/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "web-worker-example",
"type": "module",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"type-check": "tsc --noEmit -p tsconfig.json"
},
"devDependencies": {
"vite": "catalog:",
"vite-userscript-plugin": "workspace:*"
}
}
10 changes: 10 additions & 0 deletions examples/web-worker/src/echo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { EchoRequest, EchoResponse } from './protocol'

addEventListener('message', (event: MessageEvent<EchoRequest>) => {
const { text } = event.data
const response: EchoResponse = {
text,
reversed: [...text].reverse().join(''),
}
postMessage(response)
})
6 changes: 6 additions & 0 deletions examples/web-worker/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { createWidget } from './widget'
import './style.css'

if (document.body) {
document.body.append(createWidget())
}
8 changes: 8 additions & 0 deletions examples/web-worker/src/protocol.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface EchoRequest {
text: string
}

export interface EchoResponse {
text: string
reversed: string
}
21 changes: 21 additions & 0 deletions examples/web-worker/src/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.web-worker-userscript {
border-top: 1px solid black;
}

.web-worker-userscript .meta {
color: #555;
}

.actions {
display: flex;
gap: 0.5rem;
}

.web-worker-userscript .log {
margin: 0.75rem 0 0;
padding-left: 1.25rem;
}

.web-worker-userscript .log li {
margin: 0.25rem 0;
}
3 changes: 3 additions & 0 deletions examples/web-worker/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/// <reference types="vite/client" />
/// <reference types="vite-userscript-plugin/virtual" />
/// <reference types="vite-userscript-plugin/types/tampermonkey" />
65 changes: 65 additions & 0 deletions examples/web-worker/src/widget.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import type { EchoRequest, EchoResponse } from './protocol'
import EchoWorker from './echo.ts?worker&inline'

function createButton(text: string, onClick: () => void) {
const button = document.createElement('button')
button.type = 'button'
button.textContent = text
button.addEventListener('click', onClick)
return button
}

export function createWidget() {
const worker = new EchoWorker({ name: 'echo' })

const root = document.createElement('div')
root.className = 'web-worker-userscript'

const title = document.createElement('h1')
title.textContent = 'Web Worker userscript'

const meta = document.createElement('p')
meta.className = 'meta'
meta.textContent = 'Reverses text in a module worker (`?worker&inline`)'

const input = document.createElement('input')
input.type = 'text'
input.value = 'userscript'
input.setAttribute('aria-label', 'Text to reverse')

const log = document.createElement('ol')
log.className = 'log'
log.setAttribute('aria-live', 'polite')

const appendLog = (text: string) => {
const item = document.createElement('li')
item.textContent = text
log.append(item)
}

const send = () => {
const text = input.value.trim()
if (!text) return

const request: EchoRequest = {
text,
}
worker.postMessage(request)
}

worker.addEventListener('message', (event: MessageEvent<EchoResponse>) => {
const { text, reversed } = event.data
appendLog(`${text} → ${reversed}`)
})

worker.addEventListener('error', () => {
appendLog('Worker failed to start')
})

const actions = document.createElement('div')
actions.className = 'actions'
actions.append(input, createButton('Reverse', send))

root.append(title, meta, actions, log)
return root
}
7 changes: 7 additions & 0 deletions examples/web-worker/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../tsconfig.base.json",
"include": [
"src",
"vite.config.ts"
]
}
16 changes: 16 additions & 0 deletions examples/web-worker/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { defineConfig } from 'vite'
import userscript from 'vite-userscript-plugin'
import pkg from './package.json' with { type: 'json' }

export default defineConfig({
plugins: [
userscript({
entry: 'src/index.ts',
header: {
name: pkg.name,
version: pkg.version,
match: 'https://example.com/',
},
}),
],
})
19 changes: 14 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading