mikehardy/jetifier

add support to monorepo

sibelius opened this issue · 15 comments

it would be cool to run jetify on all node_modules of a yarn monorepo

This sounds good but I have zero experience with monorepos. If I could see a PR I could say more ?

we need to modify here

const SEARCH_DIR = 'node_modules';

in a monorepo you have

node_modules
packages

  • packageA
    • node_modules
  • packageB
    • node_modules

we can use this package https://github.com/viewstools/yarn-workspaces-cra-crna/tree/master/get-yarn-workspaces to find all packages folder and search node_modules from there

We have a monorepo structure in our project. In order to apply to all packages. We added jetifier to the top-level package.json and added the postinstall script to call it. It goes and updates all files in the packages as well as the ones in the root-level node_modules.

I'm curious to know why it didn't work for you @sibelius

@andresesfm could you possibly add more info about how you were able to get this to work?

I have a RN monorepo, using yarn workspaces

  1. at root level yarn add -D jetifier -W (added jetifier to top level package.json, like you said)

  2. npx jetify (also run from root level)
    output: Jetifier found 1061 file(s) to forward-jetify. Using 8 workers...

  3. npx react-native run-android (from root)
    output: error Android project not found. Are you sure this is a React Native project?

  4. yarn workspace MyProject android
    output:

info Running jetifier to migrate libraries to AndroidX. You can disable it using "--no-jetifier" flag.
Jetifier found 0 file(s) to forward-jetify. Using 8 workers...

...

FAILURE: Build failed with an exception.

* Where:
Settings file '/Users/me/workspace/react-native/MyMonorepo/packages/MyProject/android/settings.gradle' line: 4

* What went wrong:
A problem occurred evaluating settings 'MyProject'.
> Could not read script '/Users/me/workspace/react-native/MyMonorepo/packages/MyProject/node_modules/@react-native-community/cli-platform-android/native_modules.gradle' as it does not exist.

It seems like I can run npx jetify and it produces a list, but it can't actually be run in a way to make changes to files.

Do you have any detailed steps for what you ran to install and then run jetify in the monorepo where it is successful?

the root of your monorepo is not a valid react-native project is it?

my react-native chunk of my monorepo is for instance zzz/packages/public-app

so you can install jetifier wherever you want, it should still work as long as it is executed at the level of your react-native app sometime before gradlew is called by the react-native CLI (which should happen automatically with current react-native CLI

And to start react-native you'd still need to move into the actual package that holds the thing and run it I think? Since the CLI depends on jetifier now, it will likely already be there and already run it for you, so I didn't think anything special was required for anyone nowadays?

FWIW, I only have jetifier installed in the one part of my monorepo where I have a react-native app, and I run it down there at that package level

BTW - I agree in general adding support for monorepos so it runs at top-level and all the way down would be great as I've converted to a monorepo, but in the meantime it does work per-package - where ever you run it, it will convert everything in the node_modules directory where you are

Here is a temp workaround.
#60 (comment)

@mikehardy the solution described here is not suitable for monorepo structure with hoist that all the packages are in the root node_modules, the only way I could make it work is by editing the SEARCH_DIR to const SEARCH_DIR = '../../node_modules';.

@RahavLussato would another possible solution be to have it in the monorepo root with a call to jetifier in postinstall there?

@mikehardy which command I should run in post install ? I tried running ‘npx jetify’ from the root but it didn’t work, i got the same as @octopicorn described.

I don't know if I'm just being dense or what but I really don't understand.
A monorepo, at it's core, is just a folder, with a node_modules folder in it, and then sub-folders, where those can have node_modules in them.

In any of the node_modules folders, there could be java code or xml files with non-androidx references

jetifier just looks for "./node_modules" and will transform java code or XML

That is literally all there is to it.

So, where ever you may have a "node_modules" sub-folder that is not automatically handled, install jetifier and run it on postinstall.

Where ever you might start an android app, do what you would normally do?

There is not some fancy state machine built in to jetifier that is hard to work around or makes a bunch of assumptions.

And for the react-native CLI when you run-android you can disable jetifier there, so it is under manual control

I am not seeing anything that needs to happen here in the module yet. I am seeing an integration issue in local projects.

@mikehardy i understand what you say, maybe I missed something I'll check it again.
There is still a case where you have packages installed on both the root node_modules and the sub package one so there is a need for traverse on that case and also the post install workaround might work but the fact that it's not automatically support it and a user with monorepo structure should change the basic auto flow of react native run, in my opinion, worth to add the traverse option.

I do not disagree completely but I do hesitate to alter this package for niche use cases (I use a monorepo too, and we have to admit we are niche cases...) when it's used by so many. I am much much more interested in getting the rest of the ecosystem across the AndroidX transition by fixing the packages that still aren't AndroidX so this package can die a peaceful death really.

To that end, it might be more productive to patch the modules that aren't fixed yet, by issuing PRs to them and using patch-package in the meanwhile. There can't be that many left? I think I'm down to one, actually.

I share another solution

json .... "android": "yarn jetify&&react-native run-android --no-jetifier", "jetify": "yarn --cwd ../../../ jetify",

We should all be using --no-jetifier in our builds (I am, successfully) at this point, and this repo should be sunset, I don't expect to make further changes in it