Variantes por plataforma y la fusión de ficheros
Un fichero base y una variante por sistema, fusionados al compilar. Cómo se combinan de verdad —que no es como la gente supone—, qué gana partirlo y cuándo es mejor no hacerlo.
Los ficheros
Junto a tauri.conf.json, el CLI reconoce por su nombre una variante por plataforma:
src-tauri/├── tauri.conf.json el base, siempre se lee├── tauri.macos.conf.json se fusiona encima al compilar para macOS├── tauri.windows.conf.json├── tauri.linux.conf.json├── tauri.android.conf.json└── tauri.ios.conf.jsonCada variante contiene solo lo que cambia, con la misma estructura anidada que el base:
{ "app": { "windows": [{ "titleBarStyle": "Overlay", "hiddenTitle": true }] }, "bundle": { "macOS": { "minimumSystemVersion": "14.0" } }}Además del nombre por convención, el CLI acepta ficheros extra con una bandera, lo que sirve para variantes que no son de plataforma —un canal de pruebas, una compilación interna— sin ensuciar el árbol.
La regla de fusión, y la trampa
La fusión es por clave y en profundidad: un objeto de la variante se combina con el objeto del mismo nombre del base, clave a clave, bajando por los niveles anidados. Hasta ahí, lo que todo el mundo espera.
La trampa está en las listas:
El fallo que produce la trampa
Es siempre el mismo y merece verlo escrito, porque el síntoma no señala la causa.
La lista de ventanas es una lista. Si el base declara la ventana principal con sus diez atributos y la variante de macOS declara solo el estilo de barra de título, el resultado no es la ventana con un atributo extra: es una ventana con solo ese atributo y todo lo demás por defecto.
// tauri.conf.json — la ventana buena"windows": [{ "label": "main", "title": "Catálogo", "width": 1100, "minWidth": 720 }]// tauri.macos.conf.json — MAL: sustituye la lista entera"windows": [{ "titleBarStyle": "Overlay" }]// resultado en macOS: una ventana sin etiqueta, sin título y con el tamaño por defectoY el síntoma que se ve es «en macOS la ventana sale con otro tamaño», que no sugiere en absoluto que el problema sea la fusión. La forma correcta es repetir la lista entera en la variante, con lo que cambia y lo que no:
"windows": [{ "label": "main", "title": "Catálogo", "width": 1100, "minWidth": 720, "titleBarStyle": "Overlay", "hiddenTitle": true}]Es más verboso y es lo que hay. Que las listas se sustituyan enteras es coherente —fusionar listas exigiría una regla de identidad que un JSON no tiene— pero hay que saberlo.
Qué conviene partir
| va bien en una variante | conviene dejarlo en el base |
|---|---|
| la subsección de firma de cada sistema | la identidad: nombre, versión, identificador |
| la versión mínima del sistema operativo | la sección build |
| los formatos de instalador de ese sistema | la política de contenido |
| ajustes del instalador de Windows | los permisos: viven en capabilities/, no aquí |
| un atributo de ventana exclusivo, si repites la lista | cualquier lista que no cambie entera |
La identidad en el base no es negociable: tener un identificador distinto por plataforma es tener tres aplicaciones distintas, con los efectos del nivel 7.1.
Cuándo no usarlas
Tres casos en los que partir el fichero cuesta más de lo que ahorra:
- Cuando la diferencia se puede expresar en el base. Muchas claves ya tienen su subsección por plataforma dentro de
bundle; usar esa es más claro que un fichero aparte. - Cuando la diferencia depende de algo de ejecución. Entonces no es de plataforma, es de estado, y va en Rust.
- Cuando son dos líneas. Un fichero extra por dos líneas convierte «leer la configuración» en «leer cuatro ficheros y fusionarlos mentalmente». La configuración se lee mucho más de lo que se escribe.