El mismo repositorio, el mismo commit, el mismo package-lock.json: En un ordenador la aplicación de Angular funciona perfectamente, en otro muere inmediatamente al hacer bootstrap con un error NG0203. Al final no fue culpa de Angular ni de npm, sino de una carpeta llamada rene.poepperl.000.
Probado con: Angular 22.0.8 · @angular/build 22.0.7 · Node 24 · Windows · Vite Dev-Server
Error NG0203 a pesar de un código fuente sin errores
Desde el pasado viernes, este fenómeno me ha vuelto loco. En mi equipo de desarrollo, la aplicación Angular se iniciaba sin problemas, pero en el servidor de desarrollo, en modo de desarrollo (Windows Server con Remote Desktop), solo aparecía una pantalla blanca y el siguiente mensaje de error en la consola del navegador:
ERROR RuntimeError: NG0203: The `EnvironmentInjector` token injection failed.
`inject()` function must be called from an injection context…
at injectInjectorOnly (_pending_tasks-chunk.mjs:667:11)
at ɵɵinject (_pending_tasks-chunk.mjs:684:40)
at Object.factory (_debug_node-chunk.mjs:10034:42)
at R3Injector.hydrate (_pending_tasks-chunk.mjs:1314:11)
at __spreadProps.getStandaloneInjector (_debug_node-chunk.mjs:10054:31)
at createRootViewInjector (_debug_node-chunk.mjs:8994:44)
at ComponentFactory.create (_debug_node-chunk.mjs:9065:32)
¿Qué significa normalmente el error NG0203?
El error ocurre cuando se utiliza la función inject() de Angular fuera de un contexto de inyección válido. Por lo tanto, en realidad se trata de la inyección de dependencias de Angular.
Los contextos de inyección válidos son:
- Constructores de clases
- Inicializadores de campo
- Funciones de fábrica: dentro de la función de fábrica de un InjectionToken o al configurar proveedores mediante useFactory
- Guards & resolvers funcionales del router (CanActivateFn, ResolveFn, etc.)
Sin embargo, al revisar main.ts, app.config.ts y los diferentes componentes, todo estaba en orden. Configuración estándar con provideRouter y compañía. Nada sospechoso.
Si el mismo código funciona en el ordenador A y no en el B, rara vez el problema está en el código.
Paso 1: Lo más importante primero: reducir el espacio de búsqueda
Antes de leer el código durante horas: el servidor de desarrollo de Angular (Vite con módulos bajo demanda) y el build de producción (esbuild con paquetes fijos) funcionan de manera completamente diferente.
Ejecuta este comando:
npx ng build --configuration development
npx http-server dist/DeinProjekt/browser
Este comando esquiva el servidor de desarrollo Angular-Vite incorporado, construye el proyecto y lo sirve en un simple http-server. Si esto funciona, definitivamente el problema no está en el código ni en las dependencias, sino en algún lugar del servidor de desarrollo de Vite.
Paso 2: Analizar el gráfico de módulos
El mensaje de error NG0203 indica que, en el lugar donde se llama a inject, contra todo pronóstico no existe un contexto de inyección; esto puede ser causado por un problema de múltiples instancias. Si el servidor de desarrollo carga el núcleo de Angular varias veces en lugar de solo una, el contexto de inyección se crea la primera vez, pero en la segunda instancia se llama a inject sin contexto de inyección. Y entonces falla.
Por lo tanto, la búsqueda del error debería continuar en la pestaña de red de las DevTools del navegador para estar seguro.
En mi caso, el servidor de desarrollo realmente entregó los módulos / fragmentos de módulos con dos hashes diferentes. Esto significa que el núcleo de Angular fue procesado dos veces por el prebundler y ambas versiones se cargaron en la aplicación Angular:
| Angeforderte Datei | Typ | Größe |
|---|---|---|
main.js |
script | 104 kB |
@angular_platform-browser.js?v=abc4743f |
script | 50,2 kB |
@angular_core.js?v=abc4743f |
script | 998 kB |
@angular_router.js?v=abc4743f |
script | 261 kB |
| ... | ... | ... |
chunk-GMRBKFW6.js?v=7c52e23b |
script | 89,3 kB |
chunk-KXOBELG4.js?v=7c52e23b |
script | 905 kB |
Dos hashes diferentes (abc4743f y 7c52e23b) significan: El núcleo de Angular fue preempaquetado y cargado dos veces (~998 KB + ~905 KB). Una instancia establece el inyector, la otra encuentra null – ¡y boom, NG0203!
Paso 3: Encontrar al culpable
Cuando quedó claro que realmente se habían cargado dos instancias de Angular, la pregunta era: ¿Por qué?
Para ello ayudó mirar más de cerca la pestaña Sources de las DevTools del navegador.
Esta mostró que una instancia fue cargada desde C:\Users\rene.poepperl\Documents\Projekt y la otra desde C:\Users\rene.poepperl.000\Documents\Projekt. Así que el culpable era mi carpeta de perfil de Windows.
¿Qué ocurrió aquí?
En Windows, se crea una carpeta de perfil de usuario con el sufijo .000 si Windows no puede cargar el perfil de usuario original al iniciar sesión. Entonces Windows crea un nuevo perfil en segundo plano y enlaza las rutas antiguas mediante llamadas ‘Junctions’ (enlaces del sistema de archivos, también llamados puntos de reanálisis).
Normalmente, estas junctions apuntan al final a los mismos archivos. Pero: Node.js o Vite resuelven las rutas con realpath() en algunos lugares y en otros no, lo que genera inconsistencia en los nombres de ruta. Vite cree que está trabajando con dos directorios diferentes y por eso empaqueta node_modules dos veces. ¡Felicidades!
La solución: configuración limpia del espacio de trabajo
La solución es simple, pero requiere un traslado consecuente:
Mueve el proyecto a una ruta real y plana sin puntos de reanálisis (por ejemplo,
C:\dev\TuProyecto).Importante: ¡No lleves contigo la carpeta
node_modules! De lo contrario, arrastrarás contigo las referencias de ruta rotas.Instala las dependencias de nuevo
Luego revisa en el servidor de desarrollo (pestaña de red) si todos los chunks de Angular tienen exactamente el mismo hash ?v=.... Si es así, la aplicación volverá a funcionar de forma estable.