
En los últimos años, el concepto de
mono-repositorios se ha establecido
con éxito, ya que puede simplificar significativamente el proceso de desarrollo de proyectos de software modular, como las infraestructuras basadas en microservicios. Las principales ventajas de este enfoque arquitectónico son obvias en la práctica, por lo tanto, propongo crear su propio
mono-repositorio de prueba desde cero, al mismo tiempo que comprende los matices de trabajar con
espacios de trabajo de hilo y
lerna . Bueno, empecemos!
Considere la estructura de nuestro proyecto, que serán tres bibliotecas ubicadas en la carpeta
paquetes / , así como
package.json en el directorio raíz.
├── package.json └── packages ├── app │ ├── index.js │ └── package.json ├── first │ ├── index.js │ └── package.json └── second ├── index.js └── package.json
Se entiende que tenemos dos bibliotecas independientes
primero y
segundo , así como una biblioteca de
aplicaciones que importará funciones de las dos primeras. Por conveniencia, los tres paquetes se colocan en el directorio de
paquetes . Puede dejarlos en la carpeta raíz o ponerlos en un directorio con cualquier otro nombre, pero para seguir las convenciones generalmente aceptadas, los colocaremos de esta manera.
Las bibliotecas
primero y
segundo para simplificar el experimento contendrán solo una función en
index.js , cada una de las cuales devolverá una cadena de saludo en nombre del módulo. Para el
primer ejemplo, se verá así:
En el módulo de la
aplicación , mostraremos el mensaje
Hola desde la aplicación en la consola, así como saludos desde otros dos paquetes:
Para que el
primero y el
segundo estén disponibles en la
aplicación , los denotamos como dependencias en
dependencias .
Además, para cada biblioteca agregamos el prefijo
@ monorepo / en el
nombre del valor delante del nombre principal del paquete al paquete
local.json .
¿Por qué necesito un prefijo con un icono de perro delante del nombre del paquete npm (@ monorepo /)?Agregar un prefijo es opcional, pero esta
es exactamente
la convención de denominación
de paquetes a la que se adhieren muchos monorepositorios:
material ui ,
angular y otros. El hecho es que cada usuario u organización tiene su propio
alcance en el
sitio web
npm , por lo que hay una garantía de que todos los módulos con
@ somescope / postfix son creados por el equipo de
somescope y no por los atacantes. Además, se hace posible llamar a los nombres de módulos que ya están en uso. Por ejemplo, no puede simplemente tomar y crear su propio módulo de
utilidades , porque esa biblioteca
ya existe . Sin embargo, agregando el postfix
@ myscopename / podemos obtener nuestras
utilidades (
@ myscopename / utils ) con blackjack y señoritas.
Un análogo de la vida real para nuestro proyecto de prueba puede ser varias bibliotecas para trabajar con datos, herramientas de validación, análisis o simplemente un conjunto de componentes de la interfaz de usuario. Si suponemos que vamos a desarrollar una aplicación
web y
móvil (por ejemplo, usando
React y
React Native, respectivamente), y tenemos parte de la lógica reutilizada, puede valer la pena ponerla en componentes separados, para su uso posterior en otros proyectos. Agregue a esto el servidor en
Node.js y obtendrá un caso muy real de la vida.
Espacios de trabajo de hilo
El toque final antes de crear un
repositorio mono completo será el diseño de
package.json en la raíz de nuestro repositorio. Preste atención a la propiedad de
espacios de trabajo : especificamos el valor de los
paquetes / * , que significa "todas las subclaves en la carpeta de
paquetes ". En nuestro caso, esta es la
aplicación ,
primero ,
segundo .
Además,
"private": true debe especificarse en
package.json , ya que los
espacios de trabajo solo están disponibles en proyectos privados.
Para que todo despegue, ejecute el comando
yarn (de forma análoga a
yarn install o
npm install ) desde el directorio raíz. Dado que las dependencias que existen en el módulo de la
aplicación se definen como
espacios de
trabajo en el
paquete raíz.json , de hecho, no descargaremos nada de
npm-Registry , sino que simplemente
enlazaremos ("
enlazaremos ") nuestros paquetes.
yarn

Ahora podemos ejecutar el comando del
nodo. desde el directorio raíz que ejecutará el script desde el
archivo packages / app / index.js .
node .

Veamos como funciona.
Al llamar a
yarn , creamos enlaces simbólicos en
node_modules a nuestros directorios en la carpeta de
paquetes .

Debido a esta relación en las dependencias, obtuvimos una gran ventaja: ahora, al cambiar en el
primer y
segundo módulo, nuestra
aplicación recibirá la versión actual de estos paquetes sin reconstruirla. En la práctica, es muy conveniente, porque podemos llevar a cabo el desarrollo local de paquetes, aún definiéndolos como dependencias de terceros (que eventualmente se convierten).
La siguiente ventaja importante que puede obtener al trabajar con
espacios de trabajo de hilo es la organización del almacenamiento de dependencias de terceros.
Obtenga más información sobre el almacenamiento de dependencias en el nivel superior.Supongamos que queremos usar la biblioteca
lodash en
primer y
segundo lugar .
Al ejecutar el comando yarn add lodash desde los directorios apropiados, recibiremos una actualización del
paquete local.json : la versión actual del paquete aparecerá en las
dependencias .
"dependencies": { "lodash": "^4.17.11" }
En cuanto al paquete
lodash en sí , físicamente la biblioteca se instalará en
node_modules en el nivel raíz una vez.
Si la versión requerida del paquete externo (en nuestro caso
lodash ) es diferente para el
primero y el segundo (por ejemplo,
primero necesita
lodash v3.0.0 , y en el
segundo v4.0.0 ), entonces un paquete con una versión inferior (
3.0.0 ) llegará a la raíz
node_modules , y la versión
lodash para el
segundo módulo se almacenará en
paquetes locales
/ second / node_modules .
Además de las ventajas, este enfoque puede tener desventajas menores, que el
hilo permite evitar con la ayuda de banderas adicionales. Puede leer más sobre tales matices en la
documentación oficial .
Añadir Lerna
El primer paso para trabajar con
lerna es instalar el paquete. Por lo general, realizan una instalación global (
yarn global add lerna o
npm i -g lerna ), pero si no está seguro de si desea usar esta biblioteca, puede usar la llamada usando
npx .
Inicializaremos
lerna desde el directorio raíz:
lerna init

De hecho, realizamos varias acciones a la vez con la ayuda de un comando: creamos un repositorio git (si no se había inicializado antes), creamos un archivo
lerna.json y actualizamos nuestro
paquete raíz.json .
Ahora en el archivo
lerna.json recién creado
, agregue dos líneas:
“npmClient”: “yarn” y
“useWorkspaces”: true . La última línea dice que ya usamos
espacios de trabajo de hilo y no hay necesidad de crear la
carpeta app / node_modules con enlaces simbólicos a
primero y
segundo .
Pruebas con Lerna
Para mostrar la conveniencia de trabajar con
lerna, agregue pruebas para nuestras bibliotecas.
Desde el directorio raíz, instalamos el paquete para probar -
jest . Ejecute el comando:
yarn add -DW jest
¿Por qué necesito la bandera -DW?El indicador -D (- dev) es necesario para que el paquete jest se instale como una dependencia de desarrollo, y el indicador -W (- ignore-workspace-root-check) permite la instalación en el nivel raíz (que necesitamos).
El siguiente paso es agregar un archivo de prueba a nuestro paquete. Para la conveniencia de nuestro ejemplo, haremos todas las pruebas similares. Para el
primer ejemplo, el archivo de prueba se verá así:
También necesitamos agregar un script para ejecutar pruebas en
package.json de cada una de nuestras bibliotecas:
El toque final será actualizar el
paquete raíz.json . Agregue un script de
prueba que llame a
lerna run test --stream . El parámetro que sigue a
lerna run define el comando que se llamará en cada uno de nuestros paquetes desde los
paquetes / carpeta, y el indicador
--stream nos permitirá ver la salida de los resultados en el terminal.
Como resultado,
package.json del directorio raíz se verá así:
Ahora, para ejecutar las pruebas, solo necesitamos ejecutar el comando desde la raíz de nuestro proyecto:
yarn test

Actualización de versión con Lerna
La próxima tarea popular, con la que
lerna puede hacer frente a la calidad, será actualizar las versiones del paquete. Imagine que después de implementar las pruebas, decidimos actualizar nuestras bibliotecas de 1.0.0 a 2.0.0. Para hacer esto, simplemente agregue la línea
"update: version": "lerna version --no-push" al campo de
scripts del
paquete raíz.json , y luego ejecute
yarn update: version desde el directorio raíz. El indicador
--no-push se agrega para que después de actualizar la versión los cambios no se envíen al repositorio remoto, lo que
lerna hace por defecto (sin este indicador).
Como resultado, nuestro
paquete raíz.json se verá así:
Ejecute el script de actualización de versión:
yarn update:version
A continuación, se nos pedirá que seleccionemos la versión a la que queremos cambiar:

Al hacer clic en
Entrar , obtenemos una lista de paquetes en los que se actualiza la versión.

Confirmamos la actualización ingresando
y y recibimos un mensaje sobre la actualización exitosa.

Si tratamos de ejecutar el comando
git status , no recibimos
nada para confirmar, trabajando en árbol limpio , porque
La versión lerna no solo actualiza las versiones del paquete, sino que también crea un git commit y una etiqueta que indica la nueva versión (v2.0.0 en nuestro caso).
Características de trabajar con el equipo de la versión lernaSi agrega la línea
"versión": "versión lerna --no-push" en lugar de
"actualización: versión": "versión lerna --no-push" en el campo de los
scripts del
paquete raíz.json , lo más probable es que encuentre un comportamiento inesperado y consola roja El hecho es que
npm-scripts por defecto llama al comando de
versión (script reservado) inmediatamente después de actualizar la versión del paquete, lo que conduce a una llamada recursiva a la
versión lerna . Para evitar esta situación, es suficiente darle al script un nombre diferente, por ejemplo,
actualización: versión , como se hizo en nuestro ejemplo.
Conclusión
Estos ejemplos muestran una centésima parte de todas las posibilidades que
lerna tiene en conjunción con
espacios de trabajo de hilo . Desafortunadamente, hasta ahora no he encontrado instrucciones detalladas para trabajar con monorepositorios en ruso, ¡así que podemos suponer que se ha comenzado!
Enlace al repositorio del proyecto de prueba.