IjzerenHein / react-native-bundle-visualizer

See what packages are increasing your react-native bundle size 📦
MIT License
1.43k stars 42 forks source link

Support Yarn monorepo context #69

Closed Braden1996 closed 2 years ago

Braden1996 commented 2 years ago

With Yarn, the React Native binary is hoisted from the individual workspace to the repository root. Hence this command fails in such an environment, as the binary isn't located in the fixed path described here.

The proposed change resolves the React Native binary's location via Node mechanisms.

IjzerenHein commented 2 years ago

Hi! Thanks for the contribution. I've tried verifying this locally but it seems to break the tests, because require.resolve searches for packages that are installed in the same location that react-native-bundle-visualizer is installed.

I've done some experimentation and came up with this solution:

function getReactNativeBin() {
  const localBin = './node_modules/.bin/react-native';
  if (fs.existsSync(localBin)) return localBin;
  try {
    const reactNativeDir = path.dirname(
      require.resolve('react-native/package.json')
    );
    return path.join(reactNativeDir, './cli.js');
  } catch (e) {
    console.error(
      chalk.red.bold(
        `React-native binary could not be located. Please report this issue with environment info to:\n`
      ),
      chalk.blue.bold(`-> ${require('../package.json').bugs}`)
    );
  }
}

...

const reactNativeBin = getReactNativeBin();

It then first searches the cwd node_modules folder, and then tries resolving using require.resolve. Would that work for you as well?

Braden1996 commented 2 years ago

Hi! Thanks for the contribution. I've tried verifying this locally but it seems to break the tests, because require.resolve searches for packages that are installed in the same location that react-native-bundle-visualizer is installed.

I've done some experimentation and came up with this solution:

function getReactNativeBin() {
  const localBin = './node_modules/.bin/react-native';
  if (fs.existsSync(localBin)) return localBin;
  try {
    const reactNativeDir = path.dirname(
      require.resolve('react-native/package.json')
    );
    return path.join(reactNativeDir, './cli.js');
  } catch (e) {
    console.error(
      chalk.red.bold(
        `React-native binary could not be located. Please report this issue with environment info to:\n`
      ),
      chalk.blue.bold(`-> ${require('../package.json').bugs}`)
    );
  }
}

...

const reactNativeBin = getReactNativeBin();

It then first searches the cwd node_modules folder, and then tries resolving using require.resolve. Would that work for you as well?

Hey @IjzerenHein, I tested this locally in my repo and it seems to do the trick. Apologies for not considering the test cases with my initial PR.

IjzerenHein commented 2 years ago

Great, glad to hear that works. I'll see to it this gets merged shortly 👍

IjzerenHein commented 2 years ago

Released as https://github.com/IjzerenHein/react-native-bundle-visualizer/releases/tag/v3.1.0 👍