Skip to content

Instantly share code, notes, and snippets.

@sbeugen
Last active August 9, 2023 06:51
Show Gist options
  • Select an option

  • Save sbeugen/7adf0d650db2ee90af4127b46bb2462e to your computer and use it in GitHub Desktop.

Select an option

Save sbeugen/7adf0d650db2ee90af4127b46bb2462e to your computer and use it in GitHub Desktop.

This guide provides step by step instructions on how to setup a repository consisting of a frontend directory bootstrapped using Vite and a backend directory bootstrapped using the NestJS-CLI. Note that you will need node and npm installed globally on you machine. This can be done by downloading the current LTS version for your OS from here. In addition to this we will use pnpm as an alternative to the Node Package Manager (npm) in our project. After setting up node on you machine you can install pnpm by running npm install -g pnpm from any directory.

Target folder structure

- backend/
	- node_modules/
	- package.json
	- all other source files etc.
- frontend/
	- node_modules/
	- package.json
	- all other source files etc.
- node_modules/
- package.json

The repository will include three package.json files and therefore also three node_modules directories. The ones in the backend/ and frontend/ directories contain all scripts and dependencies needed for this specific part of the full stack application. The ones on the root level contain scripts and dependencies needed to start the whole application with a single command.

Find more information on what a package.json and the corresponding node_modules directory does here and here.

Generating the root package.json

In the root directory run pnpm init and simply confirm every question with enter. This will generate a package.json with basic information about the project.

{
  "name": "fullstack-ts-setup",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Now let's also add the first dependency we need on the root level, which is concurrenlty. We will use this tool later to run multiple processes (starting the frontend and the backend) in parallel. This is done by executing pnpm add concurrently. Now the dependency should appear in your package.json and a node_modules directory should have been created next to it.

Configuring GIT for the overall project

Run git init in the root of your repository.

Bootstrapping the React project

All we need to do is running pnpm create vite frontend --template react-ts. This will create a directory called frontend and setup a ready to be used React app with Typescript.

If you take a look at the frontend/package.json file, you will see several dependencies and scripts for running, building and testing the app pre configured for you.

...
"scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview"
},
...

More information on the first steps with Vite can be found here

Bootstrapping the NestJS project

First we need to install the NestJS CLI globally using npm: npm i -g @nestjs/cli

Then from the root of your repository run nest new backend. This will create a directory with the name backend containing a package.json, node_modules and all source files needed for a basic ready to be used NestJS app.

It also creates a new GIT root. This one needs to be deleted, as well. Run cd backend && rm -rf .git.

Allow CORS backend app

As we will make request from a different port, CORS will become an issue. An simple solution for solving this, is add the line app.enableCors() just before await app.listen(3000).

Connecting backend and frontend

Bootstrapping a project using the NestJS CLI will generate the first controller (backend/src/app.controller.ts) for you. In order to do an request against this endpoint following things need to be done:

  1. cd into the frontend directory
  2. run pnpm add axios (axios is a library which simplifies making REST requests in JS/TS applications)
  3. replace the App() component in frontend/src/App.tsx with the following code. We make use of React Hooks in this example. As they are an important concept in React, find more information on them here.
function App() {
  const [text, setText] = useState<String>('');
  
  useEffect(() => {
    axios
    .get('http://localhost:3000/')
    .then(response => {
      setText(response.data);
    });
  }, [])

  return (
    <div className="App">
      <h1>{text}</h1>
    </div>
  );
}

export default App;
  1. launch backend and frontend by opening two terminal instances. In the first one you need to run cd backend && pnpm run start:dev and in the second one cd frontend && pnpm run dev.
  2. open the URL http://localhost:3000 in you browser and you should see the response from the backend application which is Hello World!.

Launching backend and frontend with a single command

In the beginning we installed the library concurently. Now we can make use of it to create a script which launches the backend and the frontend via a single command. In order to achieve this, add a script section to your root package.json which looks like this:

{
  ...
  "scripts": {
    "dev": "concurrently \"yarn dev:frontend\" \"yarn dev:backend\"",
    "dev:frontend": "cd frontend && yarn start",
    "dev:backend": "cd backend && yarn start:dev"
},
  ...
}

Running pnpm run dev from the root of your repository will now launch both applications in a single terminal instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment