Based on the features in the legacy application and the current requirements we selected NextJS and MUI-5 (https://mui.com/getting-started/usage/) frameworks for:
- Easy integration with generic SSO oAuth services like ORCID, SURFconext, Microsoft etc.
- SEO support for custom meta tags and dynamic build sitemap.xml file
- Rapid development of user interface, in particular, the input/admin pages of the legacy application require improvements
- intall dependencies
yarn install
- create
.env.local
file. Use.env.example
from the project root as template. - run all app modules
docker compose up
- open another terminal and run
yarn dev
to start frontend in development mode
Use this if you are using a custom theme and mount files from the /deployment
directory
You can start the frontend in dev mode inside Docker using the Makefile
. The command will make sure that the created Docker container uses a user with the same user id and group id as your local account. This ensures that you will be the owner of all files that are written via mounted volumes to your drive (mainly everything in the frontend/.next
and frontend/node_modules
folders).
make frontend-docker
Alternatively you can run
# Export your user and group ids to the variables so Docker will correctly build the frontend-dev container. This is required only if you build the container
export DUID=$(id -u)
export DGID=$(id -g)
docker compose build frontend-dev
docker compose up --scale frontend=0 --scale frontend-dev=1 --scale scrapers=0
For oAuth implementation we need env variables. From the project root directory, copy .env.example
file to frontend/.env.local
and provide the values See next documentation page for more info.
.env.local
contains secrets when running frontend in local development (yarn dev). This file is not in the repo. You will need to create it and add secrets to it. There is one difference from basic .env file.
# postgREST api
# cosumed by services: authentication,frontend,auth-tests
# .env.local: http://localhost/api/v1, .env.production.local: http://backend:3500
POSTGREST_URL=http://localhost/api/v1
__tests__
: unit test for pages only. Unit tests for the components are in the same directory as components.assets
: images and icons. These are imported into the components. In case of svg's the content is used to create an icon coponent.components
: all custom components created in this project are stored in this folder.config
: place for configuration objects. For example, menu items are stored here.pages
: next specific, pages and api endpoints. For more information see official documentationpublic
: folder for public assets of the website. For example favicon.ico file and robots.txt are stored here. The root of the public folder is equivalent to the root on the webserver. Note that react file atpage/index.tsx
represents the template for the root webpage.styles
: folder for css files and MUI theme objects. Read specific readme file about theming.types
: folder for typescript type objects. Note! specific, not-shared types are sometimes stored within component fileutils
: folder for utility functions, hooks, composables etc.
The integration between NextJS and MUI-5 is based on official example. More explation concerning the official example can be found in this video
Most important point concerning Next is integration in template files: _app.tsx, _document.tsx
Customization in MUI5 is done using theme object. The theme is provided at the root React component using Theme context provider. In short, add theme provider to _app.tsx file
In addition to MUI-5 team preffers to use Tailwind CSS for global application layout.
# install dev dependencies
npm i -D tailwindcss@latest postcss@latest autoprefixer@latest
Steps performed:
- extracted MUI-5 theme into separate object
- created tailwind.config.js and defined to use shared theme definitions
- created postcss.config.js and added tailwind to it
- added @tailwind mixins to styles/global.css
- created styles/tailwind.css for tailwind specific utilities (eg. @apply)
The integration is based on this article.
For authentication we use custom module which integrates with our auth service. The frontend code is in frontend/auth
folder and the auth service is in authentication
folder.
For unit testing we use jest and react testing library. There are several practices that the React Testing Library promotes:
- Avoid testing internal component state
- Testing how a component renders
The setup is performed according to official Next documentation. We use rust compiler instead of babel setup.
yarn test:watch
: to run test in watch mode. The tests will be runned on each change in the test/component file(s)yarn test:coverage
: to run tests and show the test coverage report. This script is used in GH action.yarn test:memlimit
: for minimal memory consumption. When basic test scripts yarn test and yarn test:coverage causing the memory overflow on your machine use this script to limit the number of concurrent workers and memory usage.yarn test:memory
: for examining memory usage during the tests. In node version 18 (and 16) some changes are made in V8 engine memory management that cause the memory leaks when running tests with Jest. See issue
# install dependencies
yarn add -D jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom
# install whatwg-fetch to address next-auth fetch requests on node js (node-fetch)
yarn add -D whatwg-fetch
- create jest.config.js file and paste content from next instructions
- crate jest.setup.ts file and paste this content.
// isomorphic fetch suport for Node
// required to support fetch with Jest
import "whatwg-fetch";
// specific
import "@testing-library/jest-dom/extend-expect";
This is a Next.js project bootstrapped with create-next-app
.
To learn more about Next.js, take a look at the following resources:
- Next.js Documentation - learn about Next.js features and API.
- Learn Next.js - an interactive Next.js tutorial.
You can check out the Next.js GitHub repository - your feedback and contributions are welcome!
Upgrading minor version changes can be usally done using yarn outdated
and yarn upgrade
. Major updates are more demanding and might require changes in the source code.
Since RSD went live in August 2022 we started using exact versions in the package.json to avoid unexpected upgrades. This means that we manually check for outdated packages and perform "controlled" upgrades. At the same time we perfom security audits using yarn audit
.
# upgrade next, react and typescript
yarn add next@latest react@latest react-dom@latest eslint-config-next@latest typescript
# upgrade types
yarn add -D @types/node @types/react @types/react-dom
# upgrade material ui
yarn add @mui/material @mui/icons-material @emotion/react @emotion/server @emotion/styled
# react testing lib
yarn add -D @testing-library/react@latest @testing-library/jest-dom@latest jest@latest jest-environment-jsdom@latest @types/jest@latest
# cookie for tokens
yarn add cookie
# type
yarn add -D @types/cookie
For the maintenance we use unimported. It will show a list of unused files and dependencies. Additional exclude definitions, specific to this project, are in unimportedrc.json
. Unimported is able to identify next and use pages folder as entry points.
# execute in the frontend folder
yarn unimported
-
Removing unused files: Based on report validate that file are unused/not needed. To validate always run
yarn test
andyarn build
to confirm that test are working and application can be build -
Example report
RSD-as-a-service/frontend$ npx unimported
summary unimported v1.29.2 (next)
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
entry file 1 : ./pages/_app.tsx
entry file 2 : ./pages/_document.tsx
entry file 3 : ./pages/admin/keywords.tsx
entry file 4 : ./pages/admin/orcid-users.tsx
entry file 5 : ./pages/admin/organisations.tsx
entry file 6 : ./pages/admin/public-pages.tsx
entry file 7 : ./pages/admin/rsd-contributors.tsx
entry file 8 : ./pages/admin/rsd-users.tsx
entry file 9 : ./pages/admin/software-highlights.tsx
entry file 10 : ./pages/api/fe/auth/helmholtzaai.ts
entry file 11 : ./pages/api/fe/auth/index.ts
entry file 12 : ./pages/api/fe/auth/local.ts
entry file 13 : ./pages/api/fe/auth/orcid.ts
entry file 14 : ./pages/api/fe/auth/surfconext.ts
entry file 15 : ./pages/api/fe/cite/index.ts
entry file 16 : ./pages/api/fe/index.ts
entry file 17 : ./pages/api/fe/mention/impact.ts
entry file 18 : ./pages/api/fe/mention/output.ts
entry file 19 : ./pages/api/fe/mention/software.ts
entry file 20 : ./pages/api/fe/token/refresh.ts
entry file 21 : ./pages/cookies.tsx
entry file 22 : ./pages/index.tsx
entry file 23 : ./pages/invite/organisation/[id].tsx
entry file 24 : ./pages/invite/project/[id].tsx
entry file 25 : ./pages/invite/software/[id].tsx
entry file 26 : ./pages/login/failed.tsx
entry file 27 : ./pages/login/local.tsx
entry file 28 : ./pages/logout.tsx
entry file 29 : ./pages/organisations/[...slug].tsx
entry file 30 : ./pages/organisations/index.tsx
entry file 31 : ./pages/page/[slug].tsx
entry file 32 : ./pages/projects/[slug]/edit/[page].tsx
entry file 33 : ./pages/projects/[slug]/edit/index.tsx
entry file 34 : ./pages/projects/[slug]/index.tsx
entry file 35 : ./pages/projects/add.tsx
entry file 36 : ./pages/projects/index.tsx
entry file 37 : ./pages/robots.txt.tsx
entry file 38 : ./pages/sitemap/organisations.xml.tsx
entry file 39 : ./pages/sitemap/projects.xml.tsx
entry file 40 : ./pages/sitemap/software.xml.tsx
entry file 41 : ./pages/software/[slug]/edit/[page].tsx
entry file 42 : ./pages/software/[slug]/edit/index.tsx
entry file 43 : ./pages/software/[slug]/index.tsx
entry file 44 : ./pages/software/add.tsx
entry file 45 : ./pages/software/index.tsx
entry file 46 : ./pages/user/[section].tsx
unresolved imports : 0
unused dependencies : 0
unimported files : 5
─────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ 5 unimported files
─────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ components/admin/organisations/OrganisationsPage.tsx
2 │ components/projects/edit/editProjectSteps.tsx
3 │ utils/nextRouterWithLink.ts
4 │ utils/useMentionsForSoftware.tsx
5 │ utils/useOrganisationSoftware.tsx
─────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────