de errores con not-found a fork next-runtime-env / Sudo Null IT News

Recientemente encontré un error interesante en Next.js. si en la pagina not-found navegar a través de router.push(pathname)todas las variables de entorno que inicializamos a través de la biblioteca se pierden next-runtime-env (significado window.__ENV se convierte undefined).

En el proyecto utilizamos next-runtime-envya que nos adherimos al enfoque Construya una vez, implemente muchas – esto le permite conservar una imagen de Docker, en la que se incluyen las variables de entorno necesarias al inicio. Next.js no admite este comportamiento de fábrica, porque quiere recopilar variables ambientales en la etapa de compilación de la aplicación.

El error apareció en not-found página donde tenemos un botón que permite crear un elemento con un solo clic si no se encuentra algo. El mismo componente de botón se utiliza en otras páginas y esto es lo interesante: en otras páginas router.push(pathname) funciona correctamente, pero not-found – No.

Al principio pensé que el problema estaba en next-runtime-env. La biblioteca probablemente se anula cuando se actualiza la página, porque el script que establece las variables en window.__ENVcolocado en diseño raíz. También intenté versionar Next.js, asumiendo que el error estaba relacionado con ciertas versiones del marco, pero esto no arrojó ningún resultado. Como resultado, una solución temporal fue utilizar window.location.hreflo que impidió la actualización de la página y ayudó a guardar variables.

Sin embargo, la historia no terminó ahí.


El problema se ha reducido: sólo se perdió la configuración del cliente

Profundicé en el problema, tratando de entender por qué la configuración se perdía sólo en el entorno del cliente. Al principio sospeché router.push(pathname) – Pensé que estaba provocando una recarga de página completa, borrando window y sin provocar que el script se ejecute nuevamente desde el diseño raíz. Sin embargo, resultó que este no fue el caso.

Al intentar reproducir el error en entornos sandbox minimalistas, me encontré con el hecho de que el error no aparecía allí. Luego presté atención al middleware. next-intlque podría influir mágicamente en las variables ambientales durante la navegación. Durante el proceso de depuración, noté que en los sandboxes y en el proyecto en el que me estaba metiendo not-found de diferentes maneras: a través notFound() y a través de router.push(/not-existed-pathname). Esto me llevó a realizar aún más experimentos.

En los comentarios en mi blog de telegramas A mis intentos de descubrir la causa del problema, se me hizo una pregunta razonable: “¿Qué decide exactamente next-runtime-env? ” Respondí que normalmente uso bibliotecas de terceros para gestionar la complejidad del proyecto, pero el problema claramente requería profundizar más en las raíces.

Habiendo ahorrado energía para depurar, comencé a probar diferentes hipótesis:

  1. Reemplace el script nativo en línea con un script de next/scriptpara jugar con diferentes estrategias de carga.

  2. Compruebe si esto se debe a que a partir de la versión 14, not-found está preparado de forma predeterminada en el servidor.

  3. Comprenda por qué se produce una actualización completa de la página al navegar router.push.


No había finales a la vista

Después de numerosos experimentos, incluida la sustitución de scripts nativos por next/script con diferentes estrategias de carga, todavía no pude obtener la configuración en la página not-found a través de router.push. Intenté duplicar scripts en el servidor, jugué con la directiva use clientpero fue en vano.

En algún momento mi entusiasmo se agotó. incluso lo eliminé next-intl del proyecto para verificar si su middleware lo está afectando, pero esto no resolvió el problema.

Entonces me di cuenta de que en la página not-found objeto presente window.__next_fque me recordó a RSC Payload. En él vi mi script con la configuración, pero por alguna razón Next.js no hidrogenó esta parte de la página.

En esta etapa, ya estaba pensando en escribir un analizador de carga útil RSC para extraer la configuración desde allí y extraerla. windowpero algo me distrajo, y entonces decidí buscar lo que escriben sobre esto. __next_f.

Curiosamente, al renderizar la página not-foundNext.js arroja un determinado error y reacciona a todos los errores de la misma manera: deja de representar la página, incluido el diseño, donde tuvo lugar mi asignación de configuración. Cómo explicado en uno de los hilos, el problema es que Siguiente.js detiene la representación de cualquier página cuando ocurre un error, ya sea NotFoundError u otro. Como resultado, el servidor deja de mostrar la página, incluidos todos los elementos de diseño. Es importante tener en cuenta que el HTML inicial que devuelve el servidor no contiene elementos de diseño específicos.

No importa si el error se produce a través de notFound() o a través de regulares new Error()la representación de la ruta se detiene y el HTML devuelto por el servidor no contiene las etiquetas necesarias para los scripts que trabajan con beforeInteractive. Cuando se completa la hidratación, el script se agrega al HTML, pero en este punto el principal app-bootstrap el script ya ha sido ejecutado y su impacto se pierde. Por lo tanto la estrategia de carga beforeInteractive No funciona en páginas con errores.

Sin embargo, todas las demás estrategias de carga, como afterInteractive o lazyOnLoadfunciona correctamente. Esto me impulsó a comprobar cómo cargar scripts en next-runtime-envy resultó que allí también se usa beforeInteractive. decidí abrir relaciones públicas al repositorio, especialmente porque ya encontré dos problemas en los que los desarrolladores encontraron problemas similares: pérdida de configuración en el cliente.

Menos mal que no soy el único que se ha encontrado con esto. Veamos cómo reacciona el equipo al PR. Me pregunto por qué no agregaron soporte para la estrategia de carga de scripts mediante prop. estrategiay ¿existe alguna limitación conceptual que aún no entiendo? Si no hay limitaciones conceptuales, ¡genial! De lo contrario, tal vez haga mi propia implementación para pasar la configuración al cliente sin pérdidas.


Fork y su destino

Al final, decidí liberar mi bifurcación de la biblioteca. next-runtime-env. Se puede encontrar en GitHub: impresionante-siguiente-entorno-de-ejecución.

Describí todas las diferencias con el original en relaciones públicas. Que esta bifurcación se desarrolle más dependerá de si cargan mi PR o no.


Así, el historial de búsqueda de una solución, comenzando con la navegación en not-found página y terminando con una bifurcación de biblioteca, resultó estar llena de giros inesperados.

Publicaciones Similares

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *