🔌 Sincronização de Caminhos de Plugins
Os plugins do NewWhats são compilados junto com o sistema central e carregados dinamicamente na VPS 1 de produção.
1. O Desafio dos Caminhos Relativos
Durante o desenvolvimento local, os plugins residem na pasta /plugins/<nome-do-plugin>/ e dependem de caminhos relativos para importar módulos do núcleo do backend, ex:
import { PluginContext } from '../../backend/src/core/types'
No entanto, no container Docker de produção na VPS 1:
- O backend compilado está localizado em
/app/dist/. - A pasta
/app/backend/src/não existe no container. - Isso fazia com que os plugins compilados quebrassem no boot do servidor com o erro:
Error: Cannot find module '../../backend/src/...
2. A Solução Dinâmica e Compatível
Desenvolvemos uma estratégia elegante e resiliente para resolver as importações tanto em desenvolvimento quanto em produção:
A) Distinção entre Tipos e Códigos de Runtime
- No TypeScript, todas as importações que apenas utilizam tipos (como
import type { PluginContext }) são inteiramente eliminadas pelo compilador durante a geração do Javascript final. Portanto, essas importações podem continuar utilizando os caminhos normais de desenvolvimento. - Para códigos executáveis (como helpers, caches, providers), implementamos a resolução dinâmica baseada na variável de ambiente
NODE_ENV.
B) Exemplo de Implementação de Require Dinâmico
Para o plugin de armazenamento (UnifiedStorageProvider), a importação do storageProvider foi atualizada da seguinte forma:
let storageProvider: any;
if (process.env.NODE_ENV === 'production') {
storageProvider = require('../../dist/core/StorageProvider').storageProvider;
} else {
storageProvider = require('../../backend/src/core/StorageProvider').storageProvider;
}
O mesmo padrão foi aplicado com sucesso em:
- nanobana: Utilizando o
PluginContextpara recuperar chaves de configuração dinamicamente e eliminando imports estáticos. - leads: Atualizando a importação de middlewares centrais de autenticação (
autherbac). - ext-api: Atualizando a resolução das dependências
dragonflyesendRichMessageapontando para o subdiretóriodistem produção.
3. Automação de Compilação
Configuramos o arquivo tsconfig.json de plugins mapeando os caminhos de dependências externas para o node_modules do backend:
"paths": {
"*": ["../backend/node_modules/*"]
}
O script deploy-prod-builder.sh agora compila automaticamente todos os plugins em lotes utilizando o compilador TS local e realiza o sincronismo dos arquivos Javascript finais (.js e .js.map) para o diretório /app/plugins do container Docker, carregando todos os 8 plugins ativos de forma limpa e transparente!