Redwood: Cookbook about sharing code between api and web side

Created on 12 May 2020  ·  9Comments  ·  Source: redwoodjs/redwood

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.

docs

Most helpful comment

Hey @noire-munich,

You could modify the netlify build command to also build your package:

[build]
  command = "NODE_ENV=production yarn rw db up --no-db-client --auto-approve && yarn rw build && cd mypackage; yarn build"
  # ... rest of toml ...

I added && cd mypackage; yarn build

All 9 comments

@peterp Is it necessary to make the shared code an npm package? For a while now I've had a shared code folder at the same level as web and api (mine is uti for utilities) -- all I've had to do is add a path alias in my web/config/webpack.config.js like this:

module.exports = (config, { env }) => {
  config.resolve.alias['@uti'] = path.join(redwoodPaths.base, 'uti')

And then import the shared code by path like this:

import { enviro } from '@uti/netlify'

Webpack handles all the packaging. A lot easier than the npm packaging lifecycle.

@chris-hailstorm That's a great solution and probably a lot easier than the route I was suggesting. Another way to do this, for both sides, could be by specifying it as an alias in babel.config.js

One of the reasons why I like to share packages is because that's the natural way of sharing code in the node ecosystem and I try not to stray too far from that path, since you may want to share this package outside of your project eventually.

@peterp I'd use the package approach if shared stuff is bigger / reusable, agree with you there.

And if it's smaller (one-off functions, regexes, constants) -- I'd probably not package it.

As usual, developer judgment is involved!

@chris-hailstorm thanks a lot for your solution, I stumbled upon this for days ><.
I can get it to work on the web side no problem but not on the API, odd enough as my api webpack configuration is rather thin:

const { getPaths } = require('@redwoodjs/internal')
const path = require('path')

module.exports = (config) => {
  // Module working alias.
  config.resolve.alias['@shared'] = path.join(getPaths().base, 'shared/dist')

  return config
}

Did you have any issue on any of the sides? It's working well on the web side for me.

@noire-munich I was able to make it work on the API side with changing root babel.config.js and using part of your config (thanks!):

const path = require('path')
const { getPaths } = require('@redwoodjs/internal')

module.exports = {
  presets: ['@redwoodjs/core/config/babel-preset'],
  plugins: [
    [
      require.resolve('babel-plugin-module-resolver'),
      {
        alias: {
          common: path.join(getPaths().base, 'common')
        },
      },
    ],
  ],
}

You'll need to run yarn add -D babel-plugin-module-resolver -W at the root level to install required babel plugin.

Thanks for the info, @krinoid !
I got it to work on both sides as well, but it crashed my deploys ><.

My shared package is as the project's root directory and is a typescript package, locally it runs just fine but on netlify it needs to be babelled to ./dist/*.js.
It works if I commit those dist files but I'm feeling uncomfortable about this. Another way would be to modify the build command, which is cleaner.

I was wondering how you handled this, if you had to at all.

Hey @noire-munich,

You could modify the netlify build command to also build your package:

[build]
  command = "NODE_ENV=production yarn rw db up --no-db-client --auto-approve && yarn rw build && cd mypackage; yarn build"
  # ... rest of toml ...

I added && cd mypackage; yarn build

Hi @peterp !
Thanks! I ended up doing this indeed, actually I added a script to the root package.json and the build command calls it.

This is very convenient for prod build, is there some sort of equivalent to modify the dev command? It would let me have this extra package being watched along the sides of the application.

@noire-munich That's something that I want to add:

In the meantime you could do something like: https://github.com/redwoodjs/redwood/blob/b72db535c84a0656a28d1fa2dd2a9460d3bfd78f/packages/api/package.json#L41

Was this page helpful?
0 / 5 - 0 ratings