DEV Community

André Castelo
André Castelo

Posted on

CRA 5 + yarn workspaces + shared typescript packages

TL;DR:

  • create-react-app doesn't play nice with shared packages inside a monorepo if you have to compile them (which is the case of my typescript shared types package)
  • craco doesn't work officially with CRA 5, but Craco 7 alpha does, at least it works enough for it to fix this issue.
  • craco config:
const fs = require('fs'); const path = require('path'); const cracoBabelLoader = require('craco-babel-loader'); const appDirectory = fs.realpathSync(process.cwd()); const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath); module.exports = { plugins: [ { plugin: cracoBabelLoader, options: { includes: [resolveApp('../packages')], }, }, ], }; 
Enter fullscreen mode Exit fullscreen mode

This is a quick one. I've been struggling a lot today to use a shared types package in my monorepo. My structure is the following:

/.git /app // react application with CRA 5 /src package.json /gateway /src package.json /packages /types ... package.json package.json 
Enter fullscreen mode Exit fullscreen mode

I'm using:

  • create-react-app 5
  • yarn workspaces
  • typescript

The problem

Here I have my gateway and app both depending on packages/types. While gateway worked fine, app complains that I'm importing files outside of app/src, since this is a limitation in CRA configuration.

The solution

I tried ejecting, but went down a rabbit hole where nothing worked. So I reverted those commits and proceeded with craco@7.0.0-alpha.3. Inside app I ran:

$ yarn add craco@7.0.0-alpha.3 
Enter fullscreen mode Exit fullscreen mode

And then I found this answer from @robertcoopercode, and edited to suit my needs:

const fs = require('fs'); const path = require('path'); const cracoBabelLoader = require('craco-babel-loader'); const appDirectory = fs.realpathSync(process.cwd()); const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath); module.exports = { plugins: [ { plugin: cracoBabelLoader, options: { includes: [resolveApp('../packages')], }, }, ], }; 
Enter fullscreen mode Exit fullscreen mode

Thanks man, you saved my day. Now I'm going to create a ticket to drop create-react-app in favor of next.js, and add it to the next technical debt meeting.

Top comments (0)