dilanx / craco

Create React App Configuration Override, an easy and comprehensible configuration layer for Create React App.
https://craco.js.org
Apache License 2.0
7.43k stars 499 forks source link

Recipe for using with lerna & yarn workspaces? #123

Closed pcmaffey closed 4 years ago

pcmaffey commented 4 years ago

Was under the impression this worked out of the box. But my craco-app is failing to run components from other packages, ie. with same error as standard CRA. Failed to compile. Unexpected token as referenced https://github.com/facebook/create-react-app/issues/1333.

- /packages
    -/craco-app
    -/components
pcmaffey commented 4 years ago

In case anyone comes across this, here's what I ended up doing, using a craco port of https://github.com/react-workspaces/create-react-app/tree/master/packages/react-scripts

// https://github.com/react-workspaces/create-react-app/blob/master/packages/react-scripts/config/yarn-workspaces.js
const yarnWorkspaces = require('./tools/yarn-workspaces')

module.exports = {
  webpack: {
    // get CRA to read from /packages
    // based off https://github.com/react-workspaces/create-react-app/blob/master/packages/react-scripts/config/webpack.config.js
    configure: (webpackConfig, { env, paths }) => {
      const workspacesConfig = yarnWorkspaces.init(paths)
      const dev = env === 'development'
      const prod = env === 'production'
      const workspacesMainFields = [workspacesConfig.packageEntry, 'main']
      const mainFields =
        dev && workspacesConfig.development
          ? workspacesMainFields
          : prod && workspacesConfig.production
          ? workspacesMainFields
          : undefined

      const node_modules = [workspacesConfig.root]
        .concat(workspacesConfig.paths)
        .map(p => p + '/node_modules')

      const modules = Array.from(webpackConfig.resolve.modules).concat(
        node_modules
      )
      // update node_modules paths
      webpackConfig.resolve.modules = modules
      webpackConfig.resolve.mainFields = mainFields

      const include =
        dev && workspacesConfig.development
          ? [paths.appSrc, workspacesConfig.paths]
          : prod && workspacesConfig.production
          ? [paths.appSrc, workspacesConfig.paths]
          : paths.appSrc
      // linter
      webpackConfig.module.rules[1].include = include
      // skip package node_modules from linter
      webpackConfig.module.rules[1].exclude = node_modules
      // loader
      webpackConfig.module.rules[2].oneOf[1].include = include

      return webpackConfig
    },
  },
}
sebastienfi commented 4 years ago

@patricklafrance I would be interested in knowing what you think about this? Also, is there any better recipe for Lerna + Yarn Workspaces + Craco?

patricklafrance commented 4 years ago

Hi @sebastienfi,

Lerna + Yarn Workspaces should work out of the box with CRACO.

Here's the sample project I use to test the feature: https://github.com/patricklafrance/craco-lerna-and-yarn-workspace

Thank you,

Patrick

TCMiranda commented 4 years ago

Hey @patricklafrance I also think that this support should be more clear.

As far as I understood, "siblings" packages won't be compiled by default, but I thought they were after I read the main readme.

In addition to pcmaffey answer, the plugin https://github.com/rjerue/craco-babel-loader seems to be a reasonable approach to include packages paths for babel. I also could use it to transpile typescript with @babel/preset-typescript.


Here's the sample project I use to test the feature: https://github.com/patricklafrance/craco-lerna-and-yarn-workspace

Your test project should include some other package that is referenced by another to better exemplify common use cases on yarn workspaces.


Also for future reference, I'm using react-scripts 2.1. and my workspace looks like:

root/
  package.json
  packages/
    frontend/
      package.json
    shared/
      package.json
    design-system/
      package.json
    ...

Packages include .js and mostly .ts

Thanks all

llamerr commented 3 years ago

Whoever interested in more detailed example with one package referencing the other, you can check these repos. I'm not very proficient in both typescript or webpack configs, so they helped me a lot. https://github.com/tumetus/lerna-cra-typescript https://github.com/floydjones1/monorepo-cra Also IRC, I needed this change to frontend package's tsconfig to make something work (typing?)

"references": [
      {
        "path": "../shared"
      }
    ]