watch.ts 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import { AdminUiExtension } from '@vendure/common/lib/shared-types';
  2. import { spawn } from 'child_process';
  3. import { FSWatcher, watch } from 'chokidar';
  4. import * as fs from 'fs-extra';
  5. import * as path from 'path';
  6. import {
  7. copyExtensionModules,
  8. createExtensionsModule,
  9. deleteExistingExtensionModules,
  10. getModuleOutputDir,
  11. isInVendureMonorepo,
  12. restoreExtensionsModule,
  13. restoreOriginalExtensionsModule,
  14. } from './common';
  15. export type Watcher = {
  16. close: () => void;
  17. };
  18. /**
  19. * Starts the admin ui app in watch mode using the Angular CLI `ng serve` command. Also watches
  20. * the individual files of any configured extensions and copies them upon change, triggering a
  21. * rebuild of the Angular app.
  22. */
  23. export function watchAdminUiApp(extensions: Array<Required<AdminUiExtension>>, port: number): Watcher {
  24. const cwd = path.join(__dirname, '..');
  25. restoreExtensionsModule();
  26. deleteExistingExtensionModules();
  27. copyExtensionModules(extensions);
  28. createExtensionsModule(extensions);
  29. const config = isInVendureMonorepo() ? 'plugin-dev' : 'plugin';
  30. const buildProcess = spawn('yarn', ['ng', 'serve', `-c=${config}`, `--port=${port}`], {
  31. cwd,
  32. shell: true,
  33. stdio: 'inherit',
  34. });
  35. let watcher: FSWatcher | undefined;
  36. for (const extension of extensions) {
  37. if (!watcher) {
  38. watcher = watch(extension.ngModulePath, {
  39. depth: 4,
  40. ignored: '**/node_modules/',
  41. });
  42. } else {
  43. watcher.add(extension.ngModulePath);
  44. }
  45. }
  46. if (watcher) {
  47. watcher.on('change', filePath => {
  48. const extension = extensions.find(e => filePath.includes(e.ngModulePath));
  49. if (extension) {
  50. const outputDir = getModuleOutputDir(extension);
  51. const filePart = path.relative(extension.ngModulePath, filePath);
  52. const dest = path.join(outputDir, filePart);
  53. fs.copyFile(filePath, dest);
  54. }
  55. });
  56. }
  57. const close = () => {
  58. if (watcher) {
  59. watcher.close();
  60. }
  61. buildProcess.kill();
  62. restoreOriginalExtensionsModule();
  63. };
  64. process.on('SIGINT', close);
  65. return { close };
  66. }