Environment
@sayem314/react-native-keep-awake: 2.0.0
react-native: 0.84.0
- Package manager: pnpm (uses symlinked
node_modules)
- Platform: iOS, New Architecture enabled
Issue
iOS build fails in ReactNativeKCKeepAwake.mm:33:
No member named 'NativeKCKeepAwakeSpecJSI' in namespace 'facebook::react'
The generated ios/build/generated/ios/ReactCodegen/ReactNativeKCKeepAwakeSpecJSI.h is empty (just the namespace facebook::react {} shell, no class).
Cause
package.json sets:
"codegenConfig": {
"name": "ReactNativeKCKeepAwakeSpec",
"type": "modules",
"jsSrcsDir": "."
}
With pnpm, node_modules/@sayem314/react-native-keep-awake is a symlink, not a real directory. RN codegen at
react-native/node_modules/@react-native/codegen/lib/cli/combine/combine-js-to-schema.js does:
if (!fs.lstatSync(file).isDirectory()) {
return [file];
}
lstat does not follow symlinks, so for jsSrcsDir: "." the resolved path is the symlink itself, and isDirectory() returns false. Codegen skips the directory scan, never finds
NativeKCKeepAwake.ts, and emits an empty spec header.
Verified locally:
lstat isDirectory: false ← what codegen sees
lstat isSymbolicLink: true
stat isDirectory: true ← reality
This works on npm/yarn (no symlinks) but breaks on pnpm. Other RN modules avoid the issue because their jsSrcsDir is "src", "js", etc. — the resolved path crosses the symlink boundary into a
real subdirectory.
Fix
Move NativeKCKeepAwake.ts (and any other codegen specs) into a src/ subdirectory and change codegenConfig.jsSrcsDir from "." to "src". No code changes needed — purely a layout tweak that
makes the package pnpm-compatible.
Workarounds
pnpm patch @sayem314/react-native-keep-awake to relocate the spec, or
- Set
nodeLinker: hoisted in pnpm-workspace.yaml (pnpm v10+) or node-linker=hoisted in .npmrc (pnpm v9 and earlier).
Environment
@sayem314/react-native-keep-awake: 2.0.0react-native: 0.84.0node_modules)Issue
iOS build fails in
ReactNativeKCKeepAwake.mm:33:The generated
ios/build/generated/ios/ReactCodegen/ReactNativeKCKeepAwakeSpecJSI.his empty (just thenamespace facebook::react {}shell, no class).Cause
package.jsonsets:With pnpm,
node_modules/@sayem314/react-native-keep-awakeis a symlink, not a real directory. RN codegen atreact-native/node_modules/@react-native/codegen/lib/cli/combine/combine-js-to-schema.jsdoes:lstatdoes not follow symlinks, so forjsSrcsDir: "."the resolved path is the symlink itself, andisDirectory()returnsfalse. Codegen skips the directory scan, never findsNativeKCKeepAwake.ts, and emits an empty spec header.Verified locally:
This works on npm/yarn (no symlinks) but breaks on pnpm. Other RN modules avoid the issue because their
jsSrcsDiris"src","js", etc. — the resolved path crosses the symlink boundary into areal subdirectory.
Fix
Move
NativeKCKeepAwake.ts(and any other codegen specs) into asrc/subdirectory and changecodegenConfig.jsSrcsDirfrom"."to"src". No code changes needed — purely a layout tweak thatmakes the package pnpm-compatible.
Workarounds
pnpm patch @sayem314/react-native-keep-awaketo relocate the spec, ornodeLinker: hoistedinpnpm-workspace.yaml(pnpm v10+) ornode-linker=hoistedin.npmrc(pnpm v9 and earlier).