nitro-mock.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import type { PluginOption } from 'vite';
  2. import type { NitroMockPluginOptions } from '../typing';
  3. import { colors, consola, getPackage } from '@vben/node-utils';
  4. import getPort from 'get-port';
  5. import { build, createDevServer, createNitro, prepare } from 'nitropack';
  6. const hmrKeyRe = /^runtimeConfig\.|routeRules\./;
  7. export const viteNitroMockPlugin = ({
  8. mockServerPackage = '@vben/backend-mock',
  9. port = 5320,
  10. verbose = true,
  11. }: NitroMockPluginOptions = {}): PluginOption => {
  12. return {
  13. async configureServer(server) {
  14. const availablePort = await getPort({ port });
  15. if (availablePort !== port) {
  16. return;
  17. }
  18. const pkg = await getPackage(mockServerPackage);
  19. if (!pkg) {
  20. consola.log(
  21. `Package ${mockServerPackage} not found. Skip mock server.`,
  22. );
  23. return;
  24. }
  25. runNitroServer(pkg.dir, port, verbose);
  26. const _printUrls = server.printUrls;
  27. server.printUrls = () => {
  28. _printUrls();
  29. consola.log(
  30. ` ${colors.green('➜')} ${colors.bold('Nitro Mock Server')}: ${colors.cyan(`http://localhost:${port}/api`)}`,
  31. );
  32. };
  33. },
  34. enforce: 'pre',
  35. name: 'vite:mock-server',
  36. };
  37. };
  38. async function runNitroServer(rootDir: string, port: number, verbose: boolean) {
  39. let nitro: any;
  40. const reload = async () => {
  41. if (nitro) {
  42. consola.info('Restarting dev server...');
  43. if ('unwatch' in nitro.options._c12) {
  44. await nitro.options._c12.unwatch();
  45. }
  46. await nitro.close();
  47. }
  48. nitro = await createNitro(
  49. {
  50. dev: true,
  51. preset: 'nitro-dev',
  52. rootDir,
  53. },
  54. {
  55. c12: {
  56. async onUpdate({ getDiff, newConfig }) {
  57. const diff = getDiff();
  58. if (diff.length === 0) {
  59. return;
  60. }
  61. verbose &&
  62. consola.info(
  63. `Nitro config updated:\n${diff
  64. .map((entry) => ` ${entry.toString()}`)
  65. .join('\n')}`,
  66. );
  67. await (diff.every((e) => hmrKeyRe.test(e.key))
  68. ? nitro.updateConfig(newConfig.config)
  69. : reload());
  70. },
  71. },
  72. watch: true,
  73. },
  74. );
  75. nitro.hooks.hookOnce('restart', reload);
  76. const server = createDevServer(nitro);
  77. await server.listen(port, { showURL: false });
  78. await prepare(nitro);
  79. await build(nitro);
  80. if (verbose) {
  81. console.log('');
  82. consola.success(colors.bold(colors.green('Nitro Mock Server started.')));
  83. }
  84. };
  85. return await reload();
  86. }