Search code examples
node.jstypescriptcreate-react-apptsconfigjson-server

Create-React-App while attempting to run a Typescript mock api server (module loading error)


I have a client app created with create-react-app and it uses typescript. My directory structure is like this (apologies if it's confusing):

   -MyApp (folder)
   -node_modules (folder)
   -package.json (has a script that runs the react client app and the mockApi using, 'ts-node mockApi/server.ts')
   -tsconfig.json (this uses module:esnext because apparently CRA requires it?)
   -src (folder)
      -components
      etc.
    
   -MockApi (folder level with MyApp)
   -tsconfig.json (uses module:commonJS for server.ts)
   -server.ts (creates a json-server in express/node using import syntax)
       -mockData (folder)
          -index.ts (gathers domain types into single objects)
          -someEntity.ts (domain type)
   

I have in my main package.json a couple scripts. One runs the command 'ts-node mockData/server.ts' to load my typescript mock api on its own port. The other script runs the normal react-scripts to load the react client on localhost:3000. I'm using a lib that allows scripts in parallel.

Before I added this to my existing app, I created the mock api in its own project with typescript and json-server to ensure it would work, and it did. But the "module" key in the api's tsconfig needs to be "CommonJS" to do the dynamic imports. I figured it would work in a create-react-app project if the mock api had its own tsconfig file set to CommonJS. But the script to load the api causes an error.

When I run it, it says "import xxxx is not a module" (in server.ts). The package.json script is using the tsconfig settings in my main project to load the server.ts file, using "module:esnext", instead of commonJS, as defined in my api tsconfig. How do I tell it to use the settings in the other tsconfig?

Here is my scripts section in my CRA package.json:

    "scripts": {
    "start": "run-p start:dev start:api",
    "start:dev": "cross-env REACT_APP_API_URL=http://localhost:3000 react-scripts start",
    "start:api": "ts-node ./mockApi/server.ts",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },

And the start:api script is where it's blowing up in my server.ts (the first import):

  import jsonServer from "json-server";
  import mockData from "./mockData/index";

Is it just not possible to do what I'm trying to do with create-react-app? I've tried to research this but I cannot find anything that mentions this specific issue. Every json-server example is in JS. But json-server has @types for TS so I don't get why this issue isn't documented. Surely others use Typescript with Json-server and c-r-a.

Thank you


Solution

  • So in case anyone has this question, the answer was to have a script in my ui's package.json that goes to my mock api folder and runs a script in that folder's package.json to start the api, and then run my create-react-app script. So I changed my root/package.json to:

    "scripts": {
        "start:api": "cd mockApi && npm run start",
        "start": "run-p start:api start:dev",
        "start:dev": "cross-env REACT_APP_API_URL=http://localhost:3000 react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
      },
    

    then in my root folder, just run this to kick it off:

    npm run start
    

    And obviously in my mockApi/package.json I have

    "scripts": {
        "start": "ts-node server.ts"
      }
    

    This works great.