@witchcraft/nuxt-electron 0.2.0 → 0.2.1
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 +74 -46
- package/dist/module.json +1 -1
- package/dist/module.mjs +5 -1
- package/dist/runtime/electron/createProxiedProtocolHandler.js +1 -1
- package/dist/runtime/electron/getPaths.js +1 -1
- package/package.json +1 -1
- package/src/module.ts +7 -1
- package/src/runtime/electron/createProxiedProtocolHandler.ts +1 -1
- package/src/runtime/electron/getPaths.ts +1 -1
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
- :scissors: Trims server and non-electron routes from the electron bundle.
|
|
16
16
|
- :open_file_folder: Modifies directory structure for easier multi-platform builds.
|
|
17
17
|
- :snowflake: Nix Support - Playground contains an example flake for reproducible development and builds.
|
|
18
|
+
- :closed_lock_with_key: Supports Auth - Integrates with my auth library [@witchcraft/nuxt-auth](https://github.com/witchcraftjs/nuxt-auth) for local-first auth.
|
|
18
19
|
- :hammer_and_wrench: Helpful Tools/Composables
|
|
19
20
|
- `isElectron`
|
|
20
21
|
- Electron Only
|
|
@@ -47,11 +48,15 @@ pnpm build
|
|
|
47
48
|
pnpm build:electron:pack
|
|
48
49
|
# in one tab
|
|
49
50
|
pnpm preview
|
|
50
|
-
# in another tab
|
|
51
|
+
# in another tab - replace `linux-unpacked` with your platform
|
|
51
52
|
OVERRIDE_PUBLIC_SERVER_URL=http://localhost:3000 ./.dist/electron/release/linux-unpacked/your-app-name
|
|
52
53
|
```
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
#### Nix
|
|
56
|
+
|
|
57
|
+
If you're using nix the first example should work in the dev shell. The second won't. You can do `nix run`, but warning, this is like building and doing `pnpm launch:electron` so it api will be pointed at production server (see below).
|
|
58
|
+
|
|
59
|
+
See [#Usage on Nix](#Usage-on-Nix) for more details.
|
|
55
60
|
|
|
56
61
|
## Install
|
|
57
62
|
```bash
|
|
@@ -83,7 +88,10 @@ A directory structure like the following is suggested:
|
|
|
83
88
|
│ │ └── ${productName}_${version}.${ext}
|
|
84
89
|
│ └── build/ (for any intermediate builds like electron's)
|
|
85
90
|
├── app/ - nuxt code
|
|
86
|
-
|
|
91
|
+
├── app-electron/ - contains all the main/renderer code
|
|
92
|
+
│ └── package.json - to control packaged dependencies
|
|
93
|
+
└── electron-builder-config.js
|
|
94
|
+
|
|
87
95
|
```
|
|
88
96
|
The module sets it up like this when building electron, but not for the regular build. You should set that to go elsewhere if you're using it (though it's not required).
|
|
89
97
|
|
|
@@ -103,36 +111,12 @@ Usage of nuxt 4's new directory structure is recommended.
|
|
|
103
111
|
|
|
104
112
|
For whatever electron builder you want to use, you must point it at the correct directories.
|
|
105
113
|
|
|
106
|
-
For `electron-builder` with the default directories the module uses and to
|
|
114
|
+
For `electron-builder` with the default directories the module uses and to be able to control which dependencies are packaged with `app-electron/package.json` copy the following:
|
|
107
115
|
|
|
116
|
+
[electron-builder-config.js](https://github.com/witchcraftjs/nuxt-electron/blob/master/playground/electron-builder-config.js)
|
|
117
|
+
[app-electron/package.json](https://github.com/witchcraftjs/nuxt-electron/blob/master/playground/app-electron/package.json)
|
|
108
118
|
|
|
109
|
-
|
|
110
|
-
<summary>Electron Builder Config Example</summary>
|
|
111
|
-
|
|
112
|
-
```json
|
|
113
|
-
{
|
|
114
|
-
"directories": {
|
|
115
|
-
"output": ".dist/electron/release"
|
|
116
|
-
},
|
|
117
|
-
"files": [
|
|
118
|
-
".dist/electron/build/**/*",
|
|
119
|
-
".dist/electron/.output/public/**/*"
|
|
120
|
-
],
|
|
121
|
-
"linux": {
|
|
122
|
-
"artifactName": "${productName}_${version}.${ext}",
|
|
123
|
-
// ...
|
|
124
|
-
},
|
|
125
|
-
"mac": {
|
|
126
|
-
"artifactName": "${productName}_${version}.${ext}",
|
|
127
|
-
// ...
|
|
128
|
-
},
|
|
129
|
-
"win": {
|
|
130
|
-
"artifactName": "${productName}_${version}.${ext}"
|
|
131
|
-
// ...
|
|
132
|
-
},
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
</details>
|
|
119
|
+
They should work out of the box, with the package name as configured in your package.json.
|
|
136
120
|
|
|
137
121
|
Add the following to the package.json:
|
|
138
122
|
|
|
@@ -142,6 +126,12 @@ Add the following to the package.json:
|
|
|
142
126
|
```json
|
|
143
127
|
// package.json
|
|
144
128
|
{
|
|
129
|
+
// these first properties are required to package the app
|
|
130
|
+
"name": "your-app-name",
|
|
131
|
+
"version": "0.0.0",
|
|
132
|
+
"description": "Your app description",
|
|
133
|
+
"author": "Your Name",
|
|
134
|
+
"repository" :"...",
|
|
145
135
|
"main": ".dist/electron/build/main.cjs",
|
|
146
136
|
"scripts": {
|
|
147
137
|
"dev": "nuxi dev",
|
|
@@ -152,7 +142,7 @@ Add the following to the package.json:
|
|
|
152
142
|
"launch:electron": "electron .",
|
|
153
143
|
"launch:electron:dev": "LOG_LEVEL=trace OVERRIDE_PUBLIC_SERVER_URL=http://localhost:3000 electron .",
|
|
154
144
|
"build:electron": "BUILD_ELECTRON=true pnpm build",
|
|
155
|
-
"build:electron:pack": "APP_VERSION=0.0.0 electron-builder",
|
|
145
|
+
"build:electron:pack": "APP_VERSION=0.0.0 electron-builder --config electron-builder-config.js",
|
|
156
146
|
"build:electron:no-pack": "APP_VERSION=0.0.0 SKIP_ELECTRON_PACK=true BUILD_ELECTRON=true nuxi build",
|
|
157
147
|
// write a dev desktop file for linux, see below
|
|
158
148
|
"preview:electron:dev": "concurrently --kill-others \"pnpm preview\" \"sleep 2 && pnpm launch:electron:dev\"",
|
|
@@ -162,7 +152,7 @@ Add the following to the package.json:
|
|
|
162
152
|
```
|
|
163
153
|
</details>
|
|
164
154
|
|
|
165
|
-
|
|
155
|
+
### To Develop
|
|
166
156
|
|
|
167
157
|
Run `pnpm dev:electron`. This will both launch nuxt and open electron.
|
|
168
158
|
|
|
@@ -172,12 +162,12 @@ Run `pnpm dev` to start the nuxt dev server. The dev version of the app will be
|
|
|
172
162
|
|
|
173
163
|
In a seperate terminal run `pnpm launch:electron` to start the electron app (this will do `electron .` which will run the configured `main` property, aka `.dist/electron/build/main.cjs`).
|
|
174
164
|
|
|
175
|
-
|
|
165
|
+
#### Notes
|
|
176
166
|
By default the module will not open electron. You must set `process.env.AUTO_OPEN` to include the string `electron` or set `autoOpen `in the options to true, hence the seperate `dev:electron` script.
|
|
177
167
|
|
|
178
168
|
The idea is if you use other platform modules as well, you'd do `AUTO_OPEN=electron,android`, etc. for each module you wanted to actually have auto open.
|
|
179
169
|
|
|
180
|
-
|
|
170
|
+
### To Build
|
|
181
171
|
|
|
182
172
|
Build the regular nuxt app with `pnpm build` then build the electron app with `pnpm build:electron` or `pnpm build:electron:no-pack` (if you just want to test, you can skip the packing).
|
|
183
173
|
|
|
@@ -191,7 +181,7 @@ You can run `pnpm launch:electron` to launch the production build in nearly exac
|
|
|
191
181
|
|
|
192
182
|
CAREFUL though, **this will proxy api requests to the real server**.
|
|
193
183
|
|
|
194
|
-
|
|
184
|
+
ef you want to test against the local server build, run it with `pnpm preview` then run the app with `pnpm launch:electron:dev`.
|
|
195
185
|
|
|
196
186
|
If you use the example code, it allows `OVERRIDE_PUBLIC_SERVER_URL` which allows the app to override which server the app proxies to and that's what the script is setting to allow this.
|
|
197
187
|
|
|
@@ -208,7 +198,6 @@ We also need to create the nuxt `app://` protocol handler for every window and c
|
|
|
208
198
|
|
|
209
199
|
See full example in [main.ts](https://github.com/witchcraftjs/nuxt-electron/blob/master/playground/app-electron/main.ts).
|
|
210
200
|
|
|
211
|
-
|
|
212
201
|
For the nuxt config, here's the minimum you need, the one in the playground contains additional options for testing and debugging:
|
|
213
202
|
|
|
214
203
|
<details>
|
|
@@ -238,7 +227,8 @@ export default defineNuxtConfig({
|
|
|
238
227
|
? `"https://yoursite.com"`
|
|
239
228
|
: `undefined`
|
|
240
229
|
},
|
|
241
|
-
// the module will set this to
|
|
230
|
+
// the module will set this to prerender: true
|
|
231
|
+
// you can override it in routeRules and create a spa without prerender if you need
|
|
242
232
|
// additionalRoutes: ["/other-page-prerendered"]
|
|
243
233
|
}
|
|
244
234
|
})
|
|
@@ -292,20 +282,51 @@ And a third parameter pointing to your config if it's not in one of the searched
|
|
|
292
282
|
- `electron-builder.json5`
|
|
293
283
|
- `electron-builder.json`
|
|
294
284
|
|
|
285
|
+
### Usage on Nix
|
|
286
|
+
|
|
287
|
+
As mentioned, the second example script won't work out of the box with nix. You need something like [nix-alien](https://github.com/thiagokokada/nix-alien) if you want to test the electron-builder packaged version (**which you should**, it is packaged completely different than on nix where electron builder is not used).
|
|
288
|
+
|
|
289
|
+
```
|
|
290
|
+
DEBUG=true LOG_LEVEL=trace nix run "github:thiagokokada/nix-alien#nix-alien" -- .dist/electron/release/linux-unpacked/your-app-name
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Apart from that nix has some additional goodies.
|
|
294
|
+
|
|
295
|
+
First there flake with a devenv based shell and direnv support. If you have direnv run `direnv allow .` in the project root. Otherwise run `nix develop`.
|
|
296
|
+
|
|
297
|
+
Nearly everything should work, except the build electron-builder builds. You can do `nix run` instead.
|
|
298
|
+
|
|
299
|
+
The derivation for reference is [here](https://github.com/witchcraftjs/nuxt-electron/blob/master/playground/nix/derivation.nix).
|
|
300
|
+
|
|
301
|
+
There is also a debugging script `debugNixBuild` which drops you in a shell to run the derivation. See it for details. The shell should give you info about all scripts.
|
|
302
|
+
|
|
303
|
+
It uses a set of devenv flake utils I've created (see [here](https://github.com/alanscodelog/nix-devenv-utils)). They contain some good stuff like working support for electron (obviously), android, playwright, etc if you're interested.
|
|
304
|
+
|
|
295
305
|
## Misc Notes
|
|
296
306
|
|
|
297
|
-
Note that while nuxt's path aliases are passed to the electron vite config, you cannot use other nuxt paths (such as those added by modules, e.g. `#somemodule`) in electron. This is why a seperate `@witchcraft/nuxt-electron/electron` export is provided.
|
|
307
|
+
- Note that while nuxt's path aliases are passed to the electron vite config, you cannot use other nuxt paths (such as those added by modules, e.g. `#somemodule`) in electron. This is why a seperate `@witchcraft/nuxt-electron/electron` export is provided.
|
|
308
|
+
- In any electron main code, import.meta.url is always the built main.mjs file regardless of whether you're in dev or prod or what file you're in.
|
|
309
|
+
|
|
310
|
+
## Auth
|
|
311
|
+
|
|
312
|
+
While you might not want to use it (it is very beta) my auth library [@witchcraft/nuxt-auth](https://github.com/witchcraftjs/nuxt-auth) contains a whole section on auth flow on electron. It also contains electron specific code for doing local-first auth which you might find helpful (more code will be added as I figure more things out). It includes support for "semi-authed" local only users and handling "synced" users who can remain "logged in" past authentication expiration so long as they don't perform actions that require auth (e.g. sync).
|
|
313
|
+
|
|
314
|
+
I do not use an existing lib because I have not found any that support complex scenarios like these.
|
|
315
|
+
|
|
316
|
+
This takes a lot of careful consideration and planning to implement like this. I'm still working on some pain points.
|
|
317
|
+
|
|
318
|
+
I mention it because you will need to render your login page as a SPA to get it working. This makes middleware "soft" on that page, just so you're aware. You will also need to proxy auth requests.
|
|
298
319
|
|
|
299
320
|
|
|
300
321
|
## How it Works
|
|
301
322
|
|
|
302
|
-
|
|
323
|
+
### Development
|
|
303
324
|
|
|
304
325
|
Electron is pointed to the localhost server and sees a similar view to the web app except we must client side detect we're on electron and redirect to the `electronRoute`.
|
|
305
326
|
|
|
306
|
-
|
|
327
|
+
### Production
|
|
307
328
|
|
|
308
|
-
Normally nuxt
|
|
329
|
+
Normally nuxt would have had to be configured to output a SPA by setting `ssr: false` and you have to modify baseURL and buildAssetsDir for everything to work (among other changes, see nuxt-electron module for the typical changes).
|
|
309
330
|
|
|
310
331
|
But this module has gone a different route.
|
|
311
332
|
|
|
@@ -313,7 +334,7 @@ First for production only changes, we run the nuxt config with a different env v
|
|
|
313
334
|
|
|
314
335
|
Then we use a custom protocol to proxy requests and api calls.
|
|
315
336
|
|
|
316
|
-
|
|
337
|
+
#### Custom `app://` Handler
|
|
317
338
|
|
|
318
339
|
Electron uses the `file://` protocol by default to load all scripts/assets/etc.
|
|
319
340
|
|
|
@@ -343,13 +364,13 @@ We then need to remove unwanted routes from the bundle which are included regard
|
|
|
343
364
|
|
|
344
365
|
Note we would ideally also remove "/" from the prerender, but this requires manually splitting chunks by pages and I was having issues with this.
|
|
345
366
|
|
|
346
|
-
|
|
367
|
+
##### Why not use a redirect?
|
|
347
368
|
|
|
348
369
|
A `routeRules` redirect won't work, because it will trigger a request to electron's file protocol handler which we don't know what to do with.
|
|
349
370
|
|
|
350
371
|
A redirect from a page (e.i. `if (process.client && isElectron) { await navigateTo("/app") }`) works, but it takes a little big of time to navigate. This is still needed for development redirecting, but not in production.
|
|
351
372
|
|
|
352
|
-
|
|
373
|
+
### Build
|
|
353
374
|
|
|
354
375
|
Building for electron requires lots of changes to the config. We can't just build for web then copy. So this module reroutes the output when building the web app (and reroutes it differently when building for electron (see directory sturcture above).
|
|
355
376
|
|
|
@@ -357,7 +378,7 @@ The reason for the nested `.output` is so it doesn't overwrite the default one.
|
|
|
357
378
|
|
|
358
379
|
To build for electron you must set `process.env.BUILD_ELECTRON` to true, to do the configuration required to make the final output actually work with electron.
|
|
359
380
|
|
|
360
|
-
|
|
381
|
+
#### Electron Build
|
|
361
382
|
|
|
362
383
|
The electron app itself is "built" in two parts, the "build" and the "packing".
|
|
363
384
|
|
|
@@ -371,6 +392,13 @@ Note that nuxt builds the server anyways, it's just not packed into the final ap
|
|
|
371
392
|
|
|
372
393
|
Your packer should then create the final executables (into `.dist/electron/release`).
|
|
373
394
|
|
|
395
|
+
### Debugging Tips
|
|
396
|
+
|
|
397
|
+
- To inspect the asar, run `npx @electron/asar list .dist/electron/release/linux-unpacked/resources/app.asar`.
|
|
398
|
+
- If routes aren't rendering:
|
|
399
|
+
- Check the final config in the ready hook. Other modules might be causing issues.
|
|
400
|
+
- Check your structure is correct (`pages/page.vue` with NuxtPage, `pages/page/index.vue`).
|
|
401
|
+
|
|
374
402
|
|
|
375
403
|
<!-- Badges -->
|
|
376
404
|
[npm-version-src]: https://img.shields.io/npm/v/@witchcraft/nuxt-electron/latest.svg?style=flat&colorA=020420&colorB=00DC82
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -331,13 +331,17 @@ const module$1 = defineNuxtModule({
|
|
|
331
331
|
nuxtRemoveUneededPages(nuxt, ["/", electronRoute, ...options.additionalRoutes]);
|
|
332
332
|
nuxt.options.router.options ??= {};
|
|
333
333
|
nuxt.options.router.options.hashMode = false;
|
|
334
|
+
extendRouteRules(electronRoute + "/", {
|
|
335
|
+
prerender: true
|
|
336
|
+
}, { override: true });
|
|
334
337
|
extendRouteRules(electronRoute + "/**", {
|
|
335
338
|
prerender: true
|
|
336
339
|
}, { override: true });
|
|
337
340
|
for (const route of options.additionalRoutes) {
|
|
338
341
|
extendRouteRules(route, {
|
|
339
342
|
prerender: true
|
|
340
|
-
|
|
343
|
+
// allow user to set something else and use a spa
|
|
344
|
+
}, { override: false });
|
|
341
345
|
}
|
|
342
346
|
nuxt.hook("prerender:routes", ({ routes }) => {
|
|
343
347
|
for (const route of ["/404.html"]) {
|
|
@@ -32,7 +32,7 @@ export function getPaths(protocolName = "app", overridingEnvs = {
|
|
|
32
32
|
return {
|
|
33
33
|
...base,
|
|
34
34
|
// careful, do not use path.join, it will remove extra slashes
|
|
35
|
-
windowUrl: `${protocolName}://bundle
|
|
35
|
+
windowUrl: `${protocolName}://bundle${STATIC.ELECTRON_PROD_URL}`
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
unreachable();
|
package/package.json
CHANGED
package/src/module.ts
CHANGED
|
@@ -521,6 +521,11 @@ export default defineNuxtModule<ModuleOptions>({
|
|
|
521
521
|
nuxt.options.router.options ??= {}
|
|
522
522
|
nuxt.options.router.options.hashMode = false
|
|
523
523
|
|
|
524
|
+
// its not a smart merge or anything, so we need to override both possibilities
|
|
525
|
+
extendRouteRules(electronRoute + "/", {
|
|
526
|
+
prerender: true
|
|
527
|
+
}, { override: true })
|
|
528
|
+
|
|
524
529
|
extendRouteRules(electronRoute + "/**", {
|
|
525
530
|
prerender: true
|
|
526
531
|
}, { override: true })
|
|
@@ -528,7 +533,8 @@ export default defineNuxtModule<ModuleOptions>({
|
|
|
528
533
|
for (const route of options.additionalRoutes) {
|
|
529
534
|
extendRouteRules(route, {
|
|
530
535
|
prerender: true
|
|
531
|
-
|
|
536
|
+
// allow user to set something else and use a spa
|
|
537
|
+
}, { override: false })
|
|
532
538
|
}
|
|
533
539
|
|
|
534
540
|
|
|
@@ -66,7 +66,7 @@ export function getPaths(
|
|
|
66
66
|
return {
|
|
67
67
|
...base,
|
|
68
68
|
// careful, do not use path.join, it will remove extra slashes
|
|
69
|
-
windowUrl: `${protocolName}://bundle
|
|
69
|
+
windowUrl: `${protocolName}://bundle${STATIC.ELECTRON_PROD_URL}`
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
unreachable()
|