4
votes

In my project i have the following folder/project structure.

Project
├── client (create-react-app)
│   ├── tsconfig.json
│   └── packages.json
├── server
│   ├── tsconfig.json
│   └── packages.json
└── shared
    ├── tsconfig.json
    └── packages.json

The shared project is mostly interface/class type declarations that i use in both the front and backend so they use the same object type.

I was including the shared project in both client and server using the referenced projects from typescript.

tsconfig.json

...
},
  "references": [
    {
      "path": "../shared"
    }
  ],

Although upon trying to use one of the imported types in a useReducer hook:

Component in client/src

import React, { useReducer, useEffect } from 'react';
import { IRoadBook, GetNewRoadBook} from '../../../shared/src/types/IRoadBook';
import { Grid, TextField, Button } from '@material-ui/core';
import { useParams } from 'react-router-dom';

type State = {
    RoadBook: IRoadBook | any;
}
export default function RoadBookEditor() {
    const { objectId } = useParams();
    const [state, dispatch] = useReducer(reducer, {RoadBook : GetNewRoadBook()});
....

The following error happens upon starting the project : "Module not found: You attempted to import ../../../shared/src/types/IRoadBook which falls outside of the project src/ directory. Relative imports outside of src/ are not supported."

Which from what i read is a limitation imposed by create-react-app configurations.

If i do

const [state, dispatch] = useReducer(reducer, {RoadBook :{}});

Code builds/runs successfuly. (causes visual issues down the road but that is not the point of this question).

Question : What is the proper way to include this shared project in my create-react-app client project?

shared/types/IRoadBook.tsx

export interface IRoadBook {
        _id: string;
        Name: string;
        Description: string;
}

export function GetNewRoadBook(): IRoadBook {
        return { _id: '', Name: '', Description: '' } as IRoadBook;
}
1
The path of least resistance is to make the shared stuff a separate repo and install it to both projects using npm with a git url.Jared Smith
@JaredSmith was afraid something like that would be the answer, feels like overkill in this situation since this is only a little side project to learn my way around react/nodejs. Thanks though.Amgg
It isn't overkill really: just make a separate repo on your local machine and install it to your projects via npm. You don't have to publish it or anything. I understand your frustration at not being able to use what comes across at first glance as a reasonable project structure, but when learning a tech stack always be open to the possibility that if the tools won't let you do something that maybe the tool is right and your first impression was wrong. That won't always be the case, but keep an open mind.Jared Smith

1 Answers

0
votes

If I understood correctly what you're looking for is a monorepo setup. Out of the box create-react-app does not support importing code from outside your source folder. To achieve it you need to modify the webpack config inside it, and there are a couple of alternatives for that: 1- Using something like customize-cra, craco, etc. 2- forking CRA and modifying react-scripts (https://create-react-app.dev/docs/alternatives-to-ejecting/) 3- Ejecting and modifying the webpackconfig

for 2 and 3, you'll need to remove ModuleScopePlugin from webpack config and add the paths to babel-loader.

A few other places you can get a direction: Create React App + Typescript In monorepo code sharing https://blog.usejournal.com/step-by-step-guide-to-create-a-typescript-monorepo-with-yarn-workspaces-and-lerna-a8ed530ecd6d