-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathvite.config.ts
More file actions
177 lines (169 loc) · 5.27 KB
/
vite.config.ts
File metadata and controls
177 lines (169 loc) · 5.27 KB
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import { defineConfig, type Plugin } from 'vite';
import { resolve } from 'path';
import * as fs from 'fs';
const USERSCRIPT_META = `// ==UserScript==
// @name Give Me Doc
// @name:zh-CN Give Me Doc — AI 对话导出 Word
// @namespace https://github.com/Qalxry/GiveMeDoc
// @version 1.0.0
// @description Convert AI chat to Word documents — powered by Pandoc WASM
// @description:zh-CN 将 AI 对话导出为 Word 文档 — 由 Pandoc WASM 驱动
// @author GiveMeDoc Contributors
// @homepageURL https://github.com/Qalxry/GiveMeDoc
// @supportURL https://github.com/Qalxry/GiveMeDoc/issues
// @icon https://raw.githubusercontent.com/Qalxry/GiveMeDoc/main/public/icons/logo.svg
// @match https://chat.deepseek.com/*
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @grant GM_addStyle
// @grant GM_registerMenuCommand
// @grant GM_xmlhttpRequest
// @connect pandoc.org
// @connect cdn.jsdelivr.net
// @noframes
// @run-at document-idle
// @license AGPL-3.0
// ==/UserScript==
`;
/**
* Vite plugin: inject userscript metadata block at the very top of the output.
* Using a generateBundle hook is more reliable than rollup's `banner` option
* which can be overridden by Vite's internal license annotation processing.
*/
function userscriptBannerPlugin(): Plugin {
return {
name: 'userscript-banner',
enforce: 'post',
generateBundle(_, bundle) {
for (const chunk of Object.values(bundle)) {
if (chunk.type === 'chunk' && chunk.isEntry) {
chunk.code = USERSCRIPT_META + '\n' + chunk.code;
}
}
},
};
}
export default defineConfig(({ mode }) => {
if (mode === 'userscript') {
return {
plugins: [userscriptBannerPlugin()],
build: {
target: 'ES2022',
outDir: 'dist/userscript',
lib: {
entry: resolve(__dirname, 'src/userscript.ts'),
formats: ['iife'],
name: 'GiveMeDoc',
fileName: () => 'give-me-doc.user.js',
},
rollupOptions: {
output: {
inlineDynamicImports: true,
},
},
minify: false,
cssCodeSplit: false,
},
define: {
__PLATFORM__: JSON.stringify('userscript'),
},
};
}
// mode === 'extension' (default)
function copyWasmPlugin(): Plugin {
return {
name: 'copy-pandoc-wasm',
closeBundle() {
const src = resolve(__dirname, 'bin/pandoc.wasm');
const dest = resolve(__dirname, 'dist/extension/pandoc.wasm');
if (fs.existsSync(src)) {
fs.copyFileSync(src, dest);
console.log('[copy-pandoc-wasm] bin/pandoc.wasm → dist/extension/pandoc.wasm');
} else {
console.warn('[copy-pandoc-wasm] bin/pandoc.wasm not found, skipping.');
}
},
};
}
// Extension build: content script must be self-contained (no ES imports)
// because Chrome content_scripts don't support ES modules.
// We use two sequential builds:
// 1. Content script + worker → IIFE (self-contained, no chunk splitting)
// 2. Popup + background → ESM (can use chunks, loaded as module)
//
// The `mode` value selects which sub-build to run:
// - extension-content → content.js + pandoc.worker.js (IIFE)
// - extension → popup + background (ESM)
if (mode === 'extension-content') {
// Build 1: content script (IIFE, self-contained)
return {
plugins: [copyWasmPlugin()],
build: {
target: 'ES2022',
outDir: 'dist/extension',
rollupOptions: {
input: resolve(__dirname, 'src/extension-content.ts'),
output: {
entryFileNames: 'content.js',
assetFileNames: 'assets/[name][extname]',
format: 'iife',
inlineDynamicImports: true,
},
},
minify: false,
cssCodeSplit: false,
},
define: {
__PLATFORM__: JSON.stringify('extension'),
},
};
}
if (mode === 'extension-worker') {
// Build 2: pandoc worker (IIFE, self-contained)
return {
build: {
target: 'ES2022',
outDir: 'dist/extension',
emptyOutDir: false,
rollupOptions: {
input: resolve(__dirname, 'src/core/pandoc.worker.ts'),
output: {
entryFileNames: 'pandoc.worker.js',
format: 'iife',
inlineDynamicImports: true,
},
},
minify: false,
cssCodeSplit: false,
},
define: {
__PLATFORM__: JSON.stringify('extension'),
},
};
}
// mode === 'extension' — Build 3: popup + background (ESM, can use chunks)
return {
build: {
target: 'ES2022',
outDir: 'dist/extension',
emptyOutDir: false,
rollupOptions: {
input: {
'background': resolve(__dirname, 'src/extension-background.ts'),
'popup': resolve(__dirname, 'src/extension-popup.html'),
},
output: {
entryFileNames: '[name].js',
chunkFileNames: 'chunks/[name]-[hash].js',
assetFileNames: 'assets/[name][extname]',
},
},
minify: false,
cssCodeSplit: false,
},
define: {
__PLATFORM__: JSON.stringify('extension'),
},
};
});