{"id":22684197,"url":"https://github.com/bcariaga/eshop","last_synced_at":"2026-04-11T03:15:05.794Z","repository":{"id":96374529,"uuid":"404503692","full_name":"bcariaga/eshop","owner":"bcariaga","description":"an eshop demo!","archived":false,"fork":false,"pushed_at":"2022-01-29T15:42:50.000Z","size":1429,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-04T15:47:03.118Z","etag":null,"topics":["modulefederation","nodejs","react","webpack"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bcariaga.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-08T21:43:20.000Z","updated_at":"2022-01-29T15:42:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"134dacba-976f-409f-98e3-4abaa4bfad49","html_url":"https://github.com/bcariaga/eshop","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcariaga%2Feshop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcariaga%2Feshop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcariaga%2Feshop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcariaga%2Feshop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bcariaga","download_url":"https://codeload.github.com/bcariaga/eshop/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246200300,"owners_count":20739563,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["modulefederation","nodejs","react","webpack"],"created_at":"2024-12-09T21:18:57.404Z","updated_at":"2025-12-30T20:30:21.412Z","avatar_url":"https://github.com/bcariaga.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# eshop\n\n\n## TL;DR\npara correr el proyecto anda directo a [Setup \u0026 Run](#setup--run)\n\n\n## Intro\n\nHola! en este proyecto es una _demo_ funcional de un eshop, cuenta con 3 _vistas_:\n- Busqueda de productos: Nos brinda un input para poder hacer una busqueda de productos (contra la api de MeLi)\n- Listado de productos: Nos muestra los productos encontrados junto a su imagen, precio, titulo, condicion y tipo de envio.\n- Detalle de un producto: Ademas de los datos que ya se ven en el listado tenemos: Imagen com mas resolucion, Descripcion y cantidad de productos vendidos.\n\n## Arquitectura - Stack\n\n### Backend\n\nStack:\n- NodeJS (\u003e14)\n    + Express (\u003e4.17)\n    + Axios\n- Jest (tests)\n\nEs un BFF simple donde se hace _wrapping_ de las api de MeLi:\n- https://api.mercadolibre.com/sites/MLA/search?q=:q para realizar una busqueda\n- https://api.mercadolibre.com/items/:id para obtener el detalle de un producto\n- https://api.mercadolibre.com/items/:id/description para obtener la descripcion de un producto\n\n#### Estructura\n- Lib\n    + `controllers`: punto de entrada de los _routes_ orquestan los parametros recibidos y se comunican con los _services_ para gestionar los datos\n    + `services`: saben donde y como buscar la informacion\n    + `models`: conocen como se deben presentar los datos (y como convertir los datos externos en datos del dominio)\n    + `routes`: las rutas y configuracion de los handlers (para derivar a los controllers)\n    + `middleware`: se creo un _custom middleware_ para agregar una firma a todos los requests\n    \nSripts disponibles (con npm):\n- `npm start` : levanta una instancia del backend en _localhost_ el puerto se lee de `.env` (si no se cambio es 4000)\n- `nom test` : corre los tests y muestra el coverage actual.\n\n#### TODO:\n\nAlgunas features no se completaron aun: \n- [ ] Manejo de errores\n- [ ] Configuracion de CORS (deja pasar todo)\n- [ ] Coverage: se cubren solo los casos _criticos_ \n\n### Frontend\n\n\u003e _Aca se pone divertido!_\n\nPara el front se planteo una arquitectura de micro-frontends, pensando en la facilidad que nos da esto para orquestar distintos **equipos de desarrollo**, **_deploys_ mas chicos** y con menos impacto, posibilidad de mejorar la _performance_ en **cada modulo**, reutilización real de componentes/librerias, y algunas ventajas mas.\n\nStack:\n- ReactJS (\u003e17)\n    - ReactJSS (\u003e10)\n- Webpack\n    - Weppack Module Federation 😎\n- Jest\n- React Testing Library\n\n#### Estructura\n\nEl proyecto se forma por **5 microfonts**:\n- `host`: es el proyecto raiz, el encargado de orquestar y cargar los otros modulos (aunque cada modulo de por si, puede cargarse solo*), tiene un pequeño context + state (`useContext` + `useReducer`) para manejar el estado de los modulos _invitados_. No se opto por `redux` o algo mas potente como `sagas` para manejar este estado (y sus side-effects) porque la complejidad es casi nula, de hecho se podria evitar usar el contexto con algunos cambios en el backend.\n- `lib`: este modulo contiene los componentes que se comparten, por ejemplo: `\u003cItemPrice/\u003e` que se usa tanto en la busqueda como en el detalle de un producto. O bien, funciones de ayuda, como para generar `styles` con media queries (gracias a `ReactJSS`).\n- `product-detail-mf`: componentes para ver el detalle de un item. Recibe un ID, busca en el backend el detalle y lo renderiza.\n- `search-box-mf`: barra de busqueda, maneja el estado del form de busqueda. Se opto por un form para resolver la navegacion y no tener que manejar el estado en **_componentes controlados_**. Cuando se realiza una busqueda ejecuta una funcion que se pasa por parametros.\n- `search-result-mf`: **busca productos** y los **renderiza** aislando esta feature en un modulo 😁\n\n\u003csub\u003e *_se pueden cargar solos, pero hay componentes que sin pasarle las props correctas no serian funcionales (nada que con un poco de ❤️ no se pueda arreglar)_ \u003csub\u003e\n\nSripts disponibles en cada modulo (con npm):\n- `npm start`: levanta el proyecto con `webpack` en localhost (el puerto esta _hardcore_ en cada `webpack.config.js` _friendly reminder: no lo cambies_)\n- `npm run build`: hace build y deja el modulo listo en `/dist`, lo vamos a usar para crear las imagenes de docker (si, si, hay soporte para `Docker` 😎)\n- `npm test`: corre los tests con jest y muestra el coverage (por si no quedaba claro 😜)\n- `npm run lint`: no hace falta explicar...\n\n#### Estilos\n\nNota aparte para los estilos de la solucion. Se opto por usar `React-JSS` para crear componentes con estilos individuales (util para los microfronts) y reducimos el tamaño del bundle.\nLamentablemente, se genera mucho codigo que no hace a la solucion. Lo ideal seria contar con una libreria de componentes que resuelva la parte visual.\n\n#### TODO:\n\nAlgunas features no se completaron: \n- [ ] Mejorar el SEO con un SSR vendria de 10 💯\n- [ ] react-helmet: mejoraria un poco la accesibilidad y SEO.\n- [ ] Optimizar la generacion de bundles: https://webpack.js.org/guides/code-splitting/\n- [ ] Agregar una libreria de componentes, no escala usar CSS-in-JS 😰\n\n### Setup \u0026 Run\n\nSe usa `Lerna` para gestionar todos los modulos.\n\n#### Local:\n1. `npm i` -\u003e instalamos las dependencias\n2. `npm start` -\u003e Levanta todos los servicios, el proyecto host esta en : http://localhost:3000\n\n#### Recomendado: Docker\n\nSi! podemos correrlo con docker, mejoramos la performance porque se corre en modo `production` y solo se sirven los bundles resultantes del _publish_.\nNota: cada MF tiene su docker image, montando sobre un ngnix (`nginx:1.21.0-alpine`) los bundles generados previamente con `npm build`. \nPara el backend se usa la imagen `node:14-alpine`\n\nNuevamente aprovechamos `lerna` y lo podemos levantar corriendo:\n1. `npm i`: (opcional si ya se instalaron los modulos)\n2. `npm run start:docker`: esto hace un publish de cada modulo y usa `docker-compose` para levantar los servicios.\n\nPara parar los servicios podemos correr `npm run stop:docker`\n\n### Extra\n desde la raiz tmb se puede correr los tests de todos los proyectos: `npm run test`\n\n\n ----------\n \n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n\u0026nbsp;\n\n \u003e \u003csub\u003e _gracias por llegar hasta el final!_ \u003csub\u003e\n\n ![Alt Text](https://media.giphy.com/media/4ml290TZ35zOM/giphy.gif)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbcariaga%2Feshop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbcariaga%2Feshop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbcariaga%2Feshop/lists"}