1+ import InstallNpm from ' ./content/_install-npm.mdx' ;
2+ import InstallVpk from ' ./content/_install-vpk.mdx' ;
3+ import BuildRelease from ' ./content/_build-release.mdx' ;
4+ import Completion from ' ./content/_completion.mdx' ;
5+ import Admonition from ' @theme/Admonition' ;
6+
7+
18# Getting Started: JS / Electron
29<AppliesTo all />
310Get started with our NPM package for JS & Electron.
@@ -9,129 +16,136 @@ npm init electron-app@latest my-new-app-name -- --template=webpack-typescript
916```
1017:::
1118
12- 1 . Add Velopack to your ` package.json ` :
13- ``` txt
14- npm install velopack
15- ```
16-
17- 0 . Add the following code to your entry point (eg. ` index.ts ` ) as early as possible (before any electron startup code etc.):
18- ``` js
19- const { VelopackApp } = require (' velopack' );
20-
21- // Velopack builder needs to be the first thing to run in the main process.
22- // In some cases, it might quit/restart the process to perform tasks.
23- VelopackApp .build ().run ();
24-
25- // ... your other app startup code here
26- ```
27- :::warning
28- If you currently have any "Squirrel" startup code you should remove this now. For example:
29- ```
30- npm uninstall electron-squirrel-startup @electron-forge/maker-squirrel
31- ```
32- :::
33-
34- 0 . Add auto-updates to your app:
35- This has some complexity because of electron's IPC model and that Velopack has a native node module.
36-
37- First, you should setup IPC handlers in your main application thread:
38- ``` js
39- const { VelopackApp } = require (' velopack' );
40-
41- ipcMain .handle (" velopack:get-version" , () => {
42- try {
19+ <InstallNpm step = { 1 } />
20+
21+ <FancyStep step = { 2 } >
22+ <details >
23+ <summary >
24+ <strong >Configure Velopack at the beginning of your entry point</strong >
25+ </summary >
26+
27+ Add the following code to your entry point (eg. ` index.ts ` ) as early as possible (before any electron startup code etc.):
28+ ```js
29+ const { VelopackApp } = require('velopack');
30+
31+ // Velopack builder needs to be the first thing to run in the main process.
32+ // In some cases, it might quit/restart the process to perform tasks.
33+ VelopackApp.build().run();
34+
35+ // ... your other app startup code here
36+ ```
37+
38+ <Admonition type = " warning" title = " Squirrel Startup Code" >
39+ If you currently have any "Squirrel" startup code you should remove this now. For example:
40+ ```
41+ npm uninstall electron-squirrel-startup @electron-forge/maker-squirrel
42+ ```
43+ </Admonition >
44+ </details >
45+ </FancyStep >
46+
47+ <FancyStep step = { 3 } >
48+ <details >
49+ <summary >
50+ <strong >Add update check within your app</strong >
51+ </summary >
52+
53+ This has some complexity because of electron's IPC model and that Velopack has a native node module.
54+
55+ First, you should setup IPC handlers in your main application thread:
56+ ```js
57+ const { VelopackApp } = require('velopack');
58+
59+ ipcMain.handle("velopack:get-version", () => {
60+ try {
61+ const updateManager = new UpdateManager (updateUrl );
62+ return updateManager.getCurrentVersion();
63+ } catch (e ) {
64+ return ` Not Installed (${e }) ` ;
65+ }
66+ });
67+
68+ ipcMain.handle(" velopack:check-for-update" , async () => {
4369 const updateManager = new UpdateManager (updateUrl );
44- return updateManager .getCurrentVersion ();
45- } catch (e) {
46- return ` Not Installed (${ e} )` ;
47- }
48- });
49-
50- ipcMain .handle (" velopack:check-for-update" , async () => {
51- const updateManager = new UpdateManager (updateUrl);
52- return await updateManager .checkForUpdatesAsync ();
53- });
54-
55- ipcMain .handle (" velopack:download-update" , async (_ , updateInfo ) => {
56- const updateManager = new UpdateManager (updateUrl);
57- await updateManager .downloadUpdateAsync (updateInfo);
58- return true ;
59- });
60-
61- ipcMain .handle (" velopack:apply-update" , async (_ , updateInfo ) => {
62- const updateManager = new UpdateManager (updateUrl);
63- await updateManager .waitExitThenApplyUpdate (updateInfo);
64- app .quit ();
65- return true ;
66- });
67- ```
68-
69- Next, you need to expose these functions to your renderer processes in ` preload.ts `
70- ``` js
71- import { contextBridge , ipcRenderer } from " electron" ;
72- import type { UpdateInfo } from " velopack" ;
73-
74- interface VelopackBridgeApi {
75- getVersion : () => Promise < string> ,
76- checkForUpdates : () => Promise < UpdateInfo> ,
77- downloadUpdates : (updateInfo : UpdateInfo ) => Promise < boolean> ,
78- applyUpdates : (updateInfo : UpdateInfo ) => Promise < boolean> ,
79- }
80-
81- declare global {
82- interface Window {
83- velopackApi: VelopackBridgeApi;
84- }
85- }
86-
87- const velopackApi: VelopackBridgeApi = {
88- getVersion : () => ipcRenderer .invoke (" velopack:get-version" ),
89- checkForUpdates : () => ipcRenderer .invoke (" velopack:check-for-update" ),
90- downloadUpdates : (updateInfo : UpdateInfo ) => ipcRenderer .invoke (" velopack:download-update" , updateInfo),
91- applyUpdates : (updateInfo : UpdateInfo ) => ipcRenderer .invoke (" velopack:apply-update" , updateInfo)
92- };
93-
94- contextBridge .exposeInMainWorld (" velopackApi" , velopackApi);
95- ```
96-
97- Lastly, you can now use these functions in your renderer to provide an update UI to your users:
98- ``` js
99- async function updateApp () {
100- // check for new version
101- const updateInfo = await window .velopackApi .checkForUpdates ();
102- if (! updateInfo) {
103- return ; // no updates available
104- }
70+ return await updateManager .checkForUpdatesAsync ();
71+ });
10572
106- // download new version
107- await window .velopackApi .downloadUpdates (updateInfo);
73+ ipcMain.handle(" velopack:download-update" , async (_ , updateInfo ) => {
74+ const updateManager = new UpdateManager (updateUrl );
75+ await updateManager .downloadUpdateAsync (updateInfo );
76+ return true;
77+ });
10878
109- // install new version and restart app
110- await window .velopackApi .applyUpdates (updateInfo);
111- }
79+ ipcMain.handle(" velopack:apply-update" , async (_ , updateInfo ) => {
80+ const updateManager = new UpdateManager (updateUrl );
81+ await updateManager .waitExitThenApplyUpdate (updateInfo );
82+ app .quit ();
83+ return true;
84+ });
85+ ` ` `
86+
87+ Next, you need to expose these functions to your renderer processes in ` preload .ts `
88+ ` ` ` js
89+ import { contextBridge, ipcRenderer } from " electron" ;
90+ import type { UpdateInfo } from " velopack" ;
91+
92+ interface VelopackBridgeApi {
93+ getVersion: () => Promise < string > ,
94+ checkForUpdates : () => Promise < UpdateInfo > ,
95+ downloadUpdates : (updateInfo : UpdateInfo ) => Promise < boolean > ,
96+ applyUpdates : (updateInfo : UpdateInfo ) => Promise < boolean > ,
97+ }
11298
113- ```
99+ declare global {
100+ interface Window {
101+ velopackApi : VelopackBridgeApi ;
102+ }
103+ }
104+
105+ const velopackApi : VelopackBridgeApi = {
106+ getVersion : () => ipcRenderer .invoke (" velopack:get-version" ),
107+ checkForUpdates : () => ipcRenderer .invoke (" velopack:check-for-update" ),
108+ downloadUpdates : (updateInfo : UpdateInfo ) => ipcRenderer .invoke (" velopack:download-update" , updateInfo ),
109+ applyUpdates : (updateInfo : UpdateInfo ) => ipcRenderer .invoke (" velopack:apply-update" , updateInfo )
110+ };
111+
112+ contextBridge .exposeInMainWorld (" velopackApi" , velopackApi );
113+ ` ` `
114+
115+ Lastly, you can now use these functions in your renderer to provide an update UI to your users:
116+ ` ` ` js
117+ async function updateApp() {
118+ // check for new version
119+ const updateInfo = await window .velopackApi .checkForUpdates ();
120+ if (! updateInfo ) {
121+ return ; // no updates available
122+ }
123+
124+ // download new version
125+ await window .velopackApi .downloadUpdates (updateInfo );
126+
127+ // install new version and restart app
128+ await window .velopackApi .applyUpdates (updateInfo );
129+ }
130+ ` ` `
131+ </details>
132+ </FancyStep>
114133
115- Review our Electron sample app for a more complete example.
116-
134+ <FancyStep step={4}>
135+ <details>
136+ <summary>
137+ <strong>Build your app</strong>
138+ </summary>
117139
118- 0 . Compile your app to a binary (eg. ` .exe ` on Windows). Example using electron forge:
119- ``` sh
120- npx electron-forge package
121- ```
140+ Compile your app to a binary (eg. ` .exe ` on Windows). Example using electron forge:
141+ ` ` ` sh
142+ npx electron - forge package
143+ ` ` `
144+ </details>
145+ </FancyStep>
122146
123- 0 . Install the ` vpk ` command line tool:
124- ``` sh
125- dotnet tool update -g vpk
126- ```
127- :::tip
128- *** You must have the .NET Core SDK 8 installed to use and update ` vpk ` ***
129- :::
147+ <InstallVpk step={5}/>
130148
131- 0 . Package your Velopack release / installers:
132- ``` sh
133- vpk pack -u MyAppUniqueId -v 1.0.0 -p ./myBuildDir -e myexename.exe
134- ```
149+ <BuildRelease step={6}/>
135150
136- ✅ You're Done! Your app now has auto-updates and an installer.
137- You can upload your release to your website, or use the ` vpk upload ` command to publish it to the destination of your choice.
151+ <Completion />
0 commit comments