Shared code between api and web

I have a shared code folder (‘config/’) that’s a peer of api and web and imported by each. I noticed it’s not being transpiled from es6 modules (and thus throwing errors). I see the passage about overriding webpack config for web, https://redwoodjs.com/guides/webpack-config.html#overriding-webpack-config, but what about api side, is typescript transpiling that?

Also, I’d like to be able to import from this shared folder like the current ‘src/’ imports set up for both api and web.

Any tips for achieving this or am I swimming upstream by having this shared code folder outside of api and web?

Since we’re using yarn workspaces I would recommend creating a new folder called “packages/” in the root and create a shared npm package in that folder.

You can then install and import that package. Let me know if you need a more detailed explanation. We should create a guide for this.

2 Likes

Ah, got it - thanks. That makes sense.

One final thing to make this perfect for development: I’m at a loss on how to get both api and web to auto-reload the shared code. Any pointers or easy things I’m missing here? I’ve yarn linked the local package into both api and web, but when api or web reload, code changes in the shared code are not loaded.

We don’t have a good path for this yet, but we should add one we when add the guide.

A “poor hack” could be to run nodemon: yarn nodemon -w packages/--exec 'touch api/src/functions/graphql.ts; touch web/src/Routes.js'

You could do that in a separate process and run yarn rw dev in another. Any changes to your package will cause a reload of the api and web server.

1 Like

Here’s another suggestion by @chris-hailstorm that I think is a lot easier:

I would go for the babel.config.js route since you’re targeting both sides. This still wouldn’t reload the sides, but we’ll come up with an official way of doing this.

Ah many thanks for the link - the webpack config may serve my purposes better. I’ll try it out.

FWIW, this babel config almost gets me there. I can import from ‘@sharedcode’ in both web and api. web reloads on any change, but api does not as you mentioned. Currently running a separate nodemon watch that you posted above.

module.exports = {
  presets: ['@redwoodjs/core/config/babel-preset'],
  plugins: [
    [
      'module-resolver',
      {
        alias: {
          '@sharedcode': '../sharedcode',
        },
      },
    ],
  ],
}
1 Like

I’d love a guide for this even if it is just a simple cliff notes version. This is my first usage of workspaces so most of the concepts are new to me.

@peterp curious if the babel-plugin-module-resolver we’re already using might be able to help on the API side of things?

I think this is what they’re using above, but our “watch code” for the api-server only reloads if a file in ./api changes. It doesn’t have a map of all imported files and reload if any of those changes. I’m planning on seperating the “watch and reload” part from the “dev-server” part which will make this possible.

1 Like

@thedavid

Do you agree the shared types folder as described here[1] and [2] should be added to the docs here [3] ?

Rhetorical Question: do you think having two folders named types so close to each other may be confusing at some point?

Realistic Answer: well how much code do you want to break to avoid that confusion?

1: Using typescript types after modifying api/src/graphql/*.sdl.ts - #2 by danny

2: Using typescript types after modifying api/src/graphql/*.sdl.ts - #16 by danny

3: Redwood File Structure | RedwoodJS Docs

Cheers !!

Al;

Typescript is happy in both my api and web sides - but the app won’t run

web page shows:

Compiled with problems:X

ERROR in ./src/pages/ViewOnPhonePage/ViewOnPhonePage.tsx 7:0-60

Module not found: Error: Can't resolve 'types/submit-alt-id' in '/Users/ajoslin/Documents/Als/Development/EPC/Development/print-on-demand-2/web/src/pages/ViewOnPhonePage'

console log says:

web | ERROR in ./src/pages/ViewOnPhonePage/ViewOnPhonePage.tsx 7:0-60
web | Module not found: Error: Can't resolve 'types/submit-alt-id' in '/Users/ajoslin/Documents/Als/Development/EPC/Development/print-on-demand-2/web/src/pages/ViewOnPhonePage'
web | resolve 'types/submit-alt-id' in '/Users/ajoslin/Documents/Als/Development/EPC/Development/print-on-demand-2/web/src/pages/ViewOnPhonePage'
web |   Parsed request is a module
web |   using description file: /Users/ajoslin/Documents/Als/Development/EPC/Development/print-on-demand-2/web/package.json (relative path: ./src/pages/ViewOnPhonePage)
web |     Field 'browser' doesn't contain a valid alias configuration
web |     resolve as module
web |       /Users/ajoslin/Documents/Als/Development/EPC/Development/print-on-demand-2/web/src/pages/ViewOnPhonePage/node_modules doesn't exist or is not a directory
web |       /Users/ajoslin/Documents/Als/Development/EPC/Development/print-on-demand-2/web/src/pages/node_modules doesn't exist or is not a directory
web |       /Users/ajoslin/Documents/Als/Development/EPC/Development/print-on-demand-2/web/src/node_modules doesn't exist or is not a directory
web |       looking for modules in /Users/ajoslin/Documents/Als/Development/EPC/Development/print-on-demand-2/web/node_modules
web |         /Users/ajoslin/Documents/Als/Development/EPC/Development/print-on-demand-2/web/node_modules/types doesn't exist
web |       looking for modules in /Users/ajoslin/Documents/Als/Development/EPC/Development/print-on-demand-2/node_modules
web |         /Users/ajoslin/Documents/Als/Development/EPC/Development/print-on-demand-2/node_modules/types doesn't exist
web |       /Users/ajoslin/Documents/Als/Development/EPC/Development/node_modules doesn't exist or is not a directory
web |       /Users/ajoslin/Documents/Als/Development/EPC/node_modules doesn't exist or is not a directory
web |       /Users/ajoslin/Documents/Als/Development/node_modules doesn't exist or is not a directory
web |       /Users/ajoslin/Documents/Als/node_modules doesn't exist or is not a directory
web |       /Users/ajoslin/Documents/node_modules doesn't exist or is not a directory
web |       /Users/ajoslin/node_modules doesn't exist or is not a directory
web |       /Users/node_modules doesn't exist or is not a directory
web |       /node_modules doesn't exist or is not a directory
web |  @ ./src/Routes.tsx 110:0-70 206:10-25
web |  @ ./src/App.tsx 8:0-30 37:39-45
web |  @ ../node_modules/@redwoodjs/web/dist/entry/index.js 9:45-73
web |

moving my questions to

Cheers!
Al;

Ah, great question. Currently we don’t mention anything about the .redwood directory or it’s contents. I think that a high-level explanation about this would be very appropriate in that section of the Tutorial.

1 Like

Frankly it’s a huge benefit for me, if I could get it to work. It did not work for me to put some .ts files there – while the api and web side don’t “complain” (via errorLens) during development - the web side doesn’t work at runtime, says it can’t resolve the files

I think there is some confusion – I’m talking about the /types folder as a sibling to /api and /web

it’s listed in the .tsconfig files in /api and /web

AND there is an /api/types folder

This might be a stupid question, but why not simply create a symlink?

cd api/src/lib
ln -s ../../../web/lib/myLib ./myLib

And that’s about it. Along with the already shared types in /types, this is working great for me.