0%

使用 Vite 和 React 开发 UserScript

使用 Vite 和 React 开发 UserScript

@vitejs/plugin-react@2.9.x

需要配合 index.html 使用, 在没有 index.html 的环境, 有一段 preamble code 无法注入.

配合 vite-plugin-monkey 使用时, 在 React 组件内部会报一个 @vitejs/plugin-react can't detect preamble. Something is wrong. 错误

vite 配置

新建一个 plugin, 提供一个虚拟模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import react from '@vitejs/plugin-react'
import { defineConfig, Plugin, ResolvedConfig } from 'vite'

// https://github.com/vitejs/vite/blob/v2.9.9/packages/plugin-react/src/index.ts#L324-L334
// https://github.com/vitejs/vite/blob/v2.9.9/packages/plugin-react/src/fast-refresh.ts#L29-L35
function viteReactPreamble(): Plugin {
const virtualModuleId = 'virtual:vite-react-preamble'
const resolvedVirtualModuleId = '\0' + virtualModuleId

let resolvedConfig: ResolvedConfig

return {
name: 'vite-react-preamble', // required, will show up in warnings and errors
configResolved(config) {
resolvedConfig = config
},

resolveId(id) {
if (id === virtualModuleId) {
return resolvedVirtualModuleId
}
},

load(id) {
if (id === resolvedVirtualModuleId) {
if (resolvedConfig.mode === 'development') {
const preambleCode = react.preambleCode.replace(`__BASE__`, resolvedConfig.base || '/')
return `
${preambleCode}
;console.log('[vite-react-preamble]: preamble loaded')
`
} else {
return ''
}
}
},
}
}
  • 注意需要区分 mode, 在 production build 情况下不用引入 react-refresh 代码

在 entry 引入该虚拟模块

1
2
3
// main.tsx
// 在最开始引入该虚拟模块
import 'virtual:vite-react-preamble'

即可正常使用在 UserScripts 环境下正常使用 React Fast refresh