Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React + backend - project structure when sharing code

Tags:

I really like the folder structure as can be seen here when dealing with a React frontend and a some backend with express:

root ├── backend |   ├── node_modules |   ├── public |   ├── src │   │   └── Server.ts |   ├── package.json |   └── tsconfig.json ├── frontend (created using create-react-app) |   ├── node_modules |   ├── public |   ├── src │   │   └── Index.js |   ├── package.json |   └── tsconfig.json 

I think that having separate packages with individual node_modules is reasonable since the frontend and backend are basically completely different things, e. g. they need different node modules. Also, this modular approach is visually appealing to me and the repository looks tidy.


However, I encounter a problem with this structure when I need to share content between the frontend and the backend. I added a shared folder under the root-of-project which contains its own project with its own tsconfig.json, package.json and so on. This approach is a mix of the approaches here and here. For the backend, this works totally fine: having set up the tsconfig.json appropriately (using TypeScript Project References and aliased imports), I can reference the file root/shared/src/myFile.ts like this:

import { myFunction } from @shared/myFile; 

I created the React frontend using create-react-app. It's ok for me that alias imports don't work, so I would have to use (inside the src folder in frontend):

import { myFunction } from '../../shared/src/myFile'; 

Sadly, these imports from outside the src directory are not supported by create-react-app and I don't want to use eject since I have no experience with webpack and don't want to maintain all the configuration files on my own (that's why I used create-react-app in the first place).


I know I can move the shared content to the frontend's src directory. But this would mean, I had to add the tags needed for using Project References in TypeScript, e. g. setting composite to true, in the frontend's tsconfig.json which seems odd to me and feels more like a hack. I'd like to have a separate npm project with my shared content.

Since create-react-app does not inherently support imports from outside the src directory, I thought that maybe I'm getting the big picture wrong. Isn't the folder structure I use right now a valid way of how to setup a React project with a backend? What mechanism does create-react-app provide to link files between the frontend and the backend? I could also think of having a root project with a src folder and inside of that the two folders backend and frontend. But this means, that we'd have one shared node_modules folder in root.

It's my first project with React and I'd love to get to know some best practicese for this kind of architectural problem. Some links to trustful resources where project structures for full-stack React development are explained would be really helpful. Thank you 😊

like image 444
Splines Avatar asked Jan 03 '20 00:01

Splines


People also ask

How do you organize the structure of backend and frontend in Mern?

concurrently allows you to start both your frontend and backend at the same time. I suggest initializing a new Node project inside of the top-level root folder -[folder which contains both, your frontend and backend]. You would do that with the npm init command, and after that, install the concurrently package there.


1 Answers

It's perfectly reasonable to want to share code between your front and back end. It's one of the reasons to code in javascript instead of Ruby or PHP.

You can accomplish exactly what you want by using yarn instead of npm and yarn workspaces: https://yarnpkg.com/lang/en/docs/workspaces/. At the top level you set up three modules/packages in your package.json (make sure you name the workspaces correctly in their respective package.json files):

"workspaces": {     "packages": [         "backend",         "frontend",         "shared"     ] }, 

Once you do, you can import shared code in your CRA app or your back end simply like this:

import { myFunction } from 'shared/src/myFile'; 

The only drawback is that you can't import react components from the shared directory into frontend as long as you are using CRA. This won't affect you now since you only have one react app. Should you need to share react components among multiple projects, look into some on the suggestions above like bit.dev.

This isn't the only way, but it's among the simplest and most straight forward.

like image 100
Robert Moskal Avatar answered Sep 24 '22 15:09

Robert Moskal