carlos Publicada 18 de agosto de 2021 · 7 min read

Primeros pasos y buenas prácticas en Expo

Una imagen decorativa para esta página.

La escalabilidad de un proyecto como una aplicación es una tarea complicada, pues realmente es imposible conocer cuando empiezas todas las funcionalidades que acabarás implementando de tu idea inicial o las que pueden ir apareciendo. A pesar de ello en el post de hoy te cuento un par de consejos sobre cómo minimizar los problemas cuando tu proyecto empiece a crecer.

expo

Si acabas de crear tu primera app y no sabes como organizar el proyecto te voy a contar un par de consejos que me hubiesen sido muy útiles cuando empecé y que me hubieran evitado la reescritura de una gran parte del código según creció la aplicación debido a una mala gestión de la organización.

Organización

Vamos a intentar dividir el proyecto de la siguiente manera

.
├── src
│   ├── navigation
│   ├── scenes
│   ├── components
│   │   ├── lib
│   │   └── atoms
└── App.js

La idea es tener una navegador principal con 3 / 4 pantallas, estas tendrán componentes grandes como puede ser un carrousel de fotos (similar a lo que son las historias de instagram) que introduciremos dentro de nuestra carpeta lib. En la manera de lo posible intentaremos realizar componentes reutilizables y generalizables, aunque en algunos casos esta tarea es complicada te ahorrará mucho trabajo a la larga.

Estos componentes grandes se componen a su vez de componentes más pequeños a los que llamaremos átomos como puede ser un input de texto o un botón y que están en cada rincón de la aplicación por lo que es importante que sean muy reutilizables.

Para ello vamos a crear dentro de la raíz del proyecto una carpeta src y una subcarpeta para cada una de estas tres clases.

  • navigation
  • scenes
  • components
  • atoms
  • lib

Generalización como base de todo

Vamos a empezar con el componente más básico, un botón.

Para ello vamos a crear dentro de la carpeta de atoms un index.js desde el cual exportamos nuestros componentes y un archivo Button.js quedando nuestro árbol de la siguiente manera:

.
├── src
│   ├── navigation
│   ├── scenes
│   └── components
│       ├── lib
│       └── atoms
│           ├── index.js
│           └── Button.js
└── App.js

Importamos en Button.js lo necesario para generarlo.

import React from 'react';
import { TouchableOpacity, Text } from 'react-native';

Utilizaremos el componente TouchableOpacity para crearlo, al cual le vamos a pasar un texto y un estilo para poder generalizarlo.

export const Button = ({text, style}) => {

    return(
        <TouchableOpacity style={style}>
            <Text>{text}</Text>
        </TouchableOpacity>
    )
}

Ahora vamos a ir a nuestro index de atoms para exportarlo:

export { Button } from './Button';

Desde nuestro archivo App.js importamos el botón :

import { Button } from './src/components/atoms';
Captura de Android simulator con un bótón rojo en el medio con el texto no centrado.

Instanciamos un botón simple cuadrado de fondo rojo y con texto Botón

export default function App() {
  return (
    <View style={styles.container}>
      <StatusBar style="auto" />
      <Button 
        style={{ width: 50, height: 50, backgroundColor: 'red' }} 
        text='Button' 
      />
    </View>
  );
}

Ahora bien si ahora necesitamos un botón rectangular, en vez de tener que reproducir el código de Button.js todas y cada una de las veces solo tenemos que modificar la prop style que le estamos pasando al componente haciendo el código mucho más fácil de entender y más compacto.

Captura de Android simulator con un bótón rojo y otro amarillo, amboscon el texto no centrado situados en el centro de la pantalla.
export default function App() {
  return (
    <View style={styles.container}>
      <StatusBar style="auto" />
      <Button 
        style={{ width: 50, height: 50, backgroundColor: 'red' }} 
        text='Button' 
      />
      <Button 
        style={{ width: 200, height: 50, backgroundColor: 'yellow' }} 
        text='Another Button' 
      />
    </View>
  );
}

Una pantalla puede llegar a tener unas 500-800 líneas de código, la legibilidad es una cosa que se aprecia.

Cambios generales en un solo sitio

Imaginemos ahora que queremos que el texto esté situado siempre en el centro del botón, es tan fácil como añadir el estilo directamente al archivo Button.js y automáticamente estará cambiado en cada uno de los botones en vez de tener que ir botón por botón en nuestra aplicación.

Captura de Android simulator con un bótón rojo y otro amarillo, ambos con el texto centrado situados en el centro de la pantalla.
export const Button = ({text, style}) => {

    return(
        <TouchableOpacity style={{ ...style, ...styles.container }}>
            <Text>{text}</Text>
        </TouchableOpacity>
    )
}

const styles = StyleSheet.create({
    container: {
        alignItems: 'center',
        justifyContent: 'center',
    },
});

Ahora parece una cosa sin importancia pues solo tenemos dos botones pero piensa por un momento en cada uno de los botones que componen una aplicación y te hará menos gracia tener que ir a cambiarlos uno por uno.

Configurando Babel

Como no siempre vamos a encontrarnos en la raíz del proyecto los imports pueden tener una ruta complicada, por ello vamos a usar Babel para configurar los alias.

Ejecutamos desde la raíz:

yarn add babel-preset-expo babel-plugin-module-resolver --dev

Abrimos el archivo babel.config.js y añadimos:

module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    "plugins": [
      [
        "module-resolver",
        {
          "root": ["./src"],
          "alias": {
            "@atoms": "./src/components/atoms",
          }
        }
      ]
    ]
  };
};

Hemos añadido el plugin ‘module-resolver’ en el cual hemos especificado que la raíz es ./src y que el alias @atoms se corresponde con “./src/components/atoms”.

Por último vamos a mover el archivo App.js dentro de la carpeta src y a crear un un fichero index.js en la raíz del proyecto.

Vamos a buscar el siguiente archivo en nuestro proyecto node_modules/expo/AppEntry.js y vamos a copiar el contenido dentro del index que acabamos de crear y a modificar el import de App quedando de la siguiente manera:

import registerRootComponent from 'expo/build/launch/registerRootComponent';

import App from './src/App';

registerRootComponent(App);

Finalmente abrimos el archivo package.json y escribimos en la ruta main: "index.js"

Siempre que modifiquemos el archivo de babel será conveniente limpiar la caché así que cerramos el proceso de la terminal donde hemos ejecutado expo start y volvemos a lanzar el proyecto con

expo start --clear

El import de nuestro fichero App.js queda entonces de la siguiente manera:

import { Button } from '@atoms';

Añade tu proyecto a Github

Para terminar el post vamos a crear un repositorio en Github donde poder tener un control de cambios.

Como antes, ahora parece que no merece la pena, pero cuando tengas una versión de la aplicación en producción, otra para pruebas y dos o tres personas programando a la vez verás lo necesario que es.

Ejecutamos en la raíz del proyecto

git init

Ahora ejecutamos lo siguiente para ver las modificaciones que hemos realizado.

git status

Hacemos el commit con:

git commit -m [Your commit message]

Es recomendable hacer commits con pequeños cambios y con nombres significativos, de manera que luego puedas buscar de manera eficaz.

Ahora abrimos Github desde el navegador y creamos un nuevo repositorio completamente en blanco.

Copiamos la dirección https del repositorio y ejecutamos

git remote add origin [Your url]

Configuramos origin como la rama donde hacer push por defecto con

git push --set-upstream origin master

La proxima vez solo tendrás que ejecutar git push y ya estaría todo configurado.

Espero que te haya servido de ayuda, si no ahora en un futuro. Nos vemos en el siguiente post!

Da el primer paso para hacer realidad tu proyecto.

Get in touch