FAQ y guía de resolución de problemas
Aquí hemos recopilado los problemas más habituales al desarrollar plugins de cliente. Si se topa con un caso de "lo escribí bien pero no funciona", busque primero por aquí.
Sobre el plugin
Tras crear el plugin no aparece en el gestor
Compruebe que ejecutó yarn pm create en lugar de crear el directorio a mano. yarn pm create, además de generar archivos, registra el plugin en la tabla applicationPlugins de la base de datos. Si creó el directorio manualmente, ejecute yarn nocobase upgrade para que se vuelva a escanear.
Tras activar el plugin la página no cambia
Verifique en este orden:
- Que ejecutó
yarn pm enable <pluginName>. - Refresque el navegador (a veces hace falta forzar el refresco con
Ctrl+Shift+R). - Compruebe la consola del navegador en busca de errores.
Tras modificar el código la página no se actualiza
El comportamiento del hot reload depende del tipo de archivo:
Si modificó código del cliente y no se aplicó, primero pruebe a refrescar el navegador.
Sobre las rutas
No se accede a la ruta de página registrada
Las rutas de NocoBase v2 incluyen por defecto el prefijo /v. Por ejemplo, si registra path: '/hello', la URL real es /v/hello:
Para más detalles, consulte Router.
La página de configuración aparece en blanco al entrar
Si el menú de la configuración aparece pero el contenido está vacío, suele ser por uno de estos motivos:
Motivo 1: en client v1 se usó componentLoader
componentLoader es la forma de client-v2; en client v1 hay que usar Component y pasar el componente directamente:
Motivo 2: el componente de la página no tiene export default
componentLoader requiere que el módulo tenga export por defecto; sin default no se carga.
Sobre los bloques
Mi bloque personalizado no aparece en "Añadir bloque"
Compruebe que registró el modelo en load():
Si utiliza registerModels (sin carga bajo demanda), asegúrese de que models/index.ts exporta correctamente el modelo.
Tras añadir el bloque, mi tabla no está en la lista de Collections
Las tablas definidas con defineCollection son tablas internas del servidor y, por defecto, no aparecen en la lista de Collections de la UI.
Recomendación: añada la tabla correspondiente desde la "Gestión de fuentes de datos" en la interfaz de NocoBase. Tras configurar los campos y los tipos de interface, la tabla aparecerá automáticamente en la lista de Collections del bloque.
Si realmente necesita registrarla desde el código del plugin (por ejemplo, en un escenario de demostración), puede usar addCollection. Consulte Crear un plugin de gestión de datos full-stack. Atención: hay que registrarla a través del patrón eventBus, no llamando directamente desde load(), ya que ensureLoaded() se ejecuta después de load() y limpia y vuelve a fijar todas las Collections.
Quiero que mi bloque personalizado solo se enlace a una tabla concreta
Sobrescriba static filterCollection en el modelo; solo aparecerán en la lista las Collections que devuelvan true:
Sobre los campos
Mi componente de campo personalizado no aparece en el desplegable "Componente de campo"
Verifique en este orden:
- Que llamó a
DisplayItemModel.bindModelToInterface('ModelName', ['input'])y que el tipo de interface coincide:inputpara texto de una sola línea,checkboxpara casillas de verificación, etc. - Que el modelo está registrado en
load()(conregisterModelsoregisterModelLoaders). - Que el modelo de campo llamó a
define({ label }).
El desplegable "Componente de campo" muestra el nombre de la clase
Olvidó llamar a define({ label }) en el modelo de campo. Añádalo:
Asegúrese también de que existen las claves correspondientes en los archivos de src/locale/; si no, en entornos en chino seguirá viéndose el original en inglés.
Sobre las acciones
Mi botón de acción personalizado no aparece en "Configurar acciones"
Compruebe que el modelo tiene el static scene correcto:
El botón de acción no responde al clic
Compruebe que registerFlow tiene on configurado como 'click':
El uiSchema dentro de registerFlow corresponde a la UI del panel de configuración (modo configuración), no a un diálogo en tiempo de ejecución. Si quiere abrir un formulario al pulsar el botón, debe abrirlo desde el handler con ctx.viewer.dialog().
Sobre la internacionalización
Las traducciones no se aplican
Causas más comunes:
- La primera vez que añade el directorio o un archivo en
src/locale/: hay que reiniciar la aplicación. - La clave de traducción no coincide: compruebe que la clave es idéntica a la cadena del código, atendiendo a espacios y mayúsculas.
- En el componente se usó
ctx.t()directamente:ctx.t()no inyecta automáticamente el namespace del plugin; en los componentes use el hookuseT()(importado delocale.ts).
Confundir los escenarios de tExpr(), useT() y this.t()
Los tres métodos se usan en escenarios distintos; usar uno por otro provoca errores o que la traducción no se aplique:
Para más detalles, consulte Internacionalización (i18n).
Sobre las peticiones API
La petición devuelve 403 Forbidden
Suele faltar la configuración ACL en el servidor. Por ejemplo, si su Collection se llama todoItems, en el load() del plugin de servidor debe permitir las acciones correspondientes:
'loggedIn' indica que basta con estar autenticado. Si no se configura acl.allow, por defecto solo los administradores pueden operar.
La petición devuelve 404 Not Found
Verifique en este orden:
- Si usa
defineCollection, compruebe que el nombre de la Collection está bien escrito. - Si usa
resourceManager.define, compruebe los nombres del resource y de la action. - Compruebe el formato de la URL: el formato de la API de NocoBase es
resourceName:actionName, por ejemplotodoItems:list,externalApi:get.
Sobre el build y el despliegue
yarn build --tar falla con "no paths specified to add to archive"
Al ejecutar yarn build <pluginName> --tar aparece:
Pero yarn build <pluginName> (sin --tar) funciona. Esto suele deberse a que el .npmignore del plugin utiliza la sintaxis de negación (prefijo ! de npm). Al hacer el --tar, NocoBase lee cada línea de .npmignore y le añade un ! delante para convertirla en un patrón de exclusión de fast-glob. Si su .npmignore ya usa negaciones, por ejemplo:
tras procesarlo se convierte en ['!*', '!!dist', '!!package.json', '**/*']. !* excluye todos los archivos del nivel raíz (incluido package.json), y !!dist no se interpreta como "volver a incluir dist", la negación pierde efecto. Si dist/ está vacío o el build no produce archivos, la lista final queda vacía y tar lanza este error.
Solución: no use sintaxis de negación en .npmignore. Liste solo los directorios que quiere excluir:
La lógica del empaquetado los convierte en patrones de exclusión (!./node_modules, !./src) y añade **/* para incluir todo lo demás. Es una forma sencilla y libre de los problemas de negación.
El plugin se sube a producción y falla al activarlo (en local funciona)
El plugin funciona perfectamente en local pero, tras subirlo a producción mediante el "Gestor de plugins", al activarlo aparece un error similar a:
Esto suele deberse a que el plugin empaqueta dependencias internas de NocoBase dentro de su propio node_modules/. El sistema de build de NocoBase mantiene una lista de externals que enumera los paquetes (por ejemplo react, antd, axios, lodash, etc.) que proporciona el host de NocoBase y que no deben empaquetarse en el plugin. Si el plugin trae una copia privada, en tiempo de ejecución puede chocar con la versión ya cargada por el host y provocar errores extraños.
Por qué en local funciona: en desarrollo el plugin está en packages/plugins/ y no tiene node_modules/ privado; las dependencias se resuelven contra las versiones ya cargadas en la raíz del proyecto y no hay conflicto.
Solución: mueva las dependencies del package.json del plugin a devDependencies. El sistema de build de NocoBase decidirá automáticamente qué dependencias del plugin debe empaquetar:
Después vuelva a compilar y empaquetar. Así el dist/node_modules/ del plugin no contendrá esos paquetes y, en tiempo de ejecución, se utilizarán los del host.
El sistema de build de NocoBase mantiene una lista de externals con los paquetes (por ejemplo react, antd, axios, lodash, etc.) provistos por el host. Los plugins no deben empaquetarlos por su cuenta. Todas las dependencias del plugin deben ir en devDependencies; el sistema de build decide automáticamente cuáles empaquetar en dist/node_modules/ y cuáles deja al host.
Enlaces relacionados
- Plugin: entrada del plugin y ciclo de vida.
- Router: registro de rutas y prefijo
/v. - Visión general de FlowEngine: uso básico de FlowModel.
- FlowEngine → Extensión de bloques: BlockModel, TableBlockModel,
filterCollection. - FlowEngine → Extensión de campos: FieldModel,
bindModelToInterface. - FlowEngine → Extensión de acciones: ActionModel, ActionSceneEnum.
- Internacionalización (i18n): archivos de traducción,
useT,tExpr. - Context → Capacidades comunes:
ctx.api,ctx.viewer, etc. - Servidor → Collections:
defineCollectionyaddCollection. - Servidor → ACL: configuración de permisos.
- Build de plugins: configuración del build, lista de externals y empaquetado.

