El mapa de ficheros
El proyecto entero de un vistazo: qué hay dentro de src-tauri, qué genera el compilador, qué se versiona y qué no, y qué fichero es el que decide cada cosa.
El árbol
mi-app/├── package.json el frontend: dependencias, scripts de dev y build├── index.html el punto de entrada de la interfaz├── src/ tu frontend, sea el framework que sea├── dist/ lo que produce el frontend al compilar (no se versiona)│└── src-tauri/ aquí empieza el otro proyecto ├── Cargo.toml las dependencias de Rust y la forma del paquete ├── build.rs se ejecuta ANTES de compilar: genera el manifiesto ├── tauri.conf.json la configuración: ventanas, bundle, plugins, seguridad ├── capabilities/ qué puede invocar la webview. Fase V │ └── default.json ├── icons/ los iconos de la aplicación, en todos los tamaños ├── src/ │ ├── main.rs tres líneas: llama a run() │ └── lib.rs la aplicación de verdad ├── gen/ generado: los proyectos de iOS y Android. Fase XIII └── target/ generado: artefactos de compilación (no se versiona)Dos observaciones antes de entrar en el detalle. La primera: el frontend no sabe que existe Tauri. Es un proyecto web normal, con su package.json y su directorio de salida; se le podría quitar la carpeta src-tauri y seguiría funcionando como web. La segunda: src-tauri es un paquete de Rust normal, con su Cargo.toml, que se puede compilar y probar por separado.
Qué decide cada fichero
| quiero cambiar… | fichero | dónde, exactamente |
|---|---|---|
| el tamaño de la ventana | tauri.conf.json |
app.windows, o en tiempo de ejecución si depende de algo. Nivel 11 |
| el nombre y la versión | tauri.conf.json |
productName, version, identifier — el identificador es el que no se puede cambiar después. Nivel 7 |
| añadir un plugin | Cargo.toml + lib.rs |
la dependencia y su registro. Y su permiso en capabilities/, o no hará nada. Nivel 9 |
| lo que la webview puede invocar | capabilities/ |
permisos y ámbitos. Fase V entera |
| el formato del instalador | tauri.conf.json |
bundle. Nivel 59 |
| qué comando levanta el frontend | tauri.conf.json |
build.beforeDevCommand, devUrl, frontendDist: el pegamento entre los dos proyectos. Nivel 54 |
| un comando nuevo | lib.rs |
la función, y su registro en el manejador. Fase III |
| ficheros que viajen en el instalador | tauri.conf.json |
bundle.resources. Nivel 54 |
| el manifiesto de permisos | lo genera build.rs |
no se toca a mano: se deriva de los permisos declarados. Nivel 77 |
| los proyectos de iOS y Android | gen/ |
los genera el CLI y se pueden regenerar. Fase XIII |
Por qué una librería con un binario encima
Es la parte del árbol que más extraña: ¿por qué main.rs tiene tres líneas y todo está en lib.rs?
La respuesta es el móvil. En iOS y en Android, tu código no arranca con un main: lo arranca la plataforma, que carga una librería y llama a un punto de entrada concreto. Si la aplicación viviera en el binario, no habría nada que cargar.
Poniendo la aplicación en la librería, los dos mundos funcionan con el mismo código:
# src-tauri/Cargo.toml[lib]# staticlib y cdylib son para iOS y Android; rlib, para que el binario la usecrate-type = ["staticlib", "cdylib", "rlib"]En escritorio, main.rs compila un binario que llama a run(). En móvil, la plataforma carga la librería y llama al punto de entrada que el atributo del nivel 4.2 marcó. Una sola función run(), dos formas de llegar a ella.
Lo que se versiona y lo que no
Tres líneas para el fichero de exclusiones, y una advertencia:
# generado por el compilador de Rustsrc-tauri/target/# generado por tu frontenddist/La advertencia es sobre src-tauri/gen/: son los proyectos nativos de iOS y Android, y la decisión de versionarlos o no es de verdad discutible. Versionados, conservas los cambios manuales que hayas hecho ahí —que en móvil son frecuentes— a costa de un montón de ruido en cada cambio. Sin versionar, cada máquina los regenera y los cambios manuales se pierden. La fase XIII discute las dos posturas; hasta entonces, no hace falta decidir.