1
+ // vite.config.js
2
+ import { defineConfig } from 'vite' ;
3
+ import path from 'path' ;
4
+ import { fileURLToPath } from 'url' ;
5
+ import fs from 'fs' ;
6
+ import archiver from 'archiver' ;
7
+ import chokidar from 'chokidar' ;
8
+ import crypto from 'crypto' ;
9
+
10
+ // 获取当前文件的目录
11
+ const __filename = fileURLToPath ( import . meta. url ) ;
12
+ const __dirname = path . dirname ( __filename ) ;
13
+
14
+ const pluginName = 'giteeai-translate' ;
15
+
16
+ function generateDevAppcast ( outputPath ) {
17
+ const fileBuffer = fs . readFileSync ( outputPath ) ;
18
+ const hashSum = crypto . createHash ( 'sha256' ) ;
19
+ hashSum . update ( fileBuffer ) ;
20
+ const sha256 = hashSum . digest ( 'hex' ) ;
21
+
22
+ // 读取 info.json 获取版本号
23
+ const infoPath = path . resolve ( __dirname , 'src' , 'info.json' ) ;
24
+ const info = JSON . parse ( fs . readFileSync ( infoPath , 'utf8' ) ) ;
25
+ const version = info . version ;
26
+
27
+ // 使用绝对路径,确保文件名正确
28
+ const relativePluginPath = path . relative ( path . resolve ( __dirname , 'dist/dev' ) , outputPath ) ;
29
+
30
+ return {
31
+ identifier : "com.gitee.ai.bob-translate" ,
32
+ versions : [
33
+ {
34
+ version : version ,
35
+ desc : "🛠️ 开发版本" ,
36
+ sha256 : sha256 ,
37
+ url : `http://localhost:5173/${ relativePluginPath } ` ,
38
+ minBobVersion : "1.8.0"
39
+ }
40
+ ]
41
+ } ;
42
+ }
43
+
44
+ function updateInfoJsonAppcast ( isDev ) {
45
+ const infoPath = path . resolve ( __dirname , 'src' , 'info.json' ) ;
46
+ const info = JSON . parse ( fs . readFileSync ( infoPath , 'utf8' ) ) ;
47
+
48
+ if ( isDev ) {
49
+ // 总是添加新的开发时间戳
50
+ const baseVersion = info . version . split ( '-dev.' ) [ 0 ] ;
51
+ info . version = `${ baseVersion } -dev.${ Date . now ( ) } ` ;
52
+ info . appcast = 'http://localhost:5173/appcast.json' ;
53
+ } else {
54
+ // 移除开发版本标记,恢复原始版本
55
+ info . version = info . version . split ( '-dev.' ) [ 0 ] ;
56
+ info . appcast = 'https://raw.githubusercontent.com/your-username/your-repo/main/appcast.json' ;
57
+ }
58
+
59
+ return info ;
60
+ }
61
+
62
+ function createBobPlugin ( isDev = false ) {
63
+ const outputDir = isDev ? 'dist/dev' : 'dist/build' ;
64
+ const outputFileName = isDev ? `${ pluginName } -dev.bobplugin` : `${ pluginName } .bobplugin` ;
65
+ const outputPath = path . resolve ( __dirname , outputDir , outputFileName ) ;
66
+
67
+ // 确保输出目录存在
68
+ fs . mkdirSync ( path . resolve ( __dirname , outputDir ) , { recursive : true } ) ;
69
+
70
+ // 创建插件归档
71
+ const archive = archiver ( 'zip' , { zlib : { level : 9 } } ) ;
72
+ const output = fs . createWriteStream ( outputPath ) ;
73
+
74
+ archive . pipe ( output ) ;
75
+
76
+ // 更新 info.json
77
+ const updatedInfo = updateInfoJsonAppcast ( isDev ) ;
78
+ const tempInfoPath = path . resolve ( __dirname , 'src' , 'info.json' ) ;
79
+
80
+ // 使用原子写入,减少文件系统事件
81
+ const tempFile = `${ tempInfoPath } .tmp` ;
82
+ fs . writeFileSync ( tempFile , JSON . stringify ( updatedInfo , null , 4 ) ) ;
83
+ fs . renameSync ( tempFile , tempInfoPath ) ;
84
+
85
+ // 添加所有 src 目录文件到归档
86
+ archive . directory ( 'src/' , false ) ;
87
+
88
+ return new Promise ( ( resolve , reject ) => {
89
+ output . on ( 'close' , ( ) => {
90
+ console . log ( `${ outputFileName } created successfully in ${ outputDir } ` ) ;
91
+
92
+ // 仅在开发模式下生成本地 appcast
93
+ if ( isDev ) {
94
+ const devAppcast = generateDevAppcast ( outputPath ) ;
95
+ const devAppcastPath = path . resolve ( __dirname , outputDir , 'appcast.json' ) ;
96
+
97
+ // 使用原子写入,减少文件系统事件
98
+ const tempAppcastFile = `${ devAppcastPath } .tmp` ;
99
+ fs . writeFileSync ( tempAppcastFile , JSON . stringify ( devAppcast , null , 4 ) ) ;
100
+ fs . renameSync ( tempAppcastFile , devAppcastPath ) ;
101
+
102
+ console . log ( `Dev appcast created at ${ devAppcastPath } ` ) ;
103
+ }
104
+
105
+ resolve ( ) ;
106
+ } ) ;
107
+
108
+ archive . on ( 'error' , ( err ) => {
109
+ reject ( err ) ;
110
+ } ) ;
111
+
112
+ archive . finalize ( ) ;
113
+ } ) ;
114
+ }
115
+
116
+ export default defineConfig ( {
117
+ root : path . resolve ( __dirname , 'dist/dev' ) ,
118
+ server : {
119
+ port : 5173 ,
120
+ open : false ,
121
+ cors : true ,
122
+ } ,
123
+ build : {
124
+ rollupOptions : {
125
+ input : {
126
+ main : path . resolve ( __dirname , 'src/main.js' )
127
+ }
128
+ }
129
+ } ,
130
+ plugins : [
131
+ {
132
+ name : 'bob-plugin-build' ,
133
+ buildStart ( ) {
134
+ // 创建生产 .bobplugin
135
+ return createBobPlugin ( false ) ;
136
+ }
137
+ }
138
+ ]
139
+ } ) ;
140
+
141
+ export function watchPlugin ( ) {
142
+ const watcher = chokidar . watch ( 'src' , {
143
+ persistent : true ,
144
+ ignoreInitial : false
145
+ } ) ;
146
+
147
+ watcher . on ( 'all' , async ( event , path ) => {
148
+ console . log ( `${ event } detected in ${ path } ` ) ;
149
+ await createBobPlugin ( true ) ;
150
+ } ) ;
151
+ }
152
+
153
+ export { createBobPlugin } ;
0 commit comments