vite.config.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import path from 'node:path';
  2. import { YJS_WEBSOCKET_BASE_PATH } from '@growi/core/dist/consts';
  3. import react from '@vitejs/plugin-react';
  4. import glob from 'glob';
  5. import { nodeExternals } from 'rollup-plugin-node-externals';
  6. import type { Plugin } from 'vite';
  7. import { defineConfig } from 'vite';
  8. import dts from 'vite-plugin-dts';
  9. const YJS_PATH_PREFIX = `${YJS_WEBSOCKET_BASE_PATH}/`;
  10. const excludeFiles = [
  11. '**/components/playground/*',
  12. '**/main.tsx',
  13. '**/vite-env.d.ts',
  14. ];
  15. const devWebSocketPlugin = (): Plugin => ({
  16. name: 'dev-y-websocket',
  17. apply: 'serve',
  18. configureServer(server) {
  19. if (!server.httpServer) return;
  20. // eslint-disable-next-line @typescript-eslint/no-require-imports
  21. const { setupWSConnection } = require('y-websocket/bin/utils');
  22. // eslint-disable-next-line @typescript-eslint/no-require-imports
  23. const { WebSocketServer } = require('ws');
  24. const wss = new WebSocketServer({ noServer: true });
  25. server.httpServer.on('upgrade', (request, socket, head) => {
  26. const url = request.url ?? '';
  27. if (!url.startsWith(YJS_PATH_PREFIX)) return;
  28. const pageId = url.slice(YJS_PATH_PREFIX.length).split('?')[0];
  29. wss.handleUpgrade(request, socket, head, (ws) => {
  30. wss.emit('connection', ws, request);
  31. setupWSConnection(ws, request, { docName: pageId });
  32. });
  33. });
  34. },
  35. });
  36. // https://vitejs.dev/config/
  37. export default defineConfig({
  38. plugins: [
  39. react(),
  40. devWebSocketPlugin(),
  41. dts({
  42. entryRoot: 'src',
  43. exclude: [...excludeFiles],
  44. copyDtsFiles: true,
  45. // Fix TS2345/TS2719 "Two different types with this name exist" errors
  46. // during declaration file generation.
  47. //
  48. // vite-plugin-dts internally creates its own TypeScript program, which
  49. // resolves @codemirror/state and @codemirror/view through different pnpm
  50. // symlink chains depending on whether the import originates from
  51. // @growi/editor source or from @uiw/react-codemirror's re-exports.
  52. // Although both chains point to the same physical package, TypeScript
  53. // treats them as distinct types because private fields (e.g.
  54. // SelectionRange#flags) create nominal type identity per declaration.
  55. //
  56. // Pinning paths here forces vite-plugin-dts to resolve these packages
  57. // to a single location regardless of the import origin.
  58. compilerOptions: {
  59. paths: {
  60. '@codemirror/state': [
  61. path.resolve(__dirname, 'node_modules/@codemirror/state'),
  62. ],
  63. '@codemirror/view': [
  64. path.resolve(__dirname, 'node_modules/@codemirror/view'),
  65. ],
  66. },
  67. },
  68. }),
  69. {
  70. ...nodeExternals({
  71. devDeps: true,
  72. builtinsPrefix: 'ignore',
  73. }),
  74. enforce: 'pre',
  75. },
  76. ],
  77. build: {
  78. outDir: 'dist',
  79. sourcemap: true,
  80. lib: {
  81. entry: glob.sync(path.resolve(__dirname, 'src/**/*.{ts,tsx}'), {
  82. ignore: [...excludeFiles, '**/*.spec.ts'],
  83. }),
  84. name: 'editor-libs',
  85. cssFileName: 'style',
  86. formats: ['es'],
  87. },
  88. rollupOptions: {
  89. output: {
  90. preserveModules: true,
  91. preserveModulesRoot: 'src',
  92. },
  93. },
  94. },
  95. });