Skip to content

Instantly share code, notes, and snippets.

@jming422
Last active July 29, 2021 03:30
Show Gist options
  • Save jming422/4d2f7cc1dc4336ce5ce2bf7d16dea9b4 to your computer and use it in GitHub Desktop.
Save jming422/4d2f7cc1dc4336ce5ce2bf7d16dea9b4 to your computer and use it in GitHub Desktop.
Layout for sharing JS code between Create React App and a Node.js backend

This was written based off of https://docs.npmjs.com/cli/v7/using-npm/workspaces and using node v14.17.3 and npm 7.19.1.

Directory structure

I'm gonna use an example that's structured in a familiar way:

  • Create React App in /src
  • Backend server in /server
  • Shared code in /myproj-lib

Except using npm workspaces, we can make the "shared" code (which we've so far only shared between various backend programs) accessible to the frontend too!

Structure overview

myproj
+-- package.json
+-- myproj-lib (shared)
|  +-- package.json
|  `-- index.js
+-- server (backend)
|  `-- index.js
`-- src (frontend)
   +-- package.json
   `-- App.js

./package.json

The main package.json is the same as our usual with only one difference - the workspaces entry that contains the name of the directory that will hold our shared code.

{
  "name": "myproj",
  "type": "module",
  "workspaces": ["myproj-lib"],
  "dependencies": {
    "depsForBackend": "here",
    "depsForSharedLib": "here",
    "frontendCanUseTheseLibsToo": "sure I guess"
  },
  "devDependencies": {
    "frontendOnlyDependencies": "here"
  }
}

src/package.json

This should be familiar. It's required in order to let us write the backend in module syntax while still compiling the frontend with CRA's regular build command.

{
  "type": "commonjs"
}

myproj-lib/package.json

This file plus the workspaces entry in the top-level package.json are the magic sauce. This file turns this directory myproj-lib into a "standalone" npm module. The private flag ensures that this module isn't publishable or anything; it's purely for use within the scope of this one project.

{
  "name": "myproj-lib",
  "private": true,
  "type": "module",
  "main": "index.js"
}

Usage

And after an npm install that's all the config necessary! Now you can write shared code in /myproj-lib. Since index.js is the "main" file, you'll have to export anything you want to use out of there. Obviously you could write code right in index.js, but if you put it in other files in that directory, it shouldn't be that bad to use re-exports to get it exported out of index.js.

The last thing to know: when you want to import the shared code, do NOT import it as a directory, like import * from '../myproj-lib/index.js'. Instead, import it like a module, like:

import * as lib from "myproj-lib";

And that will work in both the frontend and backend!

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