Calculando la diferencia entre archivos JSON
Aprende a encontrar traducciones faltantes en archivos JSON con diccionarios.
Daniel Gustaw
• 3 min read
En este artÃculo, demostramos cómo crear una función que identifica las diferencias entre dos archivos JSON.
Desde un punto de vista educativo, esto sirve como un excelente ejemplo de uso de funciones recursivas. Desde una perspectiva práctica, es una herramienta valiosa para gestionar traducciones.
Para comenzar, crearemos un comando que lea los archivos y muestre todas las claves presentes en el primer archivo pero faltantes en el segundo archivo en la salida estándar.
Comenzaremos verificando si los archivos indicados como argumentos existen:
const fs = require('fs')
const pathBase = `${process.cwd()}/${process.argv[2]}`;
const pathComp = `${process.cwd()}/${process.argv[3]}`;
if (!fs.existsSync(pathBase)) {
console.error(`File ${pathBase} not existst`);
process.exit()
}
if (!fs.existsSync(pathComp)) {
console.error(`File ${pathComp} not existst`);
process.exit()
}
A continuación, leeremos el contenido de estos archivos y convertiremos JSON a objetos:
const base = JSON.parse(fs.readFileSync(pathBase).toString());
const comp = JSON.parse(fs.readFileSync(pathComp).toString());
Ahora, definiremos una función para encontrar diferencias:
function getDiff(a, b) {
const res = {};
for (let key in a) {
if (a.hasOwnProperty(key)) {
if (!b.hasOwnProperty(key)) {
res[key] = a[key]
} else {
if (typeof a[key] === 'object') {
res[key] = getDiff(a[key], b[key])
}
}
if (res[key] && !Object.keys(res[key]).length) {
delete res[key];
}
}
}
return res;
}
Esta función toma un par de objetos e itera a través de las claves del primer objeto (base). Si el segundo objeto (comparación) no tiene la clave, se agrega al resultado. Si la clave está presente, verifica si el tipo es un objeto y, si es asÃ, llama recursivamente a la función getDiff.
Finalmente, eliminamos las claves con objetos vacÃos antes de mostrar los resultados:
process.stdout.write(JSON.stringify(getDiff(base, comp)))
Este programa no soporta arreglos. Para los archivos de traducción, no son necesarios. Si deseas leer sobre métodos más avanzados para comparar archivos JSON, un buen punto de partida es un hilo en Stack Overflow:
Usando jq o herramientas de lÃnea de comandos alternativas para comparar archivos JSON
Ahora, veamos cómo funciona el programa en la práctica con archivos de traducción. El primer archivo, en_old.json, fue preparado manualmente y cubre todas las traducciones en la aplicación, mientras que el segundo archivo, en.json, fue generado por i18next. El problema es que i18next no detectó todas las traducciones.
Al principio, ordené ambos archivos manualmente utilizando el servicio: codeshack.io/json-sorter
https://codeshack.io/json-sorter/
A continuación, utilicé diffchecker
para encontrar las diferencias entre ellos:
https://www.diffchecker.com/yffDMWff
Luego, creé un archivo con las traducciones faltantes:
node ../DevTools/json-diff.js src/locales/en_old.json src/locales/en.json > src/locales/en-codes.json
El archivo, mostrado y formateado por jq, se ve asÃ:
Podemos ver que incluye todas las claves faltantes.
Al importar archivos de traducción, podemos utilizar el paquete deepmerge. El archivo de configuración de i18n podrÃa verse asÃ:
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import deepmerge from 'deepmerge'
import en from 'vuetify/lib/locale/en'
import pl from 'vuetify/lib/locale/pl'
Vue.use(VueI18n);
const messages = {
en: deepmerge(
require('@/locales/en-codes.json'),
require('@/locales/en.json'),
{$vuetify: en}
),
pl: deepmerge(
require('@/locales/pl-codes.json'),
require('@/locales/pl.json'),
{$vuetify: pl}
),
};
export default new VueI18n({
locale: process.env.VUE_APP_I18N_LOCALE || 'en',
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
messages,
})
export const languages = [
{text: 'lang.pl', value: 'pl'},
{text: 'lang.en', value: 'en'},
];
Si tienes experiencias relacionadas con la automatización del trabajo de traducción o recomendaciones de herramientas y scripts, no dudes en compartirlas en los comentarios. Estoy interesado en conocer las herramientas y enfoques que utilizas.
Other articles
You can find interesting also.
Análisis de registros de Apache con GoAccess
En esta publicación, muestro una herramienta que permite extraer información interesante de archivos generados automáticamente durante el funcionamiento del servidor.
Daniel Gustaw
• 21 min read
tRPC - ciclo de desarrollo súper rápido para aplicaciones fullstack en TypeScript
Estamos construyendo un cliente y servidor tRPC con consultas, mutaciones, autenticación y suscripciones. La autenticación para websocket puede ser complicada y en este caso lo es, por lo que se presentan tres enfoques para resolver este problema.
Daniel Gustaw
• 16 min read
Exprimimos datos de PDF como el jugo de un limón.
En este artÃculo, mostraremos cómo extraer datos de archivos PDF de manera conveniente escribiendo muy poca cantidad de código.
Daniel Gustaw
• 7 min read