Monorepo Setup for Create React App and Components (2/4)

This is the second part of a serie which provides answers on setting up a fullstack monorepo. If need help on how to initialize a monorepo, have a look into part 1.

  1. Setup a Monorepo for Javascript backend services
  2. Add a Create React App frontend with a component libary (current)
  3. Support Typescript in packages
  4. Deploy to private Github NPM registry


Goals

  • Website which lists events
  • Backend service with Login to create new events


Create the Website

we will use Create React App to create the website:

1cd services
2yarn create react-app web

change the default port to 3001:

1echo "PORT=3001" > web/.env


Create the Backend Web Application

we will use Create React App again:

1cd services
2yarn create react-app admin

change the default port to 3002:

1echo "PORT=3002" > admin/.env


Create the shared React Comonents Libary

1mkdir -p packages/ekzemplo-components/src
2cd packages/ekzemplo-components
3yarn init -y
4yarn add react --peer

Hint: --peer will add as a requirement but does not add it to the libary

Modify the new package.json:

  • set version to `0.0.0``
  • change main to ./dist/index.js
  • add module and source
  • add scripts
1{
2 "name": "ekzemplo-components",
3 "version": "0.0.0",
4 "main": "./dist/index.js",
5 "module": "./dist/index.js",
6 "source": "./src/index.js",
7 "license": "MIT",
8 "scripts": {
9 "start": "microbundle watch --jsx React.createElement",
10 "build": "microbundle build --jsx React.createElement"
11 },
12 "peerDependencies": {
13 "react": "^17.0.1"
14 }
15}

Important: the extentions for "module": "./dist/index.js" has to be .js - using .mjs will break create-react-app

add microbundle to transform and bundle the components:

1yarn add --dev microbundle

create the src/Event.jsx component to show a event:

1import React from "react";
2export default function Event({ name, date }) {
3 return <div>{date} - {name}</div>;
4}

create the src/EventList.jsx component to show a event:

1import React from "react";
2import { useQuery } from "react-query";
3import Event from "./Event";
42;
5export default function EventList() {
6 const { isLoading, error, data } = useQuery("repoData", () =>
7 fetch("http://localhost:3010/events").then((res) => res.json())
8 );
9
10 if (isLoading) return "Loading...";
11
12 if (error) return "An error has occurred: " + error.message;
13
14 return (
15 <ul>
16 {data.map((e) => (
17 <li key={e.id}>
18 <Event name={e.name} date={e.date} />
19 </li>
20 ))}
21 </ul>
22 );
23}

add the react-query to peerDependencies:

1yarn add react-query --peer

add the src/index.js

1import Event from './Event'
2import EventList from './EventList'
3
4export {Event, EventList}

transform all components

1yarn build

switch back to the frontend:

1cd ../../services/web

First, install http-proxy-middleware:

1yarn add http-proxy-middleware

Next, create src/setupProxy.js to route all call to /events to the events microservice:

1const { createProxyMiddleware } = require('http-proxy-middleware');
2
3module.exports = function(app) {
4 app.use(
5 '/events',
6 createProxyMiddleware({
7 target: 'http://localhost:3010',
8 changeOrigin: true,
9 })
10 );
11};


next part: Support Typescript in packages