Skip to content

Commit 9f85df0

Browse files
committed
chore: added catching error, refactor generateBundle
1 parent 5059f59 commit 9f85df0

File tree

2 files changed

+165
-155
lines changed

2 files changed

+165
-155
lines changed

src/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Grants } from './types.js'
22

3+
export const vitePluginName = 'vite-userscript-plugin'
34
export const styleTemplate = 'console.warn("__STYLE__")'
45
export const regexpScripts = new RegExp(/\.(t|j)sx?$/)
56
export const regexpStyles = new RegExp(/\.(s[ac]|c|le)ss$/)

src/index.ts

Lines changed: 164 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ import {
1616
grants,
1717
regexpScripts,
1818
regexpStyles,
19-
styleTemplate
19+
styleTemplate,
20+
vitePluginName
2021
} from './constants.js'
2122
import css from './css.js'
2223
import { defineGrants, removeDuplicates, transform } from './helpers.js'
@@ -27,181 +28,189 @@ export type { UserscriptPluginConfig }
2728
export default function UserscriptPlugin(
2829
config: UserscriptPluginConfig
2930
): PluginOption {
30-
let pluginConfig: ResolvedConfig
31-
let isBuildWatch: boolean
32-
let socketConnection: connection | null = null
33-
34-
const workdir = dirname(fileURLToPath(import.meta.url))
35-
const logger = createLogger('info', {
36-
prefix: '[vite-userscript-plugin]',
37-
allowClearScreen: true
38-
})
39-
40-
const httpServer = createServer((req, res) => {
41-
return serveHandler(req, res, {
42-
public: pluginConfig.build.outDir
31+
try {
32+
let pluginConfig: ResolvedConfig
33+
let isBuildWatch: boolean
34+
let socketConnection: connection | null = null
35+
36+
const workdir = dirname(fileURLToPath(import.meta.url))
37+
const logger = createLogger('info', {
38+
prefix: `[${vitePluginName}]`,
39+
allowClearScreen: true
4340
})
44-
})
45-
46-
const WebSocketServer = server
47-
const ws = new WebSocketServer({ httpServer })
48-
ws.on('request', (request) => {
49-
socketConnection = request.accept(null, request.origin)
50-
})
51-
52-
return {
53-
name: 'vite-userscript-plugin',
54-
apply: 'build',
55-
config() {
56-
return userConfig(config)
57-
},
58-
async configResolved(userConfig) {
59-
pluginConfig = userConfig
60-
isBuildWatch = (userConfig.build.watch ?? false) as boolean
61-
config.entry = resolve(userConfig.root, config.entry)
62-
config.header.name = sanitize(config.header.name)
63-
64-
Array.from([
65-
'match',
66-
'require',
67-
'include',
68-
'exclude',
69-
'resource',
70-
'connect'
71-
]).forEach((key) => {
72-
const value = config.header[key]
73-
config.header[key] = removeDuplicates(value)
41+
42+
const httpServer = createServer((req, res) => {
43+
return serveHandler(req, res, {
44+
public: pluginConfig.build.outDir
7445
})
46+
})
7547

76-
config.server = {
77-
port: await getPort(),
78-
open: false,
79-
...config.server
80-
}
81-
},
82-
async transform(src: string, path: string) {
83-
let code = src
48+
const WebSocketServer = server
49+
const ws = new WebSocketServer({ httpServer })
50+
ws.on('request', (request) => {
51+
socketConnection = request.accept(null, request.origin)
52+
})
8453

85-
if (regexpStyles.test(path)) {
86-
code = await css.add(src, path)
87-
}
54+
return {
55+
name: vitePluginName,
56+
apply: 'build',
57+
config() {
58+
return userConfig(config)
59+
},
60+
async configResolved(userConfig) {
61+
pluginConfig = userConfig
62+
isBuildWatch = (userConfig.build.watch ?? false) as boolean
63+
config.entry = resolve(userConfig.root, config.entry)
64+
config.header.name = sanitize(config.header.name)
65+
66+
Array.from([
67+
'match',
68+
'require',
69+
'include',
70+
'exclude',
71+
'resource',
72+
'connect'
73+
]).forEach((key) => {
74+
const value = config.header[key]
75+
config.header[key] = removeDuplicates(value)
76+
})
8877

89-
if (path.includes(config.entry)) {
90-
code = src + styleTemplate
91-
}
78+
config.server = {
79+
port: await getPort(),
80+
open: false,
81+
...config.server
82+
}
83+
},
84+
async transform(src: string, path: string) {
85+
let code = src
9286

93-
return {
94-
code,
95-
map: null
96-
}
97-
},
98-
generateBundle(_, bundle) {
99-
for (const [_, file] of Object.entries(bundle)) {
100-
const modules = Object.keys(
101-
(file as unknown as { modules: string[] }).modules
102-
)
103-
104-
const styleModules = modules.filter((module) =>
105-
regexpStyles.test(module)
106-
)
107-
108-
if (styleModules.length) {
109-
css.merge(styleModules)
87+
if (regexpStyles.test(path)) {
88+
code = await css.add(src, path)
11089
}
111-
}
112-
},
113-
async writeBundle(_, bundle) {
114-
const { open, port } = config.server!
115-
const userFilename = `${config.header.name}.user.js`
116-
const proxyFilename = `${config.header.name}.proxy.user.js`
117-
const metaFilename = `${config.header.name}.meta.js`
118-
119-
for (const [fileName] of Object.entries(bundle)) {
120-
if (regexpScripts.test(fileName)) {
121-
const rootDir = pluginConfig.root
122-
const outDir = pluginConfig.build.outDir
123-
124-
const outPath = resolve(rootDir, outDir, fileName)
125-
const userFilePath = resolve(rootDir, outDir, userFilename)
126-
const proxyFilePath = resolve(rootDir, outDir, proxyFilename)
127-
const metaFilePath = resolve(rootDir, outDir, metaFilename)
128-
const wsPath = resolve(workdir, `ws-${config.header.name}.js`)
129-
130-
try {
131-
let source = readFileSync(outPath, 'utf8')
132-
source = source.replace(styleTemplate, `${css.inject()}`)
133-
source = await transform({
134-
file: source,
135-
name: fileName,
136-
loader: 'js'
137-
})
138-
139-
config.header.grant = removeDuplicates(
140-
isBuildWatch
141-
? grants
142-
: [...defineGrants(source), ...(config.header.grant ?? [])]
143-
)
14490

145-
if (isBuildWatch) {
146-
const wsFile = readFileSync(resolve(workdir, 'ws.js'), 'utf8')
91+
if (path.includes(config.entry)) {
92+
code = src + styleTemplate
93+
}
94+
95+
return {
96+
code,
97+
map: null
98+
}
99+
},
100+
generateBundle(_, bundle) {
101+
for (const outputChunk of Object.values(bundle)) {
102+
if (outputChunk.type === 'asset') {
103+
continue
104+
}
105+
106+
// prettier-ignore
107+
const styleModules = Object
108+
.keys(outputChunk.modules)
109+
.filter((module) => regexpStyles.test(module))
147110

148-
const wsScript = await transform({
149-
file: wsFile.replace('__WS__', `ws://localhost:${port}`),
150-
name: wsPath,
111+
if (styleModules.length) {
112+
css.merge(styleModules)
113+
}
114+
}
115+
},
116+
async writeBundle(_, bundle) {
117+
const { open, port } = config.server!
118+
const userFilename = `${config.header.name}.user.js`
119+
const proxyFilename = `${config.header.name}.proxy.user.js`
120+
const metaFilename = `${config.header.name}.meta.js`
121+
122+
for (const [fileName] of Object.entries(bundle)) {
123+
if (regexpScripts.test(fileName)) {
124+
const rootDir = pluginConfig.root
125+
const outDir = pluginConfig.build.outDir
126+
127+
const outPath = resolve(rootDir, outDir, fileName)
128+
const userFilePath = resolve(rootDir, outDir, userFilename)
129+
const proxyFilePath = resolve(rootDir, outDir, proxyFilename)
130+
const metaFilePath = resolve(rootDir, outDir, metaFilename)
131+
const wsPath = resolve(workdir, `ws-${config.header.name}.js`)
132+
133+
try {
134+
let source = readFileSync(outPath, 'utf8')
135+
source = source.replace(styleTemplate, `${css.inject()}`)
136+
source = await transform({
137+
file: source,
138+
name: fileName,
151139
loader: 'js'
152140
})
153141

154-
writeFileSync(wsPath, wsScript)
155-
writeFileSync(
156-
proxyFilePath,
157-
new Banner({
158-
...config.header,
159-
require: [
160-
...config.header.require!,
161-
'file://' + wsPath,
162-
'file://' + outPath
163-
]
164-
}).generate()
142+
config.header.grant = removeDuplicates(
143+
isBuildWatch
144+
? grants
145+
: [...defineGrants(source), ...(config.header.grant ?? [])]
165146
)
166-
}
167147

168-
const banner = new Banner(config.header).generate()
169-
writeFileSync(outPath, source)
170-
writeFileSync(metaFilePath, banner)
171-
writeFileSync(userFilePath, `${banner}\n\n${source}`)
172-
} catch (err) {
173-
console.log(err)
148+
if (isBuildWatch) {
149+
const wsFile = readFileSync(resolve(workdir, 'ws.js'), 'utf8')
150+
151+
const wsScript = await transform({
152+
file: wsFile.replace('__WS__', `ws://localhost:${port}`),
153+
name: wsPath,
154+
loader: 'js'
155+
})
156+
157+
writeFileSync(wsPath, wsScript)
158+
writeFileSync(
159+
proxyFilePath,
160+
new Banner({
161+
...config.header,
162+
require: [
163+
...config.header.require!,
164+
'file://' + wsPath,
165+
'file://' + outPath
166+
]
167+
}).generate()
168+
)
169+
}
170+
171+
const banner = new Banner(config.header).generate()
172+
writeFileSync(outPath, source)
173+
writeFileSync(metaFilePath, banner)
174+
writeFileSync(userFilePath, `${banner}\n\n${source}`)
175+
} catch (err) {
176+
console.log(err)
177+
}
174178
}
175179
}
176-
}
177180

178-
if (isBuildWatch && !httpServer.listening) {
179-
const link = `http://localhost:${port}`
180-
httpServer.listen(port, () => {
181-
logger.clearScreen('info')
182-
logger.info(colors.blue(`Running at: ${colors.gray(link)}`))
183-
})
181+
if (isBuildWatch && !httpServer.listening) {
182+
const link = `http://localhost:${port}`
183+
httpServer.listen(port, () => {
184+
logger.clearScreen('info')
185+
logger.info(colors.blue(`Running at: ${colors.gray(link)}`))
186+
})
184187

185-
if (open) {
186-
await openLink(`${link}/${proxyFilename}`)
188+
if (open) {
189+
await openLink(`${link}/${proxyFilename}`)
190+
}
191+
} else if (!isBuildWatch) {
192+
httpServer.close()
193+
process.exit(0)
187194
}
188-
} else if (!isBuildWatch) {
189-
httpServer.close()
190-
process.exit(0)
191-
}
192-
},
193-
buildEnd() {
194-
if (isBuildWatch) {
195-
logger.clearScreen('info')
196-
197-
if (socketConnection) {
198-
socketConnection.sendUTF(
199-
JSON.stringify({
200-
message: 'reload'
201-
})
202-
)
195+
},
196+
buildEnd() {
197+
if (isBuildWatch) {
198+
logger.clearScreen('info')
199+
200+
if (socketConnection) {
201+
socketConnection.sendUTF(
202+
JSON.stringify({
203+
message: 'reload'
204+
})
205+
)
206+
}
203207
}
204208
}
205209
}
210+
} catch (err) {
211+
console.error(err)
212+
return {
213+
name: vitePluginName
214+
}
206215
}
207216
}

0 commit comments

Comments
 (0)