
Cuando los proyectos se convierten en un poco más de uno, es necesario reutilizar de alguna manera no solo los módulos individuales con código, sino también los componentes de la interfaz de usuario. Hay muchas opciones para resolver el problema, desde copiar y pegar tradicional hasta configurar un proyecto separado con pruebas, documentación e incluso blackjack.
El problema es que la segunda opción requiere esfuerzos de preparación significativos y cada proyecto de este tipo es único, con sus propias herramientas en las que cada nuevo desarrollador necesita lidiar con él nuevamente. A finales de julio, el equipo de Angular propuso su propia solución integral para este problema al agregar a angular / cli un nuevo comando para crear bibliotecas: biblioteca.
Veamos que salió de eso.
Para las pruebas, se tomó la última versión estable de angular / cli - 6.1.5 (09/04/2018)
Mundo perfecto
En un mundo ideal, todo debería ser conveniente. Entonces, para la biblioteca de componentes, destacaría tres puntos importantes
- Uniformidad de proyectos y inicio rápido.
- Conveniencia de desarrollo
- Facilidad de distribución
Entonces, comencemos desde el principio.
Para crear nuestra propia biblioteca, debemos seguir dos pasos: crear un nuevo proyecto y agregarle una biblioteca. Primero, crea un nuevo proyecto:
npx @angular/cli@latest new mylibapp
npxUso npx para no instalar cli globalmente y evitar construcciones de ejecución npm. Si tiene npm versión 5.2 o posterior, pruébelo. Lee más aquí
Después de ejecutar el comando, veremos un proyecto estándar (para 6 angulares, que difiere de la quinta versión) en el que se crearán dos subproyectos: el principal mylibapp y mylibapp-e2e. El proyecto angular en sí se describe ahora en angular.json.

No hay bibliotecas todavía.
Y aquí está la primera advertencia. Nuestro nombre ya está tomado por el proyecto principal, y nombrar la biblioteca tampoco funcionará. Por lo tanto, si desea nombrar la biblioteca my-super-library, primero debe crear un proyecto, que debería llamarse de alguna manera diferente. Por ejemplo, my-super-library-project. Y solo entonces, cree una biblioteca con el nombre deseado.
Ahora cree un tercer subproyecto y genere una biblioteca.
cd mylibapp npx ng generate library mylib
No es necesario especificar un prefijo, pero es muy conveniente no cruzarse con otras bibliotecas.

Como puede ver, ahora, nuestra tercera biblioteca se ha agregado como el tercer subproyecto. Tiene su propio paquete.json, tsconfig y karma.conf.js, que le permite configurarlo sin temor a dañar otros proyectos. Por cierto, si lo desea, podemos agregar otra biblioteca y también será un subproyecto separado. Pero es por eso que la biblioteca no podría distinguirse por un proyecto completamente separado (como, por ejemplo, en .Net), no lo sé. Y si el proyecto e2e no es difícil de eliminar a mano, entonces el proyecto principal ya no está allí. Como resultado, aparece un código adicional en el repositorio, que no es muy bueno.
Ahora veamos qué herramientas tenemos de inmediato. Este es un montón de tslint + codelyzer, karma + jazmín y transportador para e2e. Es decir conjunto estándar de proyecto angular, nada específico de la biblioteca que no nos trajeron. Esto es un poco extraño, ya que una herramienta para ver componentes y convertirlos en documentación (como un libro de cuentos ) es simplemente imprescindible. Pero está bien, asumiremos que aquí simplemente nos dejaron margen de maniobra.
Ejecutemos las pruebas y el linter para asegurarnos de que todo funcione.
npm test mylib npx ng lint mylib
Todo me fue bien, pero Chrome se usó para las pruebas, lo cual también es extraño. No tengo nada en contra de él, pero en los servidores de compilación no será del 90%. No está claro por qué no usaron el mismo Titiritero.
Para resumir:
Pros
- Inicio rápido de un nuevo proyecto.
- Enfoque uniforme
Contras
- Código extra en el proyecto
- Las cosas obvias deben terminarse con las manos.
Hasta ahora, nada crítico, seguimos cavando más.
Desarrollo
Ya tenemos algunos de los componentes listos para usar, echemos un vistazo. Como no tenemos herramientas especiales, utilizaremos el proyecto principal (aquí resulta por qué es necesario). Para hacer esto, necesitamos construir la biblioteca, importar el módulo de la biblioteca e iniciar el proyecto principal.
algun codigo npx ng build mylib
import { MylibModule } from "mylib"; ... @NgModule({ declarations: [ AppComponent, ], imports: [ BrowserModule, MylibModule ], providers: [], bootstrap: [AppComponent] })
npm start
Después de que todo esté hecho, veremos nuestro componente desde la biblioteca. Pero, de nuevo, hay un matiz: el modo de reloj para la biblioteca aún no se ha realizado, ¿necesita ejecutar la biblioteca cada vez? Watch solo aparecerá en angular / cli 6.2+. Y no fuera de la caja, para esto tendrá que agregar una nueva bandera en tsconfig.json
tsconfig.json
"angularCompilerOptions": { "enableResourceInlining": true, }
Y luego ejecute la compilación con la bandera de reloj:
ng build mylib
Si por alguna razón usas cli en 6.2, tendrás que construirlo tú mismo, lo que, francamente, es malo.
Ahora agreguemos un nuevo componente. Para hacer esto, ejecute el comando estándar de generar componentes. Debido al hecho de que la biblioteca no es nuestro proyecto principal, debe usar el indicador del proyecto, que también es un poco molesto (pero si la biblioteca fuera una solución independiente ...).
npx ng generate component some-nice-image
Ahora, en mylib / src, cree la carpeta de activos, agregue una imagen y reconstruya la biblioteca nuevamente para ver el resultado. Y luego nos espera otra sorpresa: no hay imagen. Resulta que los recursos utilizados en la biblioteca no entran automáticamente en la compilación, debe copiarlos usted mismo (o de esa manera ). Y parece que no da miedo, pero de alguna manera no está bien.
Pero sacudir los árboles debería funcionar fuera de la caja. Creemos otro componente en la biblioteca pero no lo usaremos en el proyecto principal. Armar el proyecto principal en modo producción
npx build
Y vemos que el tamaño del paquete no ha cambiado. ¡Sacudir árboles realmente funciona con bibliotecas!
Ahora sería bueno tratar de hacer algún tipo de adicción. Como cada proyecto tiene su propio package.json, primero debemos ir a la carpeta de la biblioteca y ejecutar el comando de instalación npm
npm i -D @drag13/when-do npm i @drag13/round-to
Los puse deliberadamente de diferentes maneras para verificar cómo el empacador manejaría esto más adelante. Todo está listo sin problemas. Intentamos recolectar y recibir una advertencia
No se recomienda distribuir paquetes npm con 'dependencias'. Considere agregar drag13 / round-to a 'peerDependencies' o eliminarlo de 'dependencias
No es deseable distribuir paquetes de dependencia npm. Considere agregar la dependencia drag13 / round-to a las dependencias pares o incluso eliminarla de las dependencias
y luego el error:
La dependencia drag13 / round-to debe estar explícitamente en la lista blanca
La dependencia drag13 / round-to debe agregarse explícitamente a la lista blanca.
Esto ya es interesante, por diseño, la biblioteca no quiere tener dependencias directas. Estamos tratando de trasladar nuestra adicción a la sección de Dependencias entre pares y volver a armarla - voila, todo funciona. Pero eso significa que el orden de instalación de las bibliotecas de terceros ahora es diferente. Primero, coloque la dependencia en el módulo principal, luego agregue los lápices a la sección PeerDependencies de la biblioteca con lápices.
El resto funciona igual que en un proyecto angular regular.
Para resumir brevemente:
Pros:
- Trabajamos en un ambiente familiar con equipos familiares.
- Hay sacudidas de árboles fuera de la caja
Contras:
- Para "ver el componente" necesita usar todo el proyecto
- Todavía no hay modo de reloj
- Los recursos deben copiarse manualmente o configurar el proceso de compilación usted mismo.
Y finalmente, ve a la publicación
Publicar
Todo está justo aquí. Angular / cli utiliza el bien establecido ng-packgr para publicar, que compila nuestro código de forma independiente en un paquete adecuado para la publicación npm, dejando de lado la configuración del archivo package.json (que no es pequeño), minificación, empaquetado en diferentes formatos (por ejemplo, en UMD) .
Para publicar su paquete (o ver lo que hay dentro), debe ejecutar tres comandos
npx ng build
Si no desea publicar, reemplace el comando de publicación con paquete
Como resultado, obtuve lo siguiente:

Primero, echemos un vistazo a package.json, que se ve bastante diferente del package.json original de nuestra biblioteca.

Como puede ver, packagr no eliminó nuestras devDependencies, aunque algunas lo hacen. Además, teóricamente satisfecho con la cantidad de formatos que se describen en package.json (aunque no conozco la mitad de ellos).
Dentro del paquete contiene un paquete minificado y no minificado en el formato UMD, y varios paquetes más del formato interno angular (fesm5, fesm2015). Pero, lo más importante, ahora la cabeza de los desarrolladores no sufrirá por esto, lo cual es maravilloso.
Pasemos a las conclusiones.
Pros:
- Conveniencia
- Consideración
Total
La solución fue interesante, pero cruda. El inicio y la publicación son muy convenientes, pero todavía hay preguntas para el desarrollo. Es especialmente frustrante que ahora la biblioteca no sea un proyecto independiente por diseño, sino más bien una adición al proyecto principal con la posibilidad de publicación.
Por otro lado, se ha realizado una gran parte del trabajo, la funcionalidad está en constante evolución y estoy seguro de que con el tiempo, obtendremos una excelente herramienta para el desarrollo.