electron-incremental-update 3.0.0-beta.4 → 3.0.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +580 -887
- package/dist/{zip-Dwm7s1C9.mjs → download-BGaAyi1Z.mjs} +16 -69
- package/dist/download-BYnkme_X.cjs +167 -0
- package/dist/{download-BN4uMS4_.d.mts → download-BjWmHHAu.d.cts} +1 -1
- package/dist/{download-DO7iuxEJ.d.cts → download-DVWJfV3S.d.mts} +1 -1
- package/dist/{electron-BJCk7uxG.mjs → electron-BInvFJ-W.mjs} +38 -13
- package/dist/electron-D_8AbLQ5.cjs +346 -0
- package/dist/index.cjs +64 -32
- package/dist/index.d.cts +10 -13
- package/dist/index.d.mts +10 -13
- package/dist/index.mjs +60 -29
- package/dist/local-Daf8naRn.cjs +118 -0
- package/dist/local-s1cw_vwb.mjs +105 -0
- package/dist/provider.cjs +21 -40
- package/dist/provider.d.cts +53 -9
- package/dist/provider.d.mts +53 -9
- package/dist/provider.mjs +9 -30
- package/dist/{types-BM9Jfu7q.d.cts → types-BOqQ_r5Q.d.cts} +5 -5
- package/dist/{types-DASqEPXE.d.mts → types-BOqQ_r5Q.d.mts} +5 -5
- package/dist/utils.cjs +15 -15
- package/dist/utils.d.cts +2 -2
- package/dist/utils.d.mts +2 -2
- package/dist/utils.mjs +4 -5
- package/dist/vite.d.mts +122 -167
- package/dist/vite.mjs +684 -753
- package/dist/zip-D1dbBzw4.cjs +254 -0
- package/dist/zip-DUK3opmV.mjs +159 -0
- package/package.json +30 -35
- package/dist/electron-C-qmVhAt.cjs +0 -321
- package/dist/version--eVB2A7n.mjs +0 -72
- package/dist/version-aPrLuz_-.cjs +0 -129
- package/dist/zip-BCC7FAQ_.cjs +0 -264
package/README.md
CHANGED
|
@@ -1,68 +1,108 @@
|
|
|
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
|
-
|
|
1
|
+
# Electron Incremental Update
|
|
2
|
+
|
|
3
|
+
Lightweight incremental update tools for Electron applications built with Vite. The package provides a Vite plugin, an Electron startup wrapper, update providers, bytecode protection, and utilities for common Electron app paths.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
- [Electron Incremental Update](#electron-incremental-update)
|
|
8
|
+
- [Contents](#contents)
|
|
9
|
+
- [Why](#why)
|
|
10
|
+
- [How It Works](#how-it-works)
|
|
11
|
+
- [Installation](#installation)
|
|
12
|
+
- [Quick Start](#quick-start)
|
|
13
|
+
- [Entry Process](#entry-process)
|
|
14
|
+
- [Main Process](#main-process)
|
|
15
|
+
- [Vite Configuration](#vite-configuration)
|
|
16
|
+
- [Plugin Options](#plugin-options)
|
|
17
|
+
- [Electron Builder](#electron-builder)
|
|
18
|
+
- [Runtime Usage](#runtime-usage)
|
|
19
|
+
- [Create The App](#create-the-app)
|
|
20
|
+
- [Updater API](#updater-api)
|
|
21
|
+
- [Providers](#providers)
|
|
22
|
+
- [GitHub](#github)
|
|
23
|
+
- [Default](#default)
|
|
24
|
+
- [Atom](#atom)
|
|
25
|
+
- [Api](#api)
|
|
26
|
+
- [URL Handling](#url-handling)
|
|
27
|
+
- [Local](#local)
|
|
28
|
+
- [Recommended Setup](#recommended-setup)
|
|
29
|
+
- [Custom Options](#custom-options)
|
|
30
|
+
- [Manual Provider](#manual-provider)
|
|
31
|
+
- [Testing The Local Flow](#testing-the-local-flow)
|
|
32
|
+
- [Update Artifacts](#update-artifacts)
|
|
33
|
+
- [Native Modules](#native-modules)
|
|
34
|
+
- [Result in app.asar](#result-in-appasar)
|
|
35
|
+
- [Bytecode Protection](#bytecode-protection)
|
|
36
|
+
- [Development Bundling](#development-bundling)
|
|
37
|
+
- [Utilities](#utilities)
|
|
38
|
+
- [Credits](#credits)
|
|
39
|
+
- [License](#license)
|
|
40
|
+
|
|
41
|
+
## Why
|
|
42
|
+
|
|
43
|
+
Electron applications are commonly shipped as full installers. This package keeps the installer stable and updates only the application asar file, which makes update packages smaller and keeps the runtime workflow explicit.
|
|
44
|
+
|
|
45
|
+
Key features:
|
|
46
|
+
|
|
47
|
+
- Vite plugin based on `vite-plugin-electron/multi-env`
|
|
48
|
+
- Dual asar runtime layout
|
|
49
|
+
- Signed update metadata and asar verification
|
|
50
|
+
- GitHub and local development providers
|
|
51
|
+
- Optional V8 bytecode generation
|
|
52
|
+
- Utilities for app paths, native modules, renderer loading, and Electron startup
|
|
53
|
+
|
|
54
|
+
## How It Works
|
|
55
|
+
|
|
56
|
+
The packaged app uses two asar files:
|
|
57
|
+
|
|
58
|
+
- `app.asar`: the stable entry asar generated from `entry.files`
|
|
59
|
+
- `${app.name}.asar`: the replaceable application asar generated from the Electron main, preload, and renderer build outputs
|
|
60
|
+
|
|
61
|
+
The update flow is:
|
|
62
|
+
|
|
63
|
+
1. `createElectronApp()` starts from `app.asar`.
|
|
64
|
+
2. If `${app.name}.asar.tmp` exists, it is renamed to `${app.name}.asar`.
|
|
65
|
+
3. The configured main file is loaded from `${app.name}.asar`.
|
|
66
|
+
4. Your main process calls `updater.checkForUpdates()`.
|
|
67
|
+
5. The provider downloads `version.json`.
|
|
68
|
+
6. The updater compares versions and emits `update-available` when a newer update exists.
|
|
69
|
+
7. `updater.downloadUpdate()` downloads, decompresses, verifies, and writes `${app.name}.asar.tmp`.
|
|
70
|
+
8. `updater.quitAndInstall()` restarts the app so the new asar can be installed on next launch.
|
|
71
|
+
|
|
72
|
+
## Installation
|
|
29
73
|
|
|
30
74
|
```sh
|
|
31
|
-
npm install -D electron-incremental-update
|
|
75
|
+
npm install -D electron-incremental-update @electron/asar @babel/core
|
|
32
76
|
```
|
|
33
77
|
|
|
34
78
|
```sh
|
|
35
|
-
|
|
79
|
+
pnpm add -D electron-incremental-update @electron/asar @babel/core
|
|
36
80
|
```
|
|
37
81
|
|
|
38
82
|
```sh
|
|
39
|
-
|
|
83
|
+
yarn add -D electron-incremental-update @electron/asar @babel/core
|
|
40
84
|
```
|
|
41
85
|
|
|
42
|
-
|
|
86
|
+
## Quick Start
|
|
43
87
|
|
|
44
|
-
|
|
88
|
+
Recommended project layout:
|
|
45
89
|
|
|
46
|
-
```
|
|
90
|
+
```txt
|
|
47
91
|
electron
|
|
48
|
-
├── entry.ts
|
|
92
|
+
├── entry.ts
|
|
49
93
|
├── main
|
|
50
94
|
│ └── index.ts
|
|
51
95
|
├── preload
|
|
52
96
|
│ └── index.ts
|
|
53
|
-
└── native
|
|
54
|
-
└──
|
|
97
|
+
└── native
|
|
98
|
+
└── db.ts
|
|
55
99
|
src
|
|
56
100
|
└── ...
|
|
57
101
|
```
|
|
58
102
|
|
|
59
|
-
###
|
|
60
|
-
|
|
61
|
-
The entry is used to load the application and initialize the `Updater`
|
|
103
|
+
### Entry Process
|
|
62
104
|
|
|
63
|
-
`
|
|
64
|
-
|
|
65
|
-
in `electron/entry.ts`
|
|
105
|
+
`electron/entry.ts` is the stable startup file. It creates the updater and loads the real main process from `${app.name}.asar`.
|
|
66
106
|
|
|
67
107
|
```ts
|
|
68
108
|
import { createElectronApp } from 'electron-incremental-update'
|
|
@@ -70,117 +110,193 @@ import { GitHubProvider } from 'electron-incremental-update/provider'
|
|
|
70
110
|
|
|
71
111
|
createElectronApp({
|
|
72
112
|
updater: {
|
|
73
|
-
// optinal, you can setup later
|
|
74
113
|
provider: new GitHubProvider({
|
|
75
|
-
|
|
76
|
-
repo: '
|
|
114
|
+
user: 'your-github-user',
|
|
115
|
+
repo: 'your-repo',
|
|
77
116
|
}),
|
|
78
117
|
},
|
|
79
118
|
beforeStart(mainFilePath, logger) {
|
|
80
|
-
logger?.debug(mainFilePath)
|
|
119
|
+
logger?.debug(`Starting app from ${mainFilePath}`)
|
|
81
120
|
},
|
|
82
121
|
})
|
|
83
122
|
```
|
|
84
123
|
|
|
85
|
-
|
|
124
|
+
### Main Process
|
|
125
|
+
|
|
126
|
+
The main entry must default-export one function wrapped with `startupWithUpdater()`.
|
|
86
127
|
|
|
87
|
-
|
|
128
|
+
```ts
|
|
129
|
+
import { app, BrowserWindow, dialog } from 'electron'
|
|
130
|
+
import { startupWithUpdater } from 'electron-incremental-update'
|
|
131
|
+
import { getAppVersion, getPathFromPreload, loadPage } from 'electron-incremental-update/utils'
|
|
88
132
|
|
|
89
|
-
|
|
133
|
+
export default startupWithUpdater(async (updater) => {
|
|
134
|
+
await app.whenReady()
|
|
90
135
|
|
|
91
|
-
|
|
92
|
-
|
|
136
|
+
const win = new BrowserWindow({
|
|
137
|
+
webPreferences: {
|
|
138
|
+
preload: getPathFromPreload('index.js'),
|
|
139
|
+
},
|
|
140
|
+
})
|
|
93
141
|
|
|
94
|
-
|
|
142
|
+
loadPage(win)
|
|
95
143
|
|
|
96
|
-
|
|
144
|
+
updater.on('update-available', async ({ version }) => {
|
|
145
|
+
const { response } = await dialog.showMessageBox({
|
|
146
|
+
type: 'info',
|
|
147
|
+
message: `Version ${version} is available. Current version is ${getAppVersion()}.`,
|
|
148
|
+
buttons: ['Download', 'Later'],
|
|
149
|
+
})
|
|
97
150
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
151
|
+
if (response === 0) {
|
|
152
|
+
await updater.downloadUpdate()
|
|
153
|
+
}
|
|
154
|
+
})
|
|
101
155
|
|
|
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
|
-
port: +url.port,
|
|
128
|
-
}
|
|
129
|
-
})(),
|
|
130
|
-
}
|
|
156
|
+
updater.on('download-progress', (info) => {
|
|
157
|
+
win.webContents.send('update-progress', info)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
updater.on('update-downloaded', async () => {
|
|
161
|
+
const { response } = await dialog.showMessageBox({
|
|
162
|
+
type: 'info',
|
|
163
|
+
message: 'Update downloaded.',
|
|
164
|
+
buttons: ['Restart Now', 'Later'],
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
if (response === 0) {
|
|
168
|
+
updater.quitAndInstall()
|
|
169
|
+
}
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
updater.on('update-not-available', (code, message) => {
|
|
173
|
+
console.log(`[${code}] ${message}`)
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
updater.on('error', (error) => {
|
|
177
|
+
console.error(error)
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
await updater.checkForUpdates()
|
|
131
181
|
})
|
|
132
182
|
```
|
|
133
183
|
|
|
134
|
-
|
|
184
|
+
## Vite Configuration
|
|
185
|
+
|
|
186
|
+
Use `defineElectronConfig()` when the same Vite config owns the renderer and Electron processes.
|
|
135
187
|
|
|
136
188
|
```ts
|
|
137
189
|
import { defineElectronConfig } from 'electron-incremental-update/vite'
|
|
138
190
|
|
|
139
191
|
export default defineElectronConfig({
|
|
192
|
+
entry: {
|
|
193
|
+
files: './electron/entry.ts',
|
|
194
|
+
},
|
|
140
195
|
main: {
|
|
141
|
-
files:
|
|
142
|
-
// see https://github.com/electron-vite/electron-vite-vue/blob/85ed267c4851bf59f32888d766c0071661d4b94c/vite.config.ts#L22-L28
|
|
143
|
-
onstart: debugStartup,
|
|
196
|
+
files: './electron/main/index.ts',
|
|
144
197
|
},
|
|
145
198
|
preload: {
|
|
146
199
|
files: './electron/preload/index.ts',
|
|
147
200
|
},
|
|
148
201
|
updater: {
|
|
149
|
-
|
|
202
|
+
minimumVersion: '0.0.0',
|
|
203
|
+
paths: {
|
|
204
|
+
asarOutputPath: 'release/my-app.asar',
|
|
205
|
+
gzipPath: 'release/my-app-1.0.0.asar.gz',
|
|
206
|
+
versionPath: 'release/version.json',
|
|
207
|
+
},
|
|
150
208
|
},
|
|
151
209
|
renderer: {
|
|
152
|
-
server:
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
return {
|
|
157
|
-
host: url.hostname,
|
|
158
|
-
port: +url.port,
|
|
210
|
+
server: process.env.VSCODE_DEBUG
|
|
211
|
+
? {
|
|
212
|
+
host: '127.0.0.1',
|
|
213
|
+
port: 5173,
|
|
159
214
|
}
|
|
160
|
-
|
|
215
|
+
: undefined,
|
|
161
216
|
},
|
|
162
217
|
})
|
|
163
218
|
```
|
|
164
219
|
|
|
165
|
-
|
|
220
|
+
Use `electronWithUpdater()` directly when you want to manage the renderer config yourself.
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
import { electronWithUpdater } from 'electron-incremental-update/vite'
|
|
224
|
+
import { defineConfig } from 'vite'
|
|
225
|
+
|
|
226
|
+
export default defineConfig({
|
|
227
|
+
plugins: [
|
|
228
|
+
electronWithUpdater({
|
|
229
|
+
entry: {
|
|
230
|
+
files: './electron/entry.ts',
|
|
231
|
+
},
|
|
232
|
+
main: {
|
|
233
|
+
files: './electron/main/index.ts',
|
|
234
|
+
},
|
|
235
|
+
preload: {
|
|
236
|
+
files: './electron/preload/index.ts',
|
|
237
|
+
},
|
|
238
|
+
}),
|
|
239
|
+
],
|
|
240
|
+
})
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Plugin Options
|
|
244
|
+
|
|
245
|
+
Common options:
|
|
246
|
+
|
|
247
|
+
- `entry.files`: entry process input. Required.
|
|
248
|
+
- `main.files`: main process input. Required.
|
|
249
|
+
- `preload.files`: preload process input. Optional.
|
|
250
|
+
- `sourcemap`: defaults to development or `VSCODE_DEBUG`.
|
|
251
|
+
- `minify`: defaults to production builds.
|
|
252
|
+
- `bytecode`: `true` or bytecode options.
|
|
253
|
+
- `notBundle`: externalizes Node modules in development. Defaults to `true`.
|
|
254
|
+
- `external`: additional Vite/Rolldown externals. Use `true` to externalize `dependencies`.
|
|
255
|
+
- `buildVersionJson`: generates update JSON. Defaults to CI only.
|
|
256
|
+
- `localDevUpdate`: generates and serves a local update package during dev startup. Use `true`
|
|
257
|
+
for defaults, or pass `{ baseDir, packageJsonPath, chunkSize, chunkDelay }`. See [Local Development](#local-development) for details.
|
|
258
|
+
- `updater.minimumVersion`: minimum supported entry asar version. Defaults to `0.0.0`.
|
|
259
|
+
|
|
260
|
+
Default output paths:
|
|
261
|
+
|
|
262
|
+
- `updater.paths.asarOutputPath`: `release/${app.name}.asar`
|
|
263
|
+
- `updater.paths.gzipPath`: `release/${app.name}-${version}.asar.gz`
|
|
264
|
+
- `updater.paths.versionPath`: `release/version.json`
|
|
265
|
+
- `updater.paths.entryOutDir`: `dist-entry`
|
|
266
|
+
- `updater.paths.electronDistPath`: `dist-electron`
|
|
267
|
+
- `updater.paths.rendererDistPath`: `dist`
|
|
268
|
+
|
|
269
|
+
Signing keys:
|
|
270
|
+
|
|
271
|
+
- `updater.keys.privateKeyPath`: defaults to `keys/private.pem`
|
|
272
|
+
- `updater.keys.certPath`: defaults to `keys/cert.pem`
|
|
273
|
+
- `UPDATER_PK`: overrides `privateKeyPath`
|
|
274
|
+
- `UPDATER_CERT`: overrides `certPath`
|
|
275
|
+
|
|
276
|
+
The plugin creates a simple self-signed certificate when the key files are missing.
|
|
277
|
+
|
|
278
|
+
## Electron Builder
|
|
279
|
+
|
|
280
|
+
Set `package.json#main` to the entry output file:
|
|
166
281
|
|
|
167
282
|
```json
|
|
168
283
|
{
|
|
169
|
-
"main": "dist-entry/entry.js"
|
|
284
|
+
"main": "dist-entry/entry.js"
|
|
170
285
|
}
|
|
171
286
|
```
|
|
172
287
|
|
|
173
|
-
|
|
288
|
+
Minimal `electron-builder.config.cjs`:
|
|
174
289
|
|
|
175
290
|
```js
|
|
176
291
|
const { name } = require('./package.json')
|
|
177
292
|
|
|
178
293
|
const targetFile = `${name}.asar`
|
|
294
|
+
|
|
179
295
|
/**
|
|
180
296
|
* @type {import('electron-builder').Configuration}
|
|
181
297
|
*/
|
|
182
298
|
module.exports = {
|
|
183
|
-
appId:
|
|
299
|
+
appId: `org.${name}`,
|
|
184
300
|
productName: name,
|
|
185
301
|
files: [
|
|
186
302
|
// entry files
|
|
@@ -194,144 +310,331 @@ module.exports = {
|
|
|
194
310
|
extraResources: [
|
|
195
311
|
{ from: `release/${targetFile}`, to: targetFile }, // <- asar file
|
|
196
312
|
],
|
|
197
|
-
// disable publish
|
|
198
|
-
publish: null,
|
|
313
|
+
publish: null, // <- disable publish
|
|
199
314
|
}
|
|
200
315
|
```
|
|
201
316
|
|
|
202
|
-
## Usage
|
|
317
|
+
## Runtime Usage
|
|
203
318
|
|
|
204
|
-
###
|
|
319
|
+
### Create The App
|
|
205
320
|
|
|
206
|
-
|
|
321
|
+
```ts
|
|
322
|
+
import { createElectronApp } from 'electron-incremental-update'
|
|
207
323
|
|
|
208
|
-
|
|
324
|
+
createElectronApp({
|
|
325
|
+
updater: {
|
|
326
|
+
provider,
|
|
327
|
+
receiveBeta: false,
|
|
328
|
+
logger: console,
|
|
329
|
+
},
|
|
330
|
+
onInstall(install, tempAsarPath, appNameAsarPath, logger) {
|
|
331
|
+
logger?.info(`Installing ${tempAsarPath} to ${appNameAsarPath}`)
|
|
332
|
+
install()
|
|
333
|
+
},
|
|
334
|
+
onStartError(error, logger) {
|
|
335
|
+
logger?.error('Failed to start app', error)
|
|
336
|
+
},
|
|
337
|
+
})
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
`updater` can also be an async factory:
|
|
209
341
|
|
|
210
|
-
|
|
342
|
+
```ts
|
|
343
|
+
createElectronApp({
|
|
344
|
+
updater: async () => {
|
|
345
|
+
const { Updater } = await import('electron-incremental-update')
|
|
346
|
+
return new Updater({ provider })
|
|
347
|
+
},
|
|
348
|
+
})
|
|
349
|
+
```
|
|
211
350
|
|
|
212
|
-
|
|
351
|
+
### Updater API
|
|
213
352
|
|
|
214
353
|
```ts
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
354
|
+
updater.provider = provider
|
|
355
|
+
updater.receiveBeta = true
|
|
356
|
+
updater.logger = console
|
|
218
357
|
|
|
219
|
-
|
|
220
|
-
|
|
358
|
+
await updater.checkForUpdates()
|
|
359
|
+
await updater.downloadUpdate()
|
|
360
|
+
updater.cancel()
|
|
361
|
+
updater.quitAndInstall()
|
|
362
|
+
```
|
|
221
363
|
|
|
222
|
-
|
|
223
|
-
[`${app.name}.asar path:`]: getPathFromAppNameAsar(),
|
|
224
|
-
'app version:': getAppVersion(),
|
|
225
|
-
'entry (installer) version:': getEntryVersion(),
|
|
226
|
-
'electron version:': process.versions.electron,
|
|
227
|
-
})
|
|
364
|
+
Events:
|
|
228
365
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
366
|
+
- `update-available`: emitted with update info and current app/entry versions.
|
|
367
|
+
- `update-not-available`: emitted with a code, message, and optional update info.
|
|
368
|
+
- `download-progress`: emitted while downloading.
|
|
369
|
+
- `update-downloaded`: emitted after the temporary asar is ready.
|
|
370
|
+
- `update-cancelled`: emitted after cancellation.
|
|
371
|
+
- `error`: emitted with `UpdaterError`.
|
|
232
372
|
|
|
233
|
-
|
|
234
|
-
const { response } = await dialog.showMessageBox({
|
|
235
|
-
type: 'info',
|
|
236
|
-
buttons: ['Download', 'Later'],
|
|
237
|
-
message: `v${version} update available!`,
|
|
238
|
-
})
|
|
239
|
-
if (response !== 0) {
|
|
240
|
-
return
|
|
241
|
-
}
|
|
242
|
-
await updater.downloadUpdate()
|
|
243
|
-
})
|
|
373
|
+
## Providers
|
|
244
374
|
|
|
245
|
-
|
|
375
|
+
### GitHub
|
|
246
376
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
main.send(BrowserWindow.getAllWindows()[0], 'msg', data)
|
|
250
|
-
})
|
|
377
|
+
GitHub providers read update metadata from a repository or release and download the generated
|
|
378
|
+
`{name}-{version}.asar.gz` artifact from GitHub Releases.
|
|
251
379
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
380
|
+
#### Default
|
|
381
|
+
|
|
382
|
+
Reads `version.json` from the repository branch and downloads the asar from GitHub Releases.
|
|
255
383
|
|
|
256
|
-
|
|
384
|
+
```ts
|
|
385
|
+
import { GitHubProvider } from 'electron-incremental-update/provider'
|
|
386
|
+
|
|
387
|
+
const provider = new GitHubProvider({
|
|
388
|
+
user: 'your-github-user',
|
|
389
|
+
repo: 'your-repo',
|
|
390
|
+
branch: 'HEAD',
|
|
257
391
|
})
|
|
258
392
|
```
|
|
259
393
|
|
|
260
|
-
|
|
394
|
+
Default URLs:
|
|
395
|
+
|
|
396
|
+
- update JSON: `https://github.com/{user}/{repo}/raw/{branch}/{versionPath}`
|
|
397
|
+
- asar: `https://github.com/{user}/{repo}/releases/download/v{version}/{name}-{version}.asar.gz`
|
|
398
|
+
|
|
399
|
+
#### Atom
|
|
400
|
+
|
|
401
|
+
Reads the latest release tag from `releases.atom`, then downloads the update JSON and asar from that release.
|
|
261
402
|
|
|
262
403
|
```ts
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
404
|
+
import { GitHubAtomProvider } from 'electron-incremental-update/provider'
|
|
405
|
+
|
|
406
|
+
const provider = new GitHubAtomProvider({
|
|
407
|
+
user: 'your-github-user',
|
|
408
|
+
repo: 'your-repo',
|
|
409
|
+
})
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
#### Api
|
|
413
|
+
|
|
414
|
+
Uses the GitHub Releases API and can use a token for private repositories or higher rate limits.
|
|
415
|
+
|
|
416
|
+
```ts
|
|
417
|
+
import { GitHubApiProvider } from 'electron-incremental-update/provider'
|
|
418
|
+
|
|
419
|
+
const provider = new GitHubApiProvider({
|
|
420
|
+
user: 'your-github-user',
|
|
421
|
+
repo: 'your-repo',
|
|
422
|
+
token: process.env.GITHUB_TOKEN,
|
|
423
|
+
})
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
#### URL Handling
|
|
427
|
+
|
|
428
|
+
GitHub providers support `urlHandler` for mirrors, custom gateways, or request rewriting.
|
|
429
|
+
|
|
430
|
+
```ts
|
|
431
|
+
const provider = new GitHubProvider({
|
|
432
|
+
user: 'your-github-user',
|
|
433
|
+
repo: 'your-repo',
|
|
434
|
+
urlHandler(url) {
|
|
435
|
+
url.hostname = 'mirror.example.com'
|
|
269
436
|
url.pathname = `https://github.com${url.pathname}`
|
|
270
437
|
return url
|
|
271
438
|
},
|
|
272
439
|
})
|
|
273
440
|
```
|
|
274
441
|
|
|
275
|
-
|
|
442
|
+
### Local
|
|
443
|
+
|
|
444
|
+
Local updates are for development and manual update-flow testing. They let you test
|
|
445
|
+
`checkForUpdates()`, download progress, `update-downloaded`, and restart/install behavior without
|
|
446
|
+
publishing a GitHub release.
|
|
447
|
+
|
|
448
|
+
Most projects should use the Vite `localDevUpdate` option instead of manually creating a
|
|
449
|
+
`LocalDevProvider`.
|
|
450
|
+
|
|
451
|
+
#### Recommended Setup
|
|
452
|
+
|
|
453
|
+
Enable local update generation in `vite.config.ts`:
|
|
276
454
|
|
|
277
455
|
```ts
|
|
278
|
-
|
|
456
|
+
import { electronWithUpdater } from 'electron-incremental-update/vite'
|
|
457
|
+
import { defineConfig } from 'vite'
|
|
458
|
+
|
|
459
|
+
export default defineConfig({
|
|
460
|
+
plugins: [
|
|
461
|
+
electronWithUpdater({
|
|
462
|
+
entry: {
|
|
463
|
+
files: './electron/entry.ts',
|
|
464
|
+
},
|
|
465
|
+
main: {
|
|
466
|
+
files: './electron/main/index.ts',
|
|
467
|
+
},
|
|
468
|
+
preload: {
|
|
469
|
+
files: './electron/preload/index.ts',
|
|
470
|
+
},
|
|
471
|
+
localDevUpdate: true,
|
|
472
|
+
}),
|
|
473
|
+
],
|
|
474
|
+
})
|
|
279
475
|
```
|
|
280
476
|
|
|
281
|
-
|
|
477
|
+
When `localDevUpdate` is enabled in development:
|
|
478
|
+
|
|
479
|
+
- the Vite plugin creates a local update package before Electron starts
|
|
480
|
+
- `createElectronApp()` auto-configures `LocalDevProvider` when no explicit `updater.provider` is set
|
|
481
|
+
- dev-only `forceUpdate` is enabled so update checks are not skipped in development
|
|
482
|
+
- production builds keep the normal provider and signature behavior
|
|
483
|
+
|
|
484
|
+
The default generated files are:
|
|
485
|
+
|
|
486
|
+
- `release/local-update/release/version.json`
|
|
487
|
+
- `release/local-update/{name}-{version}.asar.gz`
|
|
488
|
+
- `DEV.asar`
|
|
489
|
+
- `DEV.asar.tmp` after `downloadUpdate()`
|
|
490
|
+
|
|
491
|
+
The generated update version is the next patch version from the installed local dev asar. For
|
|
492
|
+
example, if `DEV.asar` contains version `1.2.3`, the generated update is `1.2.4`.
|
|
493
|
+
|
|
494
|
+
#### Custom Options
|
|
282
495
|
|
|
283
496
|
```ts
|
|
284
|
-
|
|
497
|
+
export default defineConfig({
|
|
498
|
+
plugins: [
|
|
499
|
+
electronWithUpdater({
|
|
500
|
+
// ...
|
|
501
|
+
localDevUpdate: {
|
|
502
|
+
baseDir: 'release/local-update',
|
|
503
|
+
packageJsonPath: 'playground/package.json',
|
|
504
|
+
chunkSize: 32 * 1024,
|
|
505
|
+
chunkDelay: 50,
|
|
506
|
+
},
|
|
507
|
+
}),
|
|
508
|
+
],
|
|
509
|
+
})
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
Options:
|
|
513
|
+
|
|
514
|
+
- `baseDir`: directory for generated local update resources. Defaults to `release/local-update`.
|
|
515
|
+
- `packageJsonPath`: package metadata used for update name/version. Defaults to the project
|
|
516
|
+
`package.json`.
|
|
517
|
+
- `chunkSize`: bytes per simulated download progress chunk. Defaults to `64 * 1024`.
|
|
518
|
+
- `chunkDelay`: delay between progress chunks in milliseconds. Defaults to `30`.
|
|
519
|
+
|
|
520
|
+
`chunkSize` must be greater than `0`, and `chunkDelay` must be greater than or equal to `0`.
|
|
521
|
+
|
|
522
|
+
#### Manual Provider
|
|
523
|
+
|
|
524
|
+
Use `LocalDevProvider` directly only when you need to wire local artifacts yourself.
|
|
525
|
+
|
|
526
|
+
```ts
|
|
527
|
+
import { LocalDevProvider } from 'electron-incremental-update/provider'
|
|
528
|
+
|
|
529
|
+
const provider = new LocalDevProvider({
|
|
530
|
+
baseDir: 'release/local-update',
|
|
531
|
+
chunkSize: 32 * 1024,
|
|
532
|
+
chunkDelay: 50,
|
|
533
|
+
})
|
|
285
534
|
```
|
|
286
535
|
|
|
287
|
-
|
|
536
|
+
It reads:
|
|
537
|
+
|
|
538
|
+
- `{baseDir}/{versionPath}`
|
|
539
|
+
- `{baseDir}/{name}-{version}.asar.gz`
|
|
540
|
+
|
|
541
|
+
#### Testing The Local Flow
|
|
542
|
+
|
|
543
|
+
Use the [playground](./playground) as a complete local update test:
|
|
544
|
+
|
|
545
|
+
```sh
|
|
546
|
+
bun run play
|
|
547
|
+
```
|
|
288
548
|
|
|
289
|
-
|
|
549
|
+
`bun run play` builds the package first, then starts the Vite dev server and Electron playground.
|
|
290
550
|
|
|
291
|
-
|
|
551
|
+
Expected flow:
|
|
552
|
+
|
|
553
|
+
1. The plugin builds the Electron main, preload, and entry outputs.
|
|
554
|
+
2. The plugin creates `DEV.asar` and a local update archive.
|
|
555
|
+
3. `createElectronApp()` installs any existing `DEV.asar.tmp`.
|
|
556
|
+
4. The app starts from `DEV.asar`.
|
|
557
|
+
5. The updater checks the generated `version.json`.
|
|
558
|
+
6. The playground shows an available local update.
|
|
559
|
+
7. Clicking download emits simulated progress events.
|
|
560
|
+
8. Clicking restart installs `DEV.asar.tmp` and restarts Electron.
|
|
561
|
+
|
|
562
|
+
Explicit `updater.provider` values still take priority. If you set a provider manually, automatic
|
|
563
|
+
local provider setup is skipped.
|
|
564
|
+
|
|
565
|
+
## Update Artifacts
|
|
566
|
+
|
|
567
|
+
The Vite plugin can generate:
|
|
568
|
+
|
|
569
|
+
- `${app.name}.asar`
|
|
570
|
+
- `${app.name}-${version}.asar.gz`
|
|
571
|
+
- `version.json`
|
|
572
|
+
|
|
573
|
+
Default `version.json` shape:
|
|
574
|
+
|
|
575
|
+
```json
|
|
576
|
+
{
|
|
577
|
+
"version": "1.0.0",
|
|
578
|
+
"minimumVersion": "0.0.0",
|
|
579
|
+
"signature": "...",
|
|
580
|
+
"beta": {
|
|
581
|
+
"version": "1.0.1-beta.1",
|
|
582
|
+
"minimumVersion": "0.0.0",
|
|
583
|
+
"signature": "..."
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
```
|
|
292
587
|
|
|
293
|
-
|
|
588
|
+
Stable releases update both the top-level fields and `beta`. Prerelease versions update only `beta`.
|
|
294
589
|
|
|
295
|
-
|
|
296
|
-
2. Manually copy the native binaries in `postBuild` callback
|
|
297
|
-
3. Exclude all the dependencies in `electron-builder`'s config
|
|
298
|
-
4. call the native functions with `requireNative` / `importNative` in your code
|
|
590
|
+
Set `buildVersionJson: true` if you need metadata during non-CI builds.
|
|
299
591
|
|
|
300
|
-
|
|
592
|
+
## Native Modules
|
|
301
593
|
|
|
302
|
-
in `
|
|
594
|
+
To keep update packages small, put native modules and their native binaries in `app.asar`, then load them from the main process with `requireNative()` or `importNative()`.
|
|
303
595
|
|
|
304
596
|
```ts
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
597
|
+
import { readdirSync } from 'node:fs'
|
|
598
|
+
|
|
599
|
+
import { electronWithUpdater } from 'electron-incremental-update/vite'
|
|
600
|
+
|
|
601
|
+
export default {
|
|
602
|
+
plugins: [
|
|
603
|
+
electronWithUpdater({
|
|
604
|
+
external: false,
|
|
605
|
+
entry: {
|
|
606
|
+
files: ['./electron/entry.ts', './electron/native/db.ts'],
|
|
607
|
+
postBuild({ isBuild, copyToEntryOutputDir }) {
|
|
608
|
+
if (!isBuild) {
|
|
609
|
+
return
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
copyToEntryOutputDir({
|
|
613
|
+
from: './node_modules/better-sqlite3/build/Release/better_sqlite3.node',
|
|
614
|
+
skipIfExist: false,
|
|
615
|
+
})
|
|
616
|
+
|
|
617
|
+
const packageName = readdirSync('./node_modules/.pnpm').find((name) =>
|
|
618
|
+
name.startsWith('@napi-rs+image-'),
|
|
619
|
+
)
|
|
620
|
+
|
|
621
|
+
if (packageName) {
|
|
622
|
+
const archName = packageName.substring('@napi-rs+image-'.length).split('@')[0]
|
|
623
|
+
copyToEntryOutputDir({
|
|
624
|
+
from: `./node_modules/.pnpm/${packageName}/node_modules/@napi-rs/image-${archName}/image.${archName}.node`,
|
|
625
|
+
})
|
|
626
|
+
}
|
|
627
|
+
},
|
|
312
628
|
},
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
copyToEntryOutputDir({
|
|
316
|
-
from: './node_modules/better-sqlite3/build/Release/better_sqlite3.node',
|
|
317
|
-
skipIfExist: false,
|
|
318
|
-
})
|
|
319
|
-
// for @napi-rs/image
|
|
320
|
-
const startStr = '@napi-rs+image-'
|
|
321
|
-
const fileName = readdirSync('./node_modules/.pnpm').find((p) => p.startsWith(startStr))!
|
|
322
|
-
const archName = fileName.substring(startStr.length).split('@')[0]
|
|
323
|
-
copyToEntryOutputDir({
|
|
324
|
-
from: `./node_modules/.pnpm/${fileName}/node_modules/@napi-rs/image-${archName}/image.${archName}.node`,
|
|
325
|
-
})
|
|
326
|
-
// or just copy specific dependency
|
|
327
|
-
copyModules({ modules: ['better-sqlite3'] })
|
|
629
|
+
main: {
|
|
630
|
+
files: './electron/main/index.ts',
|
|
328
631
|
},
|
|
329
|
-
},
|
|
330
|
-
|
|
331
|
-
}
|
|
632
|
+
}),
|
|
633
|
+
],
|
|
634
|
+
}
|
|
332
635
|
```
|
|
333
636
|
|
|
334
|
-
|
|
637
|
+
Use the copied native binding from entry asar:
|
|
335
638
|
|
|
336
639
|
```ts
|
|
337
640
|
import Database from 'better-sqlite3'
|
|
@@ -341,38 +644,27 @@ const db = new Database(':memory:', {
|
|
|
341
644
|
nativeBinding: getPathFromEntryAsar('./better_sqlite3.node'),
|
|
342
645
|
})
|
|
343
646
|
|
|
344
|
-
export function
|
|
345
|
-
db.exec(
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
db.prepare('INSERT INTO employees VALUES (:n, :s)').run({
|
|
351
|
-
n: 'James',
|
|
352
|
-
s: 5000,
|
|
647
|
+
export function testDatabase(): void {
|
|
648
|
+
db.exec('CREATE TABLE IF NOT EXISTS employees (name TEXT, salary INTEGER)')
|
|
649
|
+
db.prepare('INSERT INTO employees VALUES (:name, :salary)').run({
|
|
650
|
+
name: 'James',
|
|
651
|
+
salary: 5000,
|
|
353
652
|
})
|
|
354
|
-
|
|
355
|
-
const r = db.prepare('SELECT * from employees').all()
|
|
356
|
-
console.log(r)
|
|
357
|
-
// [ { name: 'James', salary: 50000 } ]
|
|
358
|
-
|
|
359
|
-
db.close()
|
|
360
653
|
}
|
|
361
654
|
```
|
|
362
655
|
|
|
363
|
-
|
|
656
|
+
Load native helper modules from main:
|
|
364
657
|
|
|
365
658
|
```ts
|
|
366
659
|
import { importNative, requireNative } from 'electron-incremental-update/utils'
|
|
367
660
|
|
|
368
|
-
|
|
369
|
-
requireNative<typeof import('../native/db')>('db').test()
|
|
661
|
+
requireNative<typeof import('../native/db')>('db').testDatabase()
|
|
370
662
|
|
|
371
|
-
|
|
372
|
-
|
|
663
|
+
const nativeDb = await importNative<typeof import('../native/db')>('db')
|
|
664
|
+
nativeDb.testDatabase()
|
|
373
665
|
```
|
|
374
666
|
|
|
375
|
-
|
|
667
|
+
For `electron-builder`, exclude `node_modules` when you have bundled dependencies manually:
|
|
376
668
|
|
|
377
669
|
```js
|
|
378
670
|
module.exports = {
|
|
@@ -452,702 +744,103 @@ After: Clean 😍
|
|
|
452
744
|
└── package.json
|
|
453
745
|
```
|
|
454
746
|
|
|
455
|
-
|
|
747
|
+
## Bytecode Protection
|
|
456
748
|
|
|
457
|
-
|
|
749
|
+
Bytecode protection compiles JavaScript into V8 bytecode.
|
|
458
750
|
|
|
459
751
|
```ts
|
|
460
752
|
electronWithUpdater({
|
|
461
|
-
|
|
462
|
-
|
|
753
|
+
bytecode: true,
|
|
754
|
+
entry: {
|
|
755
|
+
files: './electron/entry.ts',
|
|
756
|
+
},
|
|
757
|
+
main: {
|
|
758
|
+
files: './electron/main/index.ts',
|
|
759
|
+
},
|
|
463
760
|
})
|
|
464
761
|
```
|
|
465
762
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
https://electron-vite.org/guide/source-code-protection
|
|
469
|
-
|
|
470
|
-
- Improve the string protection (see [original issue](https://github.com/alex8088/electron-vite/issues/552))
|
|
471
|
-
- Protect all strings by default
|
|
472
|
-
- Minification is allowed
|
|
763
|
+
Notes:
|
|
473
764
|
|
|
474
|
-
|
|
765
|
+
- CommonJS only. Remove `"type": "module"` from `package.json` when enabling bytecode.
|
|
766
|
+
- Main process bytecode is enabled by default.
|
|
767
|
+
- To include preload scripts, use `bytecode: { enablePreload: true }`.
|
|
768
|
+
- If preload bytecode is enabled, create the `BrowserWindow` with `sandbox: false`.
|
|
475
769
|
|
|
476
|
-
|
|
477
|
-
- Only for main process by default, if you want to use in preload script, please use `electronWithUpdater({ bytecode: { enablePreload: true } })` and set `sandbox: false` when creating window
|
|
770
|
+
## Development Bundling
|
|
478
771
|
|
|
479
|
-
|
|
772
|
+
`notBundle` is enabled by default in development. It externalizes Node modules in entry and main builds to improve startup speed.
|
|
480
773
|
|
|
481
774
|
```ts
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
*
|
|
492
|
-
* If is in dev, **always** return `'DEV.asar'`
|
|
493
|
-
*/
|
|
494
|
-
function getPathFromAppNameAsar(...paths: string[]): string
|
|
495
|
-
/**
|
|
496
|
-
* Get app version, if is in dev, return `getEntryVersion()`
|
|
497
|
-
*/
|
|
498
|
-
function getAppVersion(): string
|
|
499
|
-
/**
|
|
500
|
-
* Get entry version
|
|
501
|
-
*/
|
|
502
|
-
function getEntryVersion(): string
|
|
503
|
-
/**
|
|
504
|
-
* Use `require` to load native module from entry asar
|
|
505
|
-
* @param moduleName file name in entry
|
|
506
|
-
* @example
|
|
507
|
-
* requireNative<typeof import('../native/db')>('db')
|
|
508
|
-
*/
|
|
509
|
-
function requireNative<T = any>(moduleName: string): T
|
|
510
|
-
/**
|
|
511
|
-
* Use `import` to load native module from entry asar
|
|
512
|
-
* @param moduleName file name in entry
|
|
513
|
-
* @example
|
|
514
|
-
* await importNative<typeof import('../native/db')>('db')
|
|
515
|
-
*/
|
|
516
|
-
function importNative<T = any>(moduleName: string): Promise<T>
|
|
517
|
-
/**
|
|
518
|
-
* Restarts the Electron app.
|
|
519
|
-
*/
|
|
520
|
-
function restartApp(): void
|
|
521
|
-
/**
|
|
522
|
-
* Fix app use model id, only for Windows
|
|
523
|
-
* @param id app id, default is `org.${electron.app.name}`
|
|
524
|
-
*/
|
|
525
|
-
function setAppUserModelId(id?: string): void
|
|
526
|
-
/**
|
|
527
|
-
* Disable hardware acceleration for Windows 7
|
|
528
|
-
*
|
|
529
|
-
* Only support CommonJS
|
|
530
|
-
*/
|
|
531
|
-
function disableHWAccForWin7(): void
|
|
532
|
-
/**
|
|
533
|
-
* Keep single electron instance and auto restore window on `second-instance` event
|
|
534
|
-
* @param window brwoser window to show
|
|
535
|
-
*/
|
|
536
|
-
function singleInstance(window?: BrowserWindow): void
|
|
537
|
-
/**
|
|
538
|
-
* Set `userData` dir to the dir of .exe file
|
|
539
|
-
*
|
|
540
|
-
* Useful for portable Windows app
|
|
541
|
-
* @param dirName dir name, default to `data`
|
|
542
|
-
* @param create whether to create dir, default to `true`
|
|
543
|
-
*/
|
|
544
|
-
function setPortableDataPath(dirName?: string, create?: boolean): void
|
|
545
|
-
/**
|
|
546
|
-
* Load `process.env.VITE_DEV_SERVER_URL` when dev, else load html file
|
|
547
|
-
* @param win window
|
|
548
|
-
* @param htmlFilePath html file path, default is `index.html`
|
|
549
|
-
*/
|
|
550
|
-
function loadPage(win: BrowserWindow, htmlFilePath?: string): void
|
|
551
|
-
interface BeautifyDevToolsOptions {
|
|
552
|
-
/**
|
|
553
|
-
* Sans-serif font family
|
|
554
|
-
*/
|
|
555
|
-
sans: string
|
|
556
|
-
/**
|
|
557
|
-
* Monospace font family
|
|
558
|
-
*/
|
|
559
|
-
mono: string
|
|
560
|
-
/**
|
|
561
|
-
* Whether to round scrollbar
|
|
562
|
-
*/
|
|
563
|
-
scrollbar?: boolean
|
|
564
|
-
}
|
|
565
|
-
/**
|
|
566
|
-
* Beautify devtools' font and scrollbar
|
|
567
|
-
* @param win target window
|
|
568
|
-
* @param options sans font family, mono font family and scrollbar
|
|
569
|
-
*/
|
|
570
|
-
function beautifyDevTools(win: BrowserWindow, options: BeautifyDevToolsOptions): void
|
|
571
|
-
/**
|
|
572
|
-
* Get joined path from main dir
|
|
573
|
-
* @param paths rest paths
|
|
574
|
-
*/
|
|
575
|
-
function getPathFromMain(...paths: string[]): string
|
|
576
|
-
/**
|
|
577
|
-
* Get joined path from preload dir
|
|
578
|
-
* @param paths rest paths
|
|
579
|
-
*/
|
|
580
|
-
function getPathFromPreload(...paths: string[]): string
|
|
581
|
-
/**
|
|
582
|
-
* Get joined path from publich dir
|
|
583
|
-
* @param paths rest paths
|
|
584
|
-
*/
|
|
585
|
-
function getPathFromPublic(...paths: string[]): string
|
|
586
|
-
/**
|
|
587
|
-
* Get joined path from entry asar
|
|
588
|
-
* @param paths rest paths
|
|
589
|
-
*/
|
|
590
|
-
function getPathFromEntryAsar(...paths: string[]): string
|
|
591
|
-
/**
|
|
592
|
-
* Handle all unhandled error
|
|
593
|
-
* @param callback callback function
|
|
594
|
-
*/
|
|
595
|
-
function handleUnexpectedErrors(callback: (err: unknown) => void): void
|
|
596
|
-
/**
|
|
597
|
-
* Safe get value from header
|
|
598
|
-
* @param headers response header
|
|
599
|
-
* @param key target header key
|
|
600
|
-
*/
|
|
601
|
-
function getHeader(headers: Record<string, Arrayable<string>>, key: any): any
|
|
602
|
-
function downloadUtil<T>(
|
|
603
|
-
url: string,
|
|
604
|
-
headers: Record<string, any>,
|
|
605
|
-
signal: AbortSignal,
|
|
606
|
-
onResponse: (resp: IncomingMessage, resolve: (data: T) => void, reject: (e: any) => void) => void,
|
|
607
|
-
): Promise<T>
|
|
608
|
-
/**
|
|
609
|
-
* Default function to download json and parse to UpdateJson
|
|
610
|
-
* @param url target url
|
|
611
|
-
* @param headers extra headers
|
|
612
|
-
* @param signal abort signal
|
|
613
|
-
* @param resolveData on resolve
|
|
614
|
-
*/
|
|
615
|
-
function defaultDownloadJSON<T>(
|
|
616
|
-
url: string,
|
|
617
|
-
headers: Record<string, any>,
|
|
618
|
-
signal: AbortSignal,
|
|
619
|
-
resolveData?: ResolveDataFn,
|
|
620
|
-
): Promise<T>
|
|
621
|
-
/**
|
|
622
|
-
* Default function to download json and parse to UpdateJson
|
|
623
|
-
* @param url target url
|
|
624
|
-
* @param headers extra headers
|
|
625
|
-
* @param signal abort signal
|
|
626
|
-
*/
|
|
627
|
-
function defaultDownloadUpdateJSON(
|
|
628
|
-
url: string,
|
|
629
|
-
headers: Record<string, any>,
|
|
630
|
-
signal: AbortSignal,
|
|
631
|
-
): Promise<UpdateJSON>
|
|
632
|
-
/**
|
|
633
|
-
* Default function to download asar buffer,
|
|
634
|
-
* get total size from `Content-Length` header
|
|
635
|
-
* @param url target url
|
|
636
|
-
* @param headers extra headers
|
|
637
|
-
* @param signal abort signal
|
|
638
|
-
* @param onDownloading on downloading callback
|
|
639
|
-
*/
|
|
640
|
-
function defaultDownloadAsar(
|
|
641
|
-
url: string,
|
|
642
|
-
headers: Record<string, any>,
|
|
643
|
-
signal: AbortSignal,
|
|
644
|
-
onDownloading?: (progress: DownloadingInfo) => void,
|
|
645
|
-
): Promise<Buffer>
|
|
646
|
-
```
|
|
647
|
-
|
|
648
|
-
### Types
|
|
649
|
-
|
|
650
|
-
#### Entry
|
|
651
|
-
|
|
652
|
-
```ts
|
|
653
|
-
export interface AppOption {
|
|
654
|
-
/**
|
|
655
|
-
* Path to index file that make {@link startupWithUpdater} as default export
|
|
656
|
-
*
|
|
657
|
-
* Generate from plugin configuration by default
|
|
658
|
-
*/
|
|
659
|
-
mainPath?: string
|
|
660
|
-
/**
|
|
661
|
-
* Updater options
|
|
662
|
-
*/
|
|
663
|
-
updater?: (() => Promisable<Updater>) | UpdaterOption
|
|
664
|
-
/**
|
|
665
|
-
* Hooks on rename temp asar path to `${app.name}.asar`
|
|
666
|
-
*/
|
|
667
|
-
onInstall?: OnInstallFunction
|
|
668
|
-
/**
|
|
669
|
-
* Hooks before app startup
|
|
670
|
-
* @param mainFilePath main file path of `${app.name}.asar`
|
|
671
|
-
* @param logger logger
|
|
672
|
-
*/
|
|
673
|
-
beforeStart?: (mainFilePath: string, logger?: Logger) => Promisable<void>
|
|
674
|
-
/**
|
|
675
|
-
* Hooks on app startup error
|
|
676
|
-
* @param err installing or startup error
|
|
677
|
-
* @param logger logger
|
|
678
|
-
*/
|
|
679
|
-
onStartError?: (err: unknown, logger?: Logger) => void
|
|
680
|
-
}
|
|
681
|
-
/**
|
|
682
|
-
* Hooks on rename temp asar path to `${app.name}.asar`
|
|
683
|
-
* @param install `() => renameSync(tempAsarPath, appNameAsarPath)`
|
|
684
|
-
* @param tempAsarPath temp(updated) asar path
|
|
685
|
-
* @param appNameAsarPath `${app.name}.asar` path
|
|
686
|
-
* @param logger logger
|
|
687
|
-
* @default install(); logger.info('update success!')
|
|
688
|
-
*/
|
|
689
|
-
type OnInstallFunction = (
|
|
690
|
-
install: VoidFunction,
|
|
691
|
-
tempAsarPath: string,
|
|
692
|
-
appNameAsarPath: string,
|
|
693
|
-
logger?: Logger,
|
|
694
|
-
) => Promisable<void>
|
|
775
|
+
electronWithUpdater({
|
|
776
|
+
notBundle: false,
|
|
777
|
+
entry: {
|
|
778
|
+
files: './electron/entry.ts',
|
|
779
|
+
},
|
|
780
|
+
main: {
|
|
781
|
+
files: './electron/main/index.ts',
|
|
782
|
+
},
|
|
783
|
+
})
|
|
695
784
|
```
|
|
696
785
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
```ts
|
|
700
|
-
export interface UpdaterOption {
|
|
701
|
-
/**
|
|
702
|
-
* Update provider
|
|
703
|
-
*
|
|
704
|
-
* If you will not setup `UpdateJSON` or `Buffer` in params when checking update or download, this option is **required**
|
|
705
|
-
*/
|
|
706
|
-
provider?: IProvider
|
|
707
|
-
/**
|
|
708
|
-
* Certifaction key of signature, which will be auto generated by plugin,
|
|
709
|
-
* generate by `selfsigned` if not set
|
|
710
|
-
*/
|
|
711
|
-
SIGNATURE_CERT?: string
|
|
712
|
-
/**
|
|
713
|
-
* Whether to receive beta update
|
|
714
|
-
*/
|
|
715
|
-
receiveBeta?: boolean
|
|
716
|
-
/**
|
|
717
|
-
* Updater logger
|
|
718
|
-
*/
|
|
719
|
-
logger?: Logger
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
export type Logger = {
|
|
723
|
-
info: (msg: string) => void
|
|
724
|
-
debug: (msg: string) => void
|
|
725
|
-
warn: (msg: string) => void
|
|
726
|
-
error: (msg: string, e?: Error) => void
|
|
727
|
-
}
|
|
728
|
-
```
|
|
786
|
+
## Utilities
|
|
729
787
|
|
|
730
|
-
|
|
788
|
+
Import from `electron-incremental-update/utils`:
|
|
731
789
|
|
|
732
790
|
```ts
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
* Provider name
|
|
765
|
-
*/
|
|
766
|
-
name: string
|
|
767
|
-
/**
|
|
768
|
-
* Download update json
|
|
769
|
-
* @param versionPath parsed version path in project
|
|
770
|
-
* @param signal abort signal
|
|
771
|
-
*/
|
|
772
|
-
downloadJSON: (versionPath: string, signal: AbortSignal) => Promise<UpdateJSON>
|
|
773
|
-
/**
|
|
774
|
-
* Download update asar
|
|
775
|
-
* @param name app name
|
|
776
|
-
* @param updateInfo existing update info
|
|
777
|
-
* @param signal abort signal
|
|
778
|
-
* @param onDownloading hook for on downloading
|
|
779
|
-
*/
|
|
780
|
-
downloadAsar: (
|
|
781
|
-
name: string,
|
|
782
|
-
updateInfo: UpdateInfo,
|
|
783
|
-
signal: AbortSignal,
|
|
784
|
-
onDownloading?: (info: DownloadingInfo) => void,
|
|
785
|
-
) => Promise<Buffer>
|
|
786
|
-
/**
|
|
787
|
-
* Check the old version is less than new version
|
|
788
|
-
* @param oldVer old version string
|
|
789
|
-
* @param newVer new version string
|
|
790
|
-
*/
|
|
791
|
-
isLowerVersion: (oldVer: string, newVer: string) => boolean
|
|
792
|
-
/**
|
|
793
|
-
* Function to decompress file using brotli
|
|
794
|
-
* @param buffer compressed file buffer
|
|
795
|
-
*/
|
|
796
|
-
unzipFile: (buffer: Buffer) => Promise<Buffer>
|
|
797
|
-
/**
|
|
798
|
-
* Verify asar signature,
|
|
799
|
-
* if signature is valid, returns the version, otherwise returns `undefined`
|
|
800
|
-
* @param buffer file buffer
|
|
801
|
-
* @param version target version
|
|
802
|
-
* @param signature signature
|
|
803
|
-
* @param cert certificate
|
|
804
|
-
*/
|
|
805
|
-
verifySignaure: (
|
|
806
|
-
buffer: Buffer,
|
|
807
|
-
version: string,
|
|
808
|
-
signature: string,
|
|
809
|
-
cert: string,
|
|
810
|
-
) => Promisable<boolean>
|
|
811
|
-
}
|
|
791
|
+
import {
|
|
792
|
+
aesDecrypt,
|
|
793
|
+
aesEncrypt,
|
|
794
|
+
beautifyDevTools,
|
|
795
|
+
defaultIsLowerVersion,
|
|
796
|
+
defaultSignature,
|
|
797
|
+
defaultUnzipFile,
|
|
798
|
+
defaultVerifySignature,
|
|
799
|
+
defaultZipFile,
|
|
800
|
+
getAppVersion,
|
|
801
|
+
getEntryVersion,
|
|
802
|
+
getPathFromAppNameAsar,
|
|
803
|
+
getPathFromEntryAsar,
|
|
804
|
+
getPathFromMain,
|
|
805
|
+
getPathFromPreload,
|
|
806
|
+
getPathFromPublic,
|
|
807
|
+
handleUnexpectedErrors,
|
|
808
|
+
hashBuffer,
|
|
809
|
+
importNative,
|
|
810
|
+
isDev,
|
|
811
|
+
isLinux,
|
|
812
|
+
isMac,
|
|
813
|
+
isWin,
|
|
814
|
+
loadPage,
|
|
815
|
+
parseVersion,
|
|
816
|
+
requireNative,
|
|
817
|
+
restartApp,
|
|
818
|
+
setAppUserModelId,
|
|
819
|
+
setPortableDataPath,
|
|
820
|
+
singleInstance,
|
|
821
|
+
} from 'electron-incremental-update/utils'
|
|
812
822
|
```
|
|
813
823
|
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
* Manually setup package.json, read name, version and main,
|
|
829
|
-
* use `local-pkg` of `loadPackageJSON()` to load package.json by default
|
|
830
|
-
* ```ts
|
|
831
|
-
* import pkg from './package.json'
|
|
832
|
-
* ```
|
|
833
|
-
*/
|
|
834
|
-
pkg?: PKG
|
|
835
|
-
/**
|
|
836
|
-
* Whether to generate sourcemap
|
|
837
|
-
* @default !isBuild
|
|
838
|
-
*/
|
|
839
|
-
sourcemap?: boolean
|
|
840
|
-
/**
|
|
841
|
-
* Whether to minify the code
|
|
842
|
-
* @default isBuild
|
|
843
|
-
*/
|
|
844
|
-
minify?: boolean
|
|
845
|
-
/**
|
|
846
|
-
* Whether to generate bytecode
|
|
847
|
-
*
|
|
848
|
-
* **Only support CommonJS**
|
|
849
|
-
*
|
|
850
|
-
* Only main process by default, if you want to use in preload script, please use `electronWithUpdater({ bytecode: { enablePreload: true } })` and set `sandbox: false` when creating window
|
|
851
|
-
*/
|
|
852
|
-
bytecode?: boolean | BytecodeOptions
|
|
853
|
-
/**
|
|
854
|
-
* Use `NotBundle()` plugin in main
|
|
855
|
-
* @default true
|
|
856
|
-
*/
|
|
857
|
-
useNotBundle?: boolean
|
|
858
|
-
/**
|
|
859
|
-
* Whether to generate version json
|
|
860
|
-
* @default isCI
|
|
861
|
-
*/
|
|
862
|
-
buildVersionJson?: boolean
|
|
863
|
-
/**
|
|
864
|
-
* Main process options
|
|
865
|
-
*
|
|
866
|
-
* To change output directories, use `options.updater.paths.electronDistPath` instead
|
|
867
|
-
*/
|
|
868
|
-
main: {
|
|
869
|
-
/**
|
|
870
|
-
* Shortcut of `build.rollupOptions.input`
|
|
871
|
-
*/
|
|
872
|
-
files: NonNullable<ElectronOptions['entry']>
|
|
873
|
-
/**
|
|
874
|
-
* Electron App startup function.
|
|
875
|
-
*
|
|
876
|
-
* It will mount the Electron App child-process to `process.electronApp`.
|
|
877
|
-
* @param argv default value `['.', '--no-sandbox']`
|
|
878
|
-
* @param options options for `child_process.spawn`
|
|
879
|
-
* @param customElectronPkg custom electron package name (default: 'electron')
|
|
880
|
-
*/
|
|
881
|
-
onstart?: ElectronOptions['onstart']
|
|
882
|
-
} & ViteOverride
|
|
883
|
-
/**
|
|
884
|
-
* Preload process options
|
|
885
|
-
*
|
|
886
|
-
* To change output directories, use `options.updater.paths.electronDistPath` instead
|
|
887
|
-
*/
|
|
888
|
-
preload: {
|
|
889
|
-
/**
|
|
890
|
-
* Shortcut of `build.rollupOptions.input`.
|
|
891
|
-
*
|
|
892
|
-
* Preload scripts may contain Web assets, so use the `build.rollupOptions.input` instead `build.lib.entry`.
|
|
893
|
-
*/
|
|
894
|
-
files: NonNullable<ElectronOptions['entry']>
|
|
895
|
-
} & ViteOverride
|
|
896
|
-
/**
|
|
897
|
-
* Updater options
|
|
898
|
-
*/
|
|
899
|
-
updater?: UpdaterOptions
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
export interface UpdaterOptions {
|
|
903
|
-
/**
|
|
904
|
-
* Minimum version of entry
|
|
905
|
-
* @default '0.0.0'
|
|
906
|
-
*/
|
|
907
|
-
minimumVersion?: string
|
|
908
|
-
/**
|
|
909
|
-
* Options for entry (app.asar)
|
|
910
|
-
*/
|
|
911
|
-
entry?: BuildEntryOption
|
|
912
|
-
/**
|
|
913
|
-
* Options for paths
|
|
914
|
-
*/
|
|
915
|
-
paths?: {
|
|
916
|
-
/**
|
|
917
|
-
* Path to asar file
|
|
918
|
-
* @default `release/${app.name}.asar`
|
|
919
|
-
*/
|
|
920
|
-
asarOutputPath?: string
|
|
921
|
-
/**
|
|
922
|
-
* Path to version info output, content is {@link UpdateJSON}
|
|
923
|
-
* @default `version.json`
|
|
924
|
-
*/
|
|
925
|
-
versionPath?: string
|
|
926
|
-
/**
|
|
927
|
-
* Path to gzipped asar file
|
|
928
|
-
* @default `release/${app.name}-${version}.asar.gz`
|
|
929
|
-
*/
|
|
930
|
-
gzipPath?: string
|
|
931
|
-
/**
|
|
932
|
-
* Path to electron build output
|
|
933
|
-
* @default `dist-electron`
|
|
934
|
-
*/
|
|
935
|
-
electronDistPath?: string
|
|
936
|
-
/**
|
|
937
|
-
* Path to renderer build output
|
|
938
|
-
* @default `dist`
|
|
939
|
-
*/
|
|
940
|
-
rendererDistPath?: string
|
|
941
|
-
}
|
|
942
|
-
/**
|
|
943
|
-
* signature config
|
|
944
|
-
*/
|
|
945
|
-
keys?: {
|
|
946
|
-
/**
|
|
947
|
-
* Path to the pem file that contains private key
|
|
948
|
-
* If not ended with .pem, it will be appended
|
|
949
|
-
*
|
|
950
|
-
* **If `UPDATER_PK` is set, will read it instead of read from `privateKeyPath`**
|
|
951
|
-
* @default 'keys/private.pem'
|
|
952
|
-
*/
|
|
953
|
-
privateKeyPath?: string
|
|
954
|
-
/**
|
|
955
|
-
* Path to the pem file that contains public key
|
|
956
|
-
* If not ended with .pem, it will be appended
|
|
957
|
-
*
|
|
958
|
-
* **If `UPDATER_CERT` is set, will read it instead of read from `certPath`**
|
|
959
|
-
* @default 'keys/cert.pem'
|
|
960
|
-
*/
|
|
961
|
-
certPath?: string
|
|
962
|
-
/**
|
|
963
|
-
* Length of the key
|
|
964
|
-
* @default 2048
|
|
965
|
-
*/
|
|
966
|
-
keyLength?: number
|
|
967
|
-
/**
|
|
968
|
-
* X509 certificate info
|
|
969
|
-
*
|
|
970
|
-
* only generate simple **self-signed** certificate **without extensions**
|
|
971
|
-
*/
|
|
972
|
-
certInfo?: {
|
|
973
|
-
/**
|
|
974
|
-
* The subject of the certificate
|
|
975
|
-
*
|
|
976
|
-
* @default { commonName: `${app.name}`, organizationName: `org.${app.name}` }
|
|
977
|
-
*/
|
|
978
|
-
subject?: DistinguishedName
|
|
979
|
-
/**
|
|
980
|
-
* Expire days of the certificate
|
|
981
|
-
*
|
|
982
|
-
* @default 3650
|
|
983
|
-
*/
|
|
984
|
-
days?: number
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
overrideGenerator?: GeneratorOverrideFunctions
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
export interface BytecodeOptions {
|
|
991
|
-
enable: boolean
|
|
992
|
-
/**
|
|
993
|
-
* Enable in preload script. Remember to set `sandbox: false` when creating window
|
|
994
|
-
*/
|
|
995
|
-
preload?: boolean
|
|
996
|
-
/**
|
|
997
|
-
* Custom electron binary path
|
|
998
|
-
*/
|
|
999
|
-
electronPath?: string
|
|
1000
|
-
/**
|
|
1001
|
-
* Before transformed code compile function. If return `Falsy` value, it will be ignored
|
|
1002
|
-
* @param code transformed code
|
|
1003
|
-
* @param id file path
|
|
1004
|
-
*/
|
|
1005
|
-
beforeCompile?: (code: string, id: string) => Promisable<string | null | undefined | void>
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
export interface BuildEntryOption {
|
|
1009
|
-
/**
|
|
1010
|
-
* Override to minify on entry
|
|
1011
|
-
* @default isBuild
|
|
1012
|
-
*/
|
|
1013
|
-
minify?: boolean
|
|
1014
|
-
/**
|
|
1015
|
-
* Override to generate sourcemap on entry
|
|
1016
|
-
*/
|
|
1017
|
-
sourcemap?: boolean
|
|
1018
|
-
/**
|
|
1019
|
-
* Path to app entry output file
|
|
1020
|
-
* @default 'dist-entry'
|
|
1021
|
-
*/
|
|
1022
|
-
entryOutputDirPath?: string
|
|
1023
|
-
/**
|
|
1024
|
-
* Path to app entry file
|
|
1025
|
-
* @default 'electron/entry.ts'
|
|
1026
|
-
*/
|
|
1027
|
-
appEntryPath?: string
|
|
1028
|
-
/**
|
|
1029
|
-
* Vite input options of native modules in entry directory
|
|
1030
|
-
*
|
|
1031
|
-
* @default {}
|
|
1032
|
-
* @example
|
|
1033
|
-
* { db: './electron/native/db.ts' }
|
|
1034
|
-
*/
|
|
1035
|
-
nativeModuleEntryMap?: Record<string, string>
|
|
1036
|
-
/**
|
|
1037
|
-
* Skip process dynamic require
|
|
1038
|
-
*
|
|
1039
|
-
* Useful for `better-sqlite3` and other old packages
|
|
1040
|
-
*/
|
|
1041
|
-
ignoreDynamicRequires?: boolean
|
|
1042
|
-
/**
|
|
1043
|
-
* `external` option in `build.rollupOptions`,
|
|
1044
|
-
* default is node built-in modules or native modules.
|
|
1045
|
-
*
|
|
1046
|
-
* If is in dev and {@link postBuild} is not setup, will also
|
|
1047
|
-
* external `dependencies` in `package.json`
|
|
1048
|
-
*/
|
|
1049
|
-
external?: NonNullable<NonNullable<InlineConfig['build']>['rollupOptions']>['external']
|
|
1050
|
-
/**
|
|
1051
|
-
* Custom options for `vite` build
|
|
1052
|
-
* ```ts
|
|
1053
|
-
* const options = {
|
|
1054
|
-
* plugins: [esm(), bytecodePlugin()], // load on needed
|
|
1055
|
-
* build: {
|
|
1056
|
-
* sourcemap,
|
|
1057
|
-
* minify,
|
|
1058
|
-
* outDir: entryOutputDirPath,
|
|
1059
|
-
* commonjsOptions: { ignoreDynamicRequires },
|
|
1060
|
-
* rollupOptions: { external },
|
|
1061
|
-
* },
|
|
1062
|
-
* define,
|
|
1063
|
-
* }
|
|
1064
|
-
* ```
|
|
1065
|
-
*/
|
|
1066
|
-
overrideViteOptions?: InlineConfig
|
|
1067
|
-
/**
|
|
1068
|
-
* By default, all the unbundled modules will be packaged by packager like `electron-builder`.
|
|
1069
|
-
* If setup, all the `dependencies` in `package.json` will be bundled by default, and you need
|
|
1070
|
-
* to manually handle the native module files.
|
|
1071
|
-
*/
|
|
1072
|
-
postBuild?: (args: {
|
|
1073
|
-
/**
|
|
1074
|
-
* Get path from `entryOutputDirPath`
|
|
1075
|
-
*/
|
|
1076
|
-
getPathFromEntryOutputDir: (...paths: string[]) => string
|
|
1077
|
-
/**
|
|
1078
|
-
* Check exist and copy file to `entryOutputDirPath`
|
|
1079
|
-
*
|
|
1080
|
-
* If `to` absent, set to `basename(from)`
|
|
1081
|
-
*
|
|
1082
|
-
* If `skipIfExist` absent, skip copy if `to` exist
|
|
1083
|
-
*/
|
|
1084
|
-
copyToEntryOutputDir: (options: {
|
|
1085
|
-
from: string
|
|
1086
|
-
to?: string
|
|
1087
|
-
/**
|
|
1088
|
-
* Skip copy if `to` exist
|
|
1089
|
-
* @default true
|
|
1090
|
-
*/
|
|
1091
|
-
skipIfExist?: boolean
|
|
1092
|
-
}) => void
|
|
1093
|
-
/**
|
|
1094
|
-
* Copy specified modules to entry output dir, just like `external` option in rollup
|
|
1095
|
-
*/
|
|
1096
|
-
copyModules: (options: {
|
|
1097
|
-
/**
|
|
1098
|
-
* External Modules
|
|
1099
|
-
*/
|
|
1100
|
-
modules: string[]
|
|
1101
|
-
/**
|
|
1102
|
-
* Skip copy if `to` exist
|
|
1103
|
-
* @default true
|
|
1104
|
-
*/
|
|
1105
|
-
skipIfExist?: boolean
|
|
1106
|
-
}) => void
|
|
1107
|
-
}) => Promisable<void>
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
export interface GeneratorOverrideFunctions {
|
|
1111
|
-
/**
|
|
1112
|
-
* Custom signature generate function
|
|
1113
|
-
* @param buffer file buffer
|
|
1114
|
-
* @param privateKey private key
|
|
1115
|
-
* @param cert certificate string, **EOL must be '\n'**
|
|
1116
|
-
* @param version current version
|
|
1117
|
-
*/
|
|
1118
|
-
generateSignature?: (
|
|
1119
|
-
buffer: Buffer,
|
|
1120
|
-
privateKey: string,
|
|
1121
|
-
cert: string,
|
|
1122
|
-
version: string,
|
|
1123
|
-
) => Promisable<string>
|
|
1124
|
-
/**
|
|
1125
|
-
* Custom generate update json function
|
|
1126
|
-
* @param existingJson The existing JSON object.
|
|
1127
|
-
* @param buffer file buffer
|
|
1128
|
-
* @param signature generated signature
|
|
1129
|
-
* @param version current version
|
|
1130
|
-
* @param minVersion The minimum version
|
|
1131
|
-
*/
|
|
1132
|
-
generateUpdateJson?: (
|
|
1133
|
-
existingJson: UpdateJSON,
|
|
1134
|
-
signature: string,
|
|
1135
|
-
version: string,
|
|
1136
|
-
minVersion: string,
|
|
1137
|
-
) => Promisable<UpdateJSON>
|
|
1138
|
-
/**
|
|
1139
|
-
* Custom generate zip file buffer
|
|
1140
|
-
* @param buffer source buffer
|
|
1141
|
-
*/
|
|
1142
|
-
generateGzipFile?: (buffer: Buffer) => Promisable<Buffer>
|
|
1143
|
-
}
|
|
1144
|
-
````
|
|
824
|
+
Common helpers:
|
|
825
|
+
|
|
826
|
+
- `getPathFromAppNameAsar(...paths)`: path inside `${app.name}.asar`.
|
|
827
|
+
- `getPathFromEntryAsar(...paths)`: path inside `app.asar`.
|
|
828
|
+
- `getPathFromMain(...paths)`: path inside the built main directory.
|
|
829
|
+
- `getPathFromPreload(...paths)`: path inside the built preload directory.
|
|
830
|
+
- `getPathFromPublic(...paths)`: path inside `public` in dev or renderer output in production.
|
|
831
|
+
- `getAppVersion()`: current app version. In dev, returns the entry version.
|
|
832
|
+
- `getEntryVersion()`: version from Electron app metadata.
|
|
833
|
+
- `loadPage(win, htmlFilePath)`: loads `VITE_DEV_SERVER_URL` in dev or renderer HTML in production.
|
|
834
|
+
- `singleInstance(window)`: restores and focuses the window on `second-instance`.
|
|
835
|
+
- `setPortableDataPath(dirName, create)`: stores user data beside the executable for portable apps.
|
|
836
|
+
- `requireNative(moduleName)`: loads a CommonJS native helper from entry asar.
|
|
837
|
+
- `importNative(moduleName)`: imports an ES module native helper from entry asar.
|
|
1145
838
|
|
|
1146
839
|
## Credits
|
|
1147
840
|
|
|
1148
|
-
- [Obsidian](https://obsidian.md/) for
|
|
1149
|
-
- [vite-plugin-electron](https://github.com/electron-vite/vite-plugin-electron) for
|
|
1150
|
-
- [electron-builder](https://github.com/electron-userland/electron-builder) for
|
|
841
|
+
- [Obsidian](https://obsidian.md/) for the dual asar update strategy
|
|
842
|
+
- [vite-plugin-electron](https://github.com/electron-vite/vite-plugin-electron) for the Vite Electron plugin foundation
|
|
843
|
+
- [electron-builder](https://github.com/electron-userland/electron-builder) for Electron packaging
|
|
1151
844
|
- [electron-vite](https://github.com/alex8088/electron-vite) for bytecode plugin inspiration
|
|
1152
845
|
|
|
1153
846
|
## License
|