This is a basic boilerplate to quickly set up a web application fully written in TypeScript (^4.7.4) based on:
-
NestJS (^9.0.11) for the server: > Go to the server package
« A progressive Node.js framework for building efficient, reliable and scalable server-side applications. »
-
React + ReactDOM (^18.2.0) for the client: > Go to the client package
« A JavaScript library for building user interfaces »
-
Vite (^3.0.9): Based on ESBuild and Rollup, this tool combines speed, performance and configurability to offer the best frontend DX possible
« Next Generation Frontend Tooling »
While being minimalistic, this boilerplate offers a number of features which can be very valuable for the Development Experience (DX):
-
Makes use of the yarn workspaces to centralise the package management system for all the internal packages.
-
TypeScript ^4.7.4 which comes with, for example, optional chaining and customised import paths already defined for each package.
-
EditorConfig + Prettier for code formatting.
-
Full ESLint configurations for linting.
-
Consistent coding style following the standards. See CONTRIBUTING.
-
Development scripts:
yarn start:dev
can be run in any package. See Development & builds for more information. -
Visual Studio Code debug settings.
-
Vite's Hot Module Replacement combined with the React Fast Refresh offers an incredibly fast development process. When you edit and save a source file, it will only reload the corresponding module in the development server AND only re-render the depending components without losing their state!
-
Debugger tool so you can avoid using the native but synchronous and greed
console
's methods. For more information, see the client README section about the Debug library. -
Production ready NGINX configuration example to optimise your frontend file delivery.
-
Production ready Dockerfile.
-
NestJS basic package with all the Nest tools. See the server README for more information.
-
A predefined global config module to handle all the configuration you would like to pass to your server at runtime. You can lean more in the server's README Configuration module section.
-
Production ready Dockerfile.
While being minimalistic, this boilerplate provides straight-forward access to the client's or version's deployed version:
-
To check the server's version, simply call the
/version
endpoint which returns a JSON looking like this:{ "GIT_SHORT_HASH": "568cfad", "GIT_BRANCH": "master", "REPO_VERSION": "1.0.0", "DOMAIN_VERSION": "1.0.0", "LIB_VERSION": "1.0.0", "SERVER_VERSION": "1.0.0" }
-
To identify the client's deployed version, you can see the page's source code and look for the JS bundle name, which should look like:
[email protected]
. This corresponds to the pattern passed in thevite.config.ts
file:[name].${getBuildId()}.[hash].js
. Currently, thebuildId
is defined asshortHash@branch
but you can adapt thegetBuildId
function to your needs. -
Since the two applications are supposed to be deployed as separate Docker images, this boilerplate comes with a simple function embedded in the frontend:
checkServerVersion
. If the server version doesn't satisfy the frontend peer dependency, an error message will be printed in the frontend console (using the debug library).
First, you'll need to download and adapt it to your project:
-
You can use the Use this template feature from GitHub to generate a new project based on this boilerplate. Alternatively, you can clone this repository to a brand new folder named after your
new-project
:git clone [email protected]:LandazuriPaul/nest-react.git new-project
For steps 2 to 5, a global
search in all files
command from any decent editor should help. You can simply search fornest-react
and replace it by yournew-project
.
-
Change the main project's name, set in the root
package.json
'sname
field and in itsscripts
commands. -
Change each package's name, set in its own
package.json
'sname
field. -
Update the
dependencies
of each package requiring one of the internal packages:- Server:
package.json
- Client:
package.json
- Server:
-
Change the client debug
LOGGER_PREFIX
which is set in theconfig.ts
file. For more information, see the client README section about the Debug library. -
Adapt the
packages/client/public
folder to your project (with your icons, manifest, robots.txt files).
Once you're done with the previous steps, you can properly install the project dependencies and link the packages together:
-
Basic requirements to run the repository:
- Node.js: The recommended way is via
nvm
. You can then install the version used for this project:nvm install 16.16.0
- Yarn: If you have
nvm
installed, you'd prefer to installyarn
without the node dependency. To do so, thebash
install is the easiest:curl -o- -L https://yarnpkg.com/install.sh | bash
As the boilerplate makes use of the yarn workspaces, you shouldn't use
npm
. - Node.js: The recommended way is via
-
Install dependencies with the classic:
yarn install
This will install all package dependencies in a common
node_modules
folder at the root of the project using a singleyarn.lock
file to avoid conflicting dependencies. The internal dependencies will be replaced by symbolic links to the corresponding packages. -
Finally, in order to have the "common" packages (
lib
anddomain
) built so they can be used by both theserver
and theclient
, run:yarn build:common
Or if you want the common packages to be watched for file changes, you can run:
yarn start:common
When you want to add new dependencies to any of the packages, you can either:
- Run
yarn add <new-package1> <new-package2>
in the corresponding package folder. - Or run
yarn workspace <YOUR_PACKAGE_NAME> add <new-package1> <new-package2>
from the root folder.
See each package's README to learn more about its development and build scripts:
-
EditorConfig: « helps maintain consistent coding styles for multiple developers working on the same project across various editors and IDEs. »
- Rules are set in the root
.editorconfig
file.
- Rules are set in the root
-
Prettier (^1.19.1): « An opinionated code formatter » which « saves you time and energy ».
- Rules are set in the root
.prettierrc
file.
- Rules are set in the root
ESLint (^8.22.0) with TypeScript parser (^5.33.1): « Find and fix problems in your JavaScript code »
-
Project rules are set in the root
.eslintrc
file. -
As the client package requires specific React related rules, it has its own
.eslintrc
file which extends the project one.
To see how to integrates these tools with your favourite IDE or text editor, you can see the CONTRIBUTING Development tools section.
Each package has its own
yarn lint
command to ensure that its source code is written according to the ESLint rules. The project itself also has a root yarn lint
command to sequentially run it in each internal package.
As you can see in all packages' tsconfig.json
files, both the baseUrl
and paths
properties are defined to help you avoid the cumbersome and error-prone ../../
import paths (amongst other options):
// packages' tsconfig.json
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"outDir": "dist",
"paths": {
"~/*": ["src/*"]
}
}
}
This allows you to import
any file from the same package with the '~/path/to/file/'
notation, considering the src
folder as the package's home (i.e. ~
).
This project comes with a Dockerfile
for each package likely to be deployed. They are all based on the alpine project.
To build the corresponding Docker images, you can use the build_and_push.sh script by setting the PACKAGE
and optionally the VERSION
— defaults to latest
— as environment variables or simply use the dedicated yarn
commands (the latest
version will be applied):
# To build and push the server
yarn build-push:server
# To build and push the client
yarn build-push:client
The shipped docker-compose.yml
file is mainly for demonstration purposes and local testing.
In order to run the applications in a completely containerised environment, please refer to the Docker documentation.
- #TODO: Add an automated script to run installation steps 2 to 5.
This project is licensed under the GNU Lesser General Public License v3.0 or later. You can learn more reading the LICENSE.
Paul Landázuri