Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ern run-ios failing with mkdirp error #1891

Open
fhkarczeski opened this issue Apr 13, 2023 · 3 comments
Open

ern run-ios failing with mkdirp error #1891

fhkarczeski opened this issue Apr 13, 2023 · 3 comments

Comments

@fhkarczeski
Copy link

fhkarczeski commented Apr 13, 2023

Hello everyone,

Starting last Monday April 10 we noticed that existing apps can no longer run locally on iOS. Running the ern run-ios command gives this error:

✔ Booting iOS Simulator 0s
✖ Building iOS Runner project 36s
✖ An error occurred: iOS Runner build failed [xcbuild exit code 65].
✖ To troubleshoot this build failure, we recommend building the Runner iOS project from Xcode.
✖ You can open the Runner project in Xcode manually or by running 'open ios/ErnRunner.xcodeproj'.
✖ Building the Runner from Xcode will provide more meaningful error reporting that can be of help
✖ to pinpoint the cause of the build failure.

I tried to build the .xcworkspace on Xcode and I got this error:

/.ern/containergen/out/ios/node_modules/react-native/scripts/generate-specs-cli.js:47
  mkdirp.sync(outputDirectory);
         ^

TypeError: mkdirp.sync is not a function
    at generateSpec (/.ern/containergen/out/ios/node_modules/react-native/scripts/generate-specs-cli.js:47:10)
    at main (/.ern/containergen/out/ios/node_modules/react-native/scripts/generate-specs-cli.js:91:3)
    at Object.<anonymous> (/.ern/containergen/out/ios/node_modules/react-native/scripts/generate-specs-cli.js:94:1)
    at Module._compile (node:internal/modules/cjs/loader:1126:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1180:10)
    at Module.load (node:internal/modules/cjs/loader:1004:32)
    at Function.Module._load (node:internal/modules/cjs/loader:839:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:17:47
Command PhaseScriptExecution failed with a nonzero exit code

Looking at the generate-specs-cli.js file, I see that it is requiring mkdirp, this is the line requiring the library:
const mkdirp = require('mkdirp');

Looking into the mkdirp library it is loading, I see that it is exporting this:

export const mkdirp = Object.assign(async (path, opts) => {
    path = pathArg(path);
    const resolved = optsArg(opts);
    return useNative(resolved)
        ? mkdirpNative(path, resolved)
        : mkdirpManual(path, resolved);
}, {
    mkdirpSync,
    mkdirpNative,
    mkdirpNativeSync,
    mkdirpManual,
    mkdirpManualSync,
    sync: mkdirpSync,
    native: mkdirpNative,
    nativeSync: mkdirpNativeSync,
    manual: mkdirpManual,
    manualSync: mkdirpManualSync,
    useNative,
    useNativeSync,
});
//# sourceMappingURL=index.js.map

So the mkdirp object being imported is actually mkdirp.mkdirp.sync, I can fix it either by fixing the sync call or the require like const { mkdirp } = require('mkdirp');.
If I make either change above and rebuild it with Xcode, it runs the application correctly. But if I run the ern run-ios command again, it overrides the changes and breaks again. This miniapp was running correctly last Friday, April 7, and all of our miniapps stopped working on the following Monday. I haven't seen any change on Electrode that could've caused this error, and we haven't changed our apps either. This has happened to multiple devs, so it's does not seem like a local machine issue.

Does anyone have any ideas of what could be happening?
ern version: v0.50.1
miniapp react native version: 0.66.5
node: v16.17.0
npm: 8.15.0

@fhkarczeski
Copy link
Author

fhkarczeski commented Apr 14, 2023

I seem to have found the issue, but I am still tracing why it is happening. When the iOS container is generated, it is not installing the correct dependencies from the package.json file. The file /.ern/containergen/out/ios/yarn.lock actually says that mkdirp is a dependency of metro:

[email protected], metro@^0.66.1:
  version "0.66.2"
  resolved "https://registry.yarnpkg.com/metro/-/metro-0.66.2.tgz#f21759bf00995470e7577b5b88a5277963f24492"
  integrity sha512-uNsISfcQ3iKKSHoN5Q+LAh0l3jeeg7ZcNZ/4BAHGsk02erA0OP+l2m+b5qYVoPptHz9Oc3KyG5oGJoTu41pWjg==
  dependencies:
    ...
    **mkdirp "^0.5.1"**
    ...

The metro-cache package specifies the same dependency. And the yarn.lock file actually shows the correctly resolved dependency:

mkdirp@^0.5.1:
  version "0.5.6"
  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
  integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
  dependencies:
    minimist "^1.2.6"

However, when the container generation finishes, the actually installed version of mkdirp is 3.0.0, which removed the default exports. So at some point the container generation for iOS is installing the wrong dependency, and that is what is breaking everything. If we run yarn install after the initial creation of the container, and then start the iOS emulator, it also works without a problem. I will keep debugging to see where the mismatch is happening.

@Karthiccc23 @friederbluemle any ideas on where to look?

@fhkarczeski
Copy link
Author

Seems like the correct version of mkdirp (0.5.6) gets installed briefly, then it gets overwritten by the pod install command:

✔ Running pod install --verbose 7s

The pod install command is removing the existing one and installing the latest version.

@fhkarczeski
Copy link
Author

fhkarczeski commented Apr 14, 2023

The issue is happening on the IosGenerator.ts file. For our version of RN (0.66.5), it is using the code react-native-codegen. After the pod install command runs, the generator is removing all libraries that are not RN related. This removes the correct mkdirp module.

Later during the react-native-codegen function, it manually adds the mkdirp dependency again without checking the required version on the main packages.json file. At this point the latest version of the mkdirp library that contains breaking changes is added and then merged into the node_modules folder.

Would it be better to not remove the mkdirp library from the initial node_modules or to ensure we check for a particular version on the package.json file to install the correct version (if one exists)?
@friederbluemle @belemaire @Karthiccc23

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant