metro: Out of memory or out of time when compiling large JS files

Do you want to request a feature or report a bug? Bug.

What is the current behavior? Metro will either run out of memory or it will give up after 5 minutes of waiting to transform the JS file.

This was first reported here https://github.com/facebook/react-native/issues/8475 and then again here https://github.com/facebook/react-native/issues/12590

If the current behavior is a bug, please provide the steps to reproduce and a minimal repository on GitHub that we can yarn install and yarn test. I have a repro repo here https://github.com/jeaye/react-native-packager-bug – it’s not in the yarn format, since I don’t know what that is.

What is the expected behavior? The transformation completes in a timely fashion or metro waits long enough for the transformation to finish in however long it needs. In order to achieve the latter, my production build script currently contains the following:

metro=../node_modules/metro-bundler/src/JSTransformer/index.js
sed -i 's/\(TRANSFORM_TIMEOUT_INTERVAL\) = .*;/\1 = 901000;/g' "$metro" || true

Please provide your exact Metro configuration and mention your Metro, node, yarn/npm version and operating system.

React Native: 0.50.4 babel-preset-react-native: 4.0.0 Metro (comes with RN): 0.20.3 Node: 9.3.0 OS: Arch Linux x86_64

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 10
  • Comments: 25 (6 by maintainers)

Most upvoted comments

@roesneb It certainly shouldn’t be closed. It was ignored when it was reported, multiple times, in the react native repo, while people suggested it be brought up here. Now that it’s brought up here, it’s promptly closed and no workarounds are available (for people using ClojureScript).

For your problem, you might try ignoring that JSON file using your babelrc. Alas, if it has a common name, then all JSONs with that name will be ignored, which is the last problem about which I asked @rafeca.

Why is this issue closed? I have a json file with 17.4MB. If i require it the bundler crashes and if comment it out everything works fine. This seems to be a common problem. Is there a solution for this issue?

“FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory”

FYI including @boogie666 the RN cljs transformer has been updated to work with the new interfaces in current metro 0.49 : https://gist.github.com/sundbry/55bb902b66a39c0ff83629d9a8015ca4

@ChadHarrisVerr Nope, this is still very much an issue. metro doesn’t handle large files well and has a non-linear time growth with respect to file size. So far, there’s been no official way to speed things up and this ticket, just like many others here and in the react-native repo, has been closed with little help (read the full discussion here to understand more, if you haven’t).

I have documented my current workaround here: https://github.com/cljsrn/cljsrn-org/wiki/Avoiding-Metro-timeouts In short, I patch metro to not give up after several minutes of transforming and I just wait a long time for my prod builds. As a result of this, I also can’t reasonably use something like jest for testing, since it wants a bundled package as well.

@rafeca In production, my index.android.js is 1.2MB; these out-of-memory and timeout issues happen even before the 1MB mark though. Why is it that big? Well, it’s a mid-sized application, about 10K LOC of ClojureScript, compiled with Google Closure.

As linked above, this issue is affect basically everyone using ClojureScript with RN, likely due to the CLJS stdlib and everything else included in the compiled file. Note, this is going through Google Closure, so it’s not like there’s a lot of waste here which we can trim down; all dead code is removed and all remaining code is optimized and minified.

Closing this issue because the timeout is removed is ok, but, really, waiting over 5 minutes to transform these files is pretty awful. Trying to do this with a non-production build (which doesn’t have Google Closure optimizations applied) is a fool’s errand, since it’ll take more like 30 minutes, if it doesn’t run out of memory before that.