Análise Profunda da Arquitetura Frontend do Chat2DB: React + TypeScript + Umi

O Chat2DB é uma ferramenta moderna de gerenciamento de banco de dados cuja interface frontend foi construída com uma pilha tecnológica robusta e atualizada. Este artigo explora em detalhes as escolhas arquiteturais, configurações de ferramentas, otimizações de produção e integrações chave que fazem do Chat2DB um exemplo de engenharia frontend corporativa.

Stack Tecnológico e Configuração

A combinação React + TypeScript + Umi.js foi escolhida por fornecer maturidade, segurança de tipos e produtividade. O Umi 4.0 atua como framework com roteamento, plugins e build otimizado.

// .umirc.ts
export default defineConfig({
  title: 'Chat2DB',
  base: '/',
  publicPath: '/',
  hash: true,
  routes: [
    { path: '/', component: '@/layouts/GlobalLayout', routes: [
      { path: '/login', component: '@/pages/login' },
      { path: '/connections', component: 'main' },
      { path: '/dashboard', component: 'main' },
      { path: '/workspace', component: 'main' },
    ]}
  ],
  npmClient: 'yarn',
  plugins: ['@umijs/plugins/dist/dva'],
  chainWebpack(config) {
    config.plugin('monaco-editor').use(MonacoWebpackPlugin, [{
      languages: ['mysql', 'pgsql', 'sql'],
    }]);
  },
  proxy: {
    '/api': { target: 'http://127.0.0.1:10821', changeOrigin: true },
  },
});

Gerenciamento de Estado com Zustand

A equipe optou pelo Zustand como solução leve e tipada para estado globall, combinando com ahooks para hooks reutilizáveis. Cada domínio (usuário, conexão, editor) possui sua própria store.

import { createWithEqualityFn } from 'zustand/traditional';
import { devtools, persist } from 'zustand/middleware';

interface IConnectionStore {
  connections: IConnection[];
  currentConnection?: IConnection;
  addConnection: (conn: IConnection) => void;
  removeConnection: (id: string) => void;
}

export const useConnectionStore = createWithEqualityFn(
  devtools((set) => ({
    connections: [],
    currentConnection: undefined,
    addConnection: (conn) => set((s) => ({ connections: [...s.connections, conn] })),
    removeConnection: (id) => set((s) => ({ connections: s.connections.filter(c => c.id !== id) })),
  })),
  Object.is
);

A persistência é feita via localStorage para preferências de usuário, enquanto dados críticos são mantidos apenas em memória.

Editor SQL com Monaco Editor

O componente MonacoEditor encapsula toda a lógica de edição, suportando múltiplos bancos de dados (MySQL, PostgreSQL, Oracle, SQL Server). A configuração padrão é extensível via prop options.

export const defaultEditorOptions: IEditorOptions = {
  fontFamily: '"Menlo", "Consolas", monospace',
  scrollBeyondLastLine: false,
  automaticLayout: true,
  fontSize: 12,
  tabSize: 2,
  lineHeight: 18,
  theme: 'vscode',
  readOnly: false,
  wordWrap: 'on',
  minimap: { enabled: false },
};

Funções como inserção de texto em diferentes posições (início, fim, substituir) são implementadas com executeEdits e um seletor de intervalo:

function insertText(editor: monaco.editor.IStandaloneCodeEditor, text: string, mode: 'end' | 'front' | 'cursor') {
  const model = editor.getModel();
  if (!model) return;
  let range: monaco.Range;
  if (mode === 'front') {
    range = new monaco.Range(1, 1, 1, 1);
  } else if (mode === 'cursor') {
    const pos = editor.getPosition();
    range = new monaco.Range(pos.lineNumber, pos.column, pos.lineNumber, pos.column);
  } else {
    const lastLine = model.getLineCount();
    const lastCol = model.getLineMaxColumn(lastLine);
    range = new monaco.Range(lastLine, lastCol, lastLine, lastCol);
  }
  editor.executeEdits('insert', [{ range, text, forceMoveMarkers: true }]);
}

Internacionalização e Temas

O suporte a múltiplos idiomas (inglês, chinês, japonês, turco) é gerenciado por arquivos de tradução em src/i18n. O tema do editor também é customizado dinamicamente com defineTheme:

monaco.editor.defineTheme('dashboardLight', {
  base: 'vs',
  inherit: true,
  rules: [],
  colors: {
    'editor.foreground': '#000000',
    'editor.background': '#f8f9fa',
  },
});

Integração Desktop com Electron

Para a versão desktop, o Chat2DB utiliza Electron 22 e electron-builder. As rotas e o build são adaptados via variáveis de ambiente:

// package.json (trecho)
"electron": "^22.3.0",
"electron-builder": "^23.6.0",
"scripts": {
  "build:desktop": "cross-env BUILD_TARGET=electron umi build",
  "start:desktop": "electron ."
}

O proxy de desenvolvimento redireciona chamadas de API para o backend local, facilitando o desenvolvimento simultâneo.

Otimizações de Performance

  • Code splitting via lazy loading dos componentes pesados (ex: MonacoEditor).
  • Memoização com React.memo e useMemo para evitar re-renderizações desnecessárias.
  • Shallow comparison no Zustand para evitar disparos de estado irrelevantes.
  • Minificação com esbuild e hash nos arquivos para cache eficiente.

Essa arquitetura modular, com separação clara entre componantes de apresentação, lógica de negócio e estado global, permite ao Chat2DB evoluir com segurança e manter alta performance mesmo em bases de dados complexas.

Tags: React TypeScript Umi Zustand Monaco Editor

Publicado em 6-14 00:31 por Thomas