watch.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #!/usr/bin/env node
  2. const {createServer, build, createLogger} = require('vite');
  3. const electronPath = require('electron');
  4. const {spawn} = require('child_process');
  5. /** @type 'production' | 'development'' */
  6. const mode = process.env.MODE = process.env.MODE || 'development';
  7. /** @type {import('vite').LogLevel} */
  8. const logLevel = 'info';
  9. /** Messages on stderr that match any of the contained patterns will be stripped from output */
  10. const stderrFilterPatterns = [
  11. /**
  12. * warning about devtools extension
  13. * @see https://github.com/cawa-93/vite-electron-builder/issues/492
  14. * @see https://github.com/MarshallOfSound/electron-devtools-installer/issues/143
  15. */
  16. /ExtensionLoadWarning/,
  17. ];
  18. /**
  19. * Setup watcher for `main` package
  20. * On file changed it totally re-launch electron app.
  21. * @param {import('vite').ViteDevServer} watchServer Renderer watch server instance.
  22. * Needs to set up `VITE_DEV_SERVER_URL` environment variable from {@link import('vite').ViteDevServer.resolvedUrls}
  23. */
  24. const setupMainPackageWatcher = ({resolvedUrls}) => {
  25. process.env.VITE_DEV_SERVER_URL = resolvedUrls.local[0];
  26. const logger = createLogger(logLevel, {
  27. prefix: '[main]',
  28. });
  29. /** @type {ChildProcessWithoutNullStreams | null} */
  30. let spawnProcess = null;
  31. return build({
  32. mode,
  33. logLevel,
  34. build: {
  35. /**
  36. * Set to {} to enable rollup watcher
  37. * @see https://vitejs.dev/config/build-options.html#build-watch
  38. */
  39. watch: {},
  40. },
  41. configFile: 'packages/main/vite.config.js',
  42. plugins: [{
  43. name: 'reload-app-on-main-package-change',
  44. writeBundle() {
  45. /** Kill electron ff process already exist */
  46. if (spawnProcess !== null) {
  47. spawnProcess.off('exit', process.exit);
  48. spawnProcess.kill('SIGINT');
  49. spawnProcess = null;
  50. }
  51. /** Spawn new electron process */
  52. spawnProcess = spawn(String(electronPath), ['.']);
  53. /** Proxy all logs */
  54. spawnProcess.stdout.on('data', d => d.toString().trim() && logger.warn(d.toString(), {timestamp: true}));
  55. /** Proxy error logs but stripe some noisy messages. See {@link stderrFilterPatterns} */
  56. spawnProcess.stderr.on('data', d => {
  57. const data = d.toString().trim();
  58. if (!data) return;
  59. const mayIgnore = stderrFilterPatterns.some((r) => r.test(data));
  60. if (mayIgnore) return;
  61. logger.error(data, {timestamp: true});
  62. });
  63. /** Stops the watch script when the application has been quit */
  64. spawnProcess.on('exit', process.exit);
  65. },
  66. }],
  67. });
  68. };
  69. /**
  70. * Setup watcher for `preload` package
  71. * On file changed it reload web page.
  72. * @param {import('vite').ViteDevServer} watchServer Renderer watch server instance.
  73. * Required to access the web socket of the page. By sending the `full-reload` command to the socket, it reloads the web page.
  74. */
  75. const setupPreloadPackageWatcher = ({ws}) =>
  76. build({
  77. mode,
  78. logLevel,
  79. build: {
  80. /**
  81. * Set to {} to enable rollup watcher
  82. * @see https://vitejs.dev/config/build-options.html#build-watch
  83. */
  84. watch: {},
  85. },
  86. configFile: 'packages/preload/vite.config.js',
  87. plugins: [{
  88. name: 'reload-page-on-preload-package-change',
  89. writeBundle() {
  90. ws.send({
  91. type: 'full-reload',
  92. });
  93. },
  94. }],
  95. });
  96. (async () => {
  97. try {
  98. /**
  99. * Renderer watcher
  100. * This must be the first,
  101. * because the {@link setupMainPackageWatcher} and {@link setupPreloadPackageWatcher} depend on the renderer params
  102. */
  103. const rendererWatchServer = await createServer({
  104. mode,
  105. logLevel,
  106. configFile: 'packages/renderer/vite.config.js',
  107. });
  108. /**
  109. * Should launch watch server before create other watchers
  110. */
  111. await rendererWatchServer.listen();
  112. /**
  113. * See {@link setupPreloadPackageWatcher} JSDoc
  114. */
  115. await setupPreloadPackageWatcher(rendererWatchServer);
  116. /**
  117. * See {@link setupMainPackageWatcher} JSDoc
  118. */
  119. await setupMainPackageWatcher(rendererWatchServer);
  120. } catch (e) {
  121. console.error(e);
  122. process.exit(1);
  123. }
  124. })();