问题
When bundling js for React Native using ClojureScript I got the following error. It seems that node runs out of memory when bundling the javascript bundle. This is probably more likely to happen when using ClojureScript since the resulting js files are generally bigger than vanilla js.
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
<--- Last few GCs --->
152689 ms: Mark-sweep 1369.3 (1434.8) -> 1362.8 (1434.8) MB, 2794.5 / 0 ms [allocation failure] [GC in old space requested].
155498 ms: Mark-sweep 1362.8 (1434.8) -> 1362.9 (1434.8) MB, 2808.4 / 0 ms [allocation failure] [GC in old space requested].
158508 ms: Mark-sweep 1362.9 (1434.8) -> 1362.8 (1434.8) MB, 3010.8 / 0 ms [last resort gc].
161189 ms: Mark-sweep 1362.8 (1434.8) -> 1362.8 (1434.8) MB, 2680.5 / 0 ms [last resort gc].
<--- JS stacktrace --->
==== JS stack trace =========================================
Security context: 0xd4b9fdc9e59 <JS Object>
1: visitQueue [/Users/myproj/node_modules/babel-traverse/lib/context.js:~130] [pc=0x3e89a3f7bd28] (this=0x24a5ec659101 <a TraversalContext with map 0x157972399611>,queue=0x24a5ec659149 <JS Array[1]>)
2: node [/Users/myproj/node_modules/babel-traverse/lib/index.js:~150] [pc=0x3e89a3e4f23a] (this=0x387a6b7f4301 <JS Function traverse (SharedFunction...
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
<--- Last few GCs --->
238422 ms: Mark-sweep 1364.8 (1434.8) -> 1364.8 (1434.8) MB, 3377.7 / 0 ms [allocation failure] [GC in old space requested].
241834 ms: Mark-sweep 1364.8 (1434.8) -> 1364.8 (1434.8) MB, 3412.3 / 0 ms [allocation failure] [GC in old space requested].
245313 ms: Mark-sweep 1364.8 (1434.8) -> 1364.8 (1434.8) MB, 3478.7 / 0 ms [last resort gc].
248639 ms: Mark-sweep 1364.8 (1434.8) -> 1364.8 (1434.8) MB, 3326.4 / 0 ms [last resort gc].
<--- JS stacktrace --->
==== JS stack trace =========================================
Security context: 0x266dabec9e59 <JS Object>
1: new constructor(aka NodePath) [/Users/myproj/node_modules/babel-traverse/lib/path/index.js:~61] [pc=0x108980041705] (this=0x1cedf9a7ef69 <a NodePath with map 0x3182f379cf21>,hub=0x266dabe04189 <undefined>,parent=0x3d43337ab49 <a Node with map 0x3182f3798489>)
3: get [/Users/myproj/node_modules/babel-traverse/lib/path/index.js:~87] [pc=0x10898...
[node-haste] Encountered an error while persisting cache:
> Error: Uncaught error in the transformer worker: /Users/myproj/node_modules/react-native/packager/transformer.js
> at _transform.then.catch.error (/Users/myproj/node_modules/react-native/packager/react-packager/src/JSTransformer/index.js:99:31)
> at tryCallOne (/Users/myproj/node_modules/promise/lib/core.js:37:12)
> at /Users/myproj/node_modules/promise/lib/core.js:123:15
> at flush (/Users/myproj/node_modules/asap/raw.js:50:29)
> at _combinedTickCallback (internal/process/next_tick.js:67:7)
> at process._tickCallback (internal/process/next_tick.js:98:9)
/Users/myproj/node_modules/promise/lib/done.js:10
throw err;
^
Error: Uncaught error in the transformer worker: /Users/myproj/node_modules/react-native/packager/transformer.js
at _transform.then.catch.error (/Users/myproj/node_modules/react-native/packager/react-packager/src/JSTransformer/index.js:99:31)
at tryCallOne (/Users/myproj/node_modules/promise/lib/core.js:37:12)
at /Users/myproj/node_modules/promise/lib/core.js:123:15
at flush (/Users/myproj/node_modules/asap/raw.js:50:29)
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
Command /bin/sh failed with exit code 1
回答1:
The solution for iOS is to edit the following file: ios/YourProjectName.xcodeproj/project.pbxproj
and change the following line (~600)
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh";
to
shellScript = "export NODE_BINARY='node --max_old_space_size=4092'\n../node_modules/react-native/packager/react-native-xcode.sh";
回答2:
For android, this can also be set in android/app/build.gradle by adding:
project.ext.react = [
// override which node gets called and with what additional arguments
nodeExecutableAndArgs: ["node", "--max-old-space-size=4096"]
]
note that this must be added above the following line:
apply from: "../../node_modules/react-native/react.gradle"
回答3:
Another workaround is to disable optimizations by setting --dev true
for production builds. This has performance drawbacks, but in my experience they are acceptable. Dev mode also enables a number of runtime checks. You can disable them by changing the DEV constant at the top of the bundle output, like so:
#!/usr/bin/env python
# Patch jsbundle to set __DEV__ to false
import sys, re
print(re.sub(r'__DEV__\s*=\s*true;', "__DEV__=false;",
sys.stdin.read()))
回答4:
I have found way to generate Signed APK in re-natal project.
For this we must edit file in node_modules/react-native/react.gradle
Change 84-th row in this file. From
commandLine(*nodeExecutableAndArgs, "node_modules/react-native/local-cli/cli.js", "bundle", "--platform", "android", "--dev", "${devEnabled}",
"--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraPackagerArgs)
To this
commandLine(*nodeExecutableAndArgs, "--max-old-space-size=4096", "node_modules/react-native/local-cli/cli.js", "bundle", "--platform", "android", "--dev", "${devEnabled}",
"--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraPackagerArgs)
To create production build you must use
lein prod-build
After compiling of ClojureScript use this commands:
cd android && ./gradlew assembleRelease
The generated APK can be found under android/app/build/outputs/apk/app-release.apk
, and is ready to be distributed.
回答5:
For iOS
, with react-native 0.59.0 works by editing on ios/YourProjectName.xcodeproj/project.pbxproj
this line
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh";
with
shellScript = "export NODE_OPTIONS=--max_old_space_size=4096\n../node_modules/react-native/scripts/react-native-xcode.sh";
来源:https://stackoverflow.com/questions/38198511/how-to-prevent-node-from-running-out-of-memory-when-bundling-js-for-react-native