-
-
Notifications
You must be signed in to change notification settings - Fork 631
feat(plugin-vite): hot-restart 🔥 #3203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c09aa2a
474d2f0
e358075
440bec6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,7 @@ | ||
| import { builtinModules } from 'node:module'; | ||
|
|
||
| import type { VitePluginBuildConfig } from '../Config'; | ||
| import type { RendererConfigWithServer } from '../VitePlugin'; | ||
| import type { Plugin } from 'vite'; | ||
|
|
||
| /** | ||
|
|
@@ -33,3 +35,48 @@ export function externalBuiltins() { | |
| }, | ||
| }; | ||
| } | ||
|
|
||
| /** | ||
| * Hot restart App during development for better DX. | ||
| */ | ||
| export function hotRestart( | ||
| config: VitePluginBuildConfig, | ||
| // For `VitePluginBuildConfig['restart']` callback args. | ||
| context: { renderers: RendererConfigWithServer[] } | ||
| ) { | ||
| const restart = () => { | ||
|
erickzhao marked this conversation as resolved.
|
||
| // https://github.com/electron/forge/blob/v6.1.1/packages/api/core/src/api/start.ts#L204-L211 | ||
| process.stdin.emit('data', 'rs'); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @MarshallOfSound pointed out to me that using Ideally, we should instead expose additional start logic from the
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay! This does seem a little dangerous. 🚨 |
||
| }; | ||
| // Avoid first start, it's stated by forge. | ||
| let isFirstStart: undefined | true; | ||
|
|
||
| return <Plugin>{ | ||
| name: '@electron-forge/plugin-vite:hot-restart', | ||
| closeBundle() { | ||
| if (isFirstStart == null) { | ||
| isFirstStart = true; | ||
| return; | ||
| } | ||
| if (config.restart === false) { | ||
| return; | ||
| } | ||
| if (typeof config.restart === 'function') { | ||
| // Leave it to the user to decide whether to restart. | ||
| config.restart({ | ||
| restart, | ||
| renderer: context.renderers.map((renderer) => ({ | ||
| // 🎯-②: | ||
| // Users can decide which Renderer process to refresh according to `config`. | ||
| config: renderer.config, | ||
| reload() { | ||
| renderer.server.ws.send({ type: 'full-reload' }); | ||
| }, | ||
| })), | ||
| }); | ||
| } else { | ||
| restart(); | ||
| } | ||
| }, | ||
| }; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,20 +15,23 @@ describe('ViteConfigGenerator', () => { | |
| const generator = new ViteConfigGenerator(config, '', false); | ||
| const servers: ViteDevServer[] = []; | ||
|
|
||
| for (const userConfig of await generator.getRendererConfig()) { | ||
| for (const { vite: viteConfig } of await generator.getRendererConfig()) { | ||
| const viteDevServer = await vite.createServer({ | ||
| configFile: false, | ||
| ...userConfig, | ||
| optimizeDeps: { | ||
| disabled: true, | ||
| }, | ||
| ...viteConfig, | ||
| }); | ||
|
|
||
| await viteDevServer.listen(); | ||
| viteDevServer.printUrls(); | ||
| // viteDevServer.printUrls(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question: is this commented out intentionally?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep! When I run test on my local machine, some verbose log print, so commented it.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we remove this before we ship it to users then?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The logs removed here are only for the CI test environment and will not affect the production environment.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
No. If others need it, they can add it themselves. |
||
| servers.push(viteDevServer); | ||
|
|
||
| // Make suee that `getDefines` in VitePlugin.ts gets the correct `server.port`. (#3198) | ||
| const addressInfo = viteDevServer.httpServer!.address() as AddressInfo; | ||
| userConfig.server ??= {}; | ||
| userConfig.server.port = addressInfo.port; | ||
| viteConfig.server ??= {}; | ||
| viteConfig.server.port = addressInfo.port; | ||
| } | ||
|
|
||
| const define = await generator.getDefines(); | ||
|
|
@@ -50,15 +53,15 @@ describe('ViteConfigGenerator', () => { | |
| renderer: [], | ||
| } as VitePluginConfig; | ||
| const generator = new ViteConfigGenerator(config, '', true); | ||
| const buildConfig = (await generator.getBuildConfig())[0]; | ||
| expect(buildConfig).deep.equal({ | ||
| const { vite: viteConfig } = (await generator.getBuildConfig())[0]; | ||
| expect(viteConfig).deep.equal({ | ||
| mode: 'production', | ||
| build: { | ||
| lib: { | ||
| entry: 'foo.js', | ||
| formats: ['cjs'], | ||
| // shims | ||
| fileName: (buildConfig.build?.lib as any)?.fileName, | ||
| fileName: (viteConfig.build?.lib as any)?.fileName, | ||
| }, | ||
| emptyOutDir: false, | ||
| outDir: path.join('.vite', 'build'), | ||
|
|
@@ -67,7 +70,7 @@ describe('ViteConfigGenerator', () => { | |
| clearScreen: false, | ||
| define: {}, | ||
| // shims | ||
| plugins: [buildConfig.plugins?.[0]], | ||
| plugins: viteConfig.plugins, | ||
| } as UserConfig); | ||
| }); | ||
|
|
||
|
|
@@ -77,8 +80,8 @@ describe('ViteConfigGenerator', () => { | |
| } as VitePluginConfig; | ||
| const generator = new ViteConfigGenerator(config, '', false); | ||
| const configs = await generator.getRendererConfig(); | ||
| for (const [index, rendererConfig] of configs.entries()) { | ||
| expect(rendererConfig).deep.equal({ | ||
| for (const [index, { vite: viteConfig }] of configs.entries()) { | ||
| expect(viteConfig).deep.equal({ | ||
| mode: 'development', | ||
| base: './', | ||
| build: { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export default function booststrap() { | ||
| console.log('App bootstrap.'); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be
rendererssince it's a list of all renderer processes?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about this API design? 🤔
It looks little simper.
Usage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think @erickzhao means that because this is an array, it would be better to use plural for words.