Code Structure
In the root folder we have 3 different app-configs. They are used for different environments. When we run yarn dev it will use app-config.yaml by default and will override whatever is in app-config.local.yaml which initially comes empty.
Let's imagine we have a development portal and a production one, but the project is the same and what changes are the Github, Gitlab, database, cluster keys, etc. Of course, when creating a production image we need to point to the config with the correct credentials. In this second moment, app-config.yaml will be used to load the initial configurations and app-config.production.yaml will be used to override what's necessary.
In the packages folder we have the following.
tree packages
packages
βββ README.md
βββ app
β βββ e2e-tests
β β βββ app.test.ts
β βββ package.json
β βββ public
β β βββ android-chrome-192x192.png
β β βββ apple-touch-icon.png
β β βββ favicon-16x16.png
β β βββ favicon-32x32.png
β β βββ favicon.ico
β β βββ index.html
β β βββ manifest.json
β β βββ robots.txt
β β βββ safari-pinned-tab.svg
β βββ src
β βββ App.test.tsx
β βββ App.tsx
β βββ apis.ts
β βββ components
β β βββ Root
β β β βββ LogoFull.tsx
β β β βββ LogoIcon.tsx
β β β βββ Root.tsx
β β β βββ index.ts
β β βββ catalog
β β β βββ EntityPage.tsx
β β βββ search
β β βββ SearchPage.tsx
β βββ index.tsx
β βββ setupTests.ts
βββ backend
βββ Dockerfile
βββ README.md
βββ node_modules
β βββ app -> ../../app
βββ package.json
βββ src
βββ index.ts
We can see that we have the app folder (frontend) and the backend folder.
- The frontend (app) is based on React.
- The backend is based on Node.js and uses the Express JS framework.
We can run them together or separately. If we look at app-config.yaml we can adjust the ports that will be used for this.
app:
title: Scaffolded Backstage App
baseUrl: http://localhost:3000
backend:
baseUrl: http://localhost:7007
listen:
port: 7007
In a terminal, in the root folder of the project, if we run the command yarn start we will have the portal in the browser at localhost:3000 without being able to populate anything. In another terminal if we run yarn start-backend, wait a bit and refresh the browser, everything works. The yarn dev command runs both commands together.
Knowing this, we can already understand that we can scale this if needed in the future in Kubernetes as containers.
The plugins folder will be used when necessary when we create our own plugins.
In the package.json file we can see the commands we can execute with yarn and the versions of the libraries used.
The yarn dev command is just an alias for the real command yarn workspaces foreach -A --include backend --include app --parallel -v -i run start. It's important to know the commands because they can be useful in the entrypoint and cmd of the image.
"scripts": {
"dev": "yarn workspaces foreach -A --include backend --include app --parallel -v -i run start",
"start": "yarn workspace app start",
"start-backend": "yarn workspace backend start",
"build:backend": "yarn workspace backend build",
"build:all": "backstage-cli repo build --all",
"build-image": "yarn workspace backend build-image",
"tsc": "tsc",
"tsc:full": "tsc --skipLibCheck false --incremental false",
"clean": "backstage-cli repo clean",
"test": "backstage-cli repo test",
"test:all": "backstage-cli repo test --coverage",
"test:e2e": "playwright test",
"fix": "backstage-cli repo fix",
"lint": "backstage-cli repo lint --since origin/master",
"lint:all": "backstage-cli repo lint",
"prettier:check": "prettier --check .",
"new": "backstage-cli new --scope internal"
},
Still in package.json, we can see the use of workspaces. This configuration indicates that the Node.js project uses Yarn Workspaces, a feature that facilitates monorepo management. What does this mean? It means that yarn installs all dependencies of partial projects in a single place (node_modules folder) to avoid dependency duplication and facilitate management.
"workspaces": {
"packages": [
"packages/*",
"plugins/*"
]
},
- workspaces: Defines that the current project is a monorepo and specifies where the packages that are part of this monorepo are located.
- packages: It's an array that lists the directories where the monorepo packages are located. In this case we have app with its package.json and backend with its own package.json.
- plugins: Each of the plugin projects could even have their own separate package.json.
"packages/": Includes all directories inside the packages folder. "plugins/": Includes all directories inside the plugins folder.
An illustrative example.
my-project/
βββ package.json β Workspaces definition
βββ node_modules/ β Centralized dependencies
βββ packages/
β βββ package1/
β β βββ package.json
β βββ package2/
β βββ package.json
βββ plugins/
βββ plugin1/
β βββ package.json
βββ plugin2/
βββ package.json
The yarn install command installs the dependencies for all package.json files and each of the workspace projects.
The command yarn workspace app start or the script yarn start in the root folder means that we will execute only the yarn start command as if we were in the package/app folder. This yarn start command, which is also a script from the package.json inside the packages/app folder, if executed inside the app folder (it's a workspace) would be the same as executing the command backstage-cli package start.
App workspace scripts to better illustrate.
"scripts": {
"start": "backstage-cli package start",
"build": "backstage-cli package build",
"clean": "backstage-cli package clean",
"test": "backstage-cli package test",
"lint": "backstage-cli package lint"
},
In app we can have a portal with the company's look and feel, include various sidebar tabs to facilitate searches, and much more.
In backend we have the functionalities actually implemented.
Knowing this, shall we add a tab for Kubernetes there? Hold on young grasshopper, let's walk before we run.