Estoy trabajando en un módulo i18n personalizado y me encantaría reemplazar este código (esta es una página "acerca de nosotros"):
const messages = (await import(`./about-us.${locale}.json`)) .default as Messages;Por
const messages = ( await import(`./${__filename.replace('.tsx', `.${locale}.json`)}`) ).default as Messages; Desafortunadamente __filename resuelve en /index.js (¿supongo que debido a Webpack?) - ¿Hay alguna forma de lograr lo que estoy tratando de hacer en mi ejemplo o esto debería estar integrado en Next.js directamente para que funcione?
Spoiler: no te voy a decir cómo acceder a __filename con Next.js; No sé nada de eso.
Aquí hay un patrón que es mejor que lo que propones y que evade el problema por completo.
Primero, configuración: parece que tienes una carpeta llena con estos archivos JSON. Me imagino esto:
l10n/ about-us.en-US.json about-us.fr-FR.json contact-us.en-US.json contact-us.fr-FR.json ... <package>.<locale>.jsonEsa organización de archivos es agradable, pero es un error hacer que todos los posibles consumidores de l10n lo sepan.
Es mejor crear una función que tome packageName y localeCode como argumentos y devuelva el contenido deseado. Esa función se convierte entonces en la única parte de la aplicación que debe conocer los nombres de archivo, la lógica de respaldo, etc.
// l10n/index.js export default function getLang( packageName, localeCode ) { let contentPath = `${packageName}.${localeCode}.json` // TODO: fallback logic return JSON.parse(FS.readFileSync(contentPath, 'utf8')) } Es un trabajo complejo ubicar y leer los datos deseados y, al mismo tiempo, garantizar que ninguna solicitud obtenga una carga útil vacía y que cada tecla de texto se resuelva en un valor. import dinámica + sistema de archivos sano es un buen comienzo (:aplausos:), pero esa combinación no es lo suficientemente sólida por sí sola.
En un trabajo anterior, construimos un microservicio completo solo para hacer esto. (También creamos un servicio separado para obtener traducciones y algunos paquetes npm privados para permitir que las aplicaciones web soliciten y usen paquetes de idiomas de nuestro CMS). no es diminuto.
1 Lógica alternativa: por ejemplo en-UK y en-US suelen ser intercambiables; algunos grupos de lenguas romances podrían ser aceptables en una emergencia (me vienen a la mente español/portugués/brasileño); también idiomas germánicos, etc. Lo que funciona y lo que no depende del contenido y el contexto, pero ninguna versión de respaldo encajará en una import dinámica.
Después de una larga búsqueda, la solución fue escribir un useMessages que se "inyectaría" con las cadenas correctas usando un complemento de Babel personalizado.
Un cargador de Webpack no parecía la opción correcta ya que el cargador solo tiene acceso al contenido del archivo que carga. Al usar Babel, tenemos muchas más opciones para inyectar código en la versión compilada final.