Capacitor-NodeJS
Capacitor-NodeJS copied to clipboard
support for native node modules build
I have tried to run on android a node app that includes a dependency that includes the sodium-native package and it crushes. Does android build, rebuild the npm modules ?
I will investigate further and provide more info.
Thank you. Fantastic job .
No, unfortunately native packages aren't automatically rebuilt for mobile platforms. If a native package isn't built for mobile platforms, you have to do it by yourself.
I haven't tried yet, but maybe you can make use of the "override" field in your package.json. See https://docs.npmjs.com/cli/v9/configuring-npm/package-json?v=true#overrides and npm/cli#4909
You could try overriding your dependency's sodium-native
package with the sodium-native-nodejs-mobile
package, which should work on android and ios.
You might try something like this for a npm module:
"overrides": {
"your_dependency": {
"sodium-native": "npm:sodium-native-nodejs-mobile@version"
}
}
or for a module not hosted on npm:
"overrides": {
"your_dependency": {
"sodium-native": "github:staltz/sodium-native-nodejs-mobile"
}
}
Let me know if it works so I can add a note to the readme.
I've been using this hacky shell script (in combination with ncc) until i containerize it properly to build and bundle for android. I'm sure i'll need a different approach for ios though, whenever i happen to need it.
export PATH=$PATH:$ANDROID_NDK_PATH/toolchains/llvm/prebuilt/linux-x86_64/bin/
toolchain_target_arch=aarch64
node_target_arch=arm64
android_api_level=$ANDROID_API_LEVEL
export CC=$ANDROID_NDK_PATH/toolchains/llvm/prebuilt/linux-x86_64/bin/${toolchain_target_arch}-linux-android${android_api_level}-clang
export CXX=$ANDROID_NDK_PATH/toolchains/llvm/prebuilt/linux-x86_64/bin/${toolchain_target_arch}-linux-android${android_api_level}-clang++
export LINK=$ANDROID_NDK_PATH/toolchains/llvm/prebuilt/linux-x86_64/bin/${toolchain_target_arch}-linux-android${android_api_level}-clang++
export AR=$ANDROID_NDK_PATH/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
export npm_config_verbose=1
export npm_config_nodedir=${ANDROID_LIBNODE_PATH}
export npm_config_arch=${node_target_arch}
export node_config_plaform=android
export node_config_format=make-android
mv node_modules ../node_modules.bak
# --from-from-source is used by node-pre-gyp
npm install --build-from-source
# Remove executable permissions from native node modules
find node_modules -iname '*.node' -exec chmod -x '{}' \;
buildroot=$(pwd)/ncc
target=arm64-android
buildpath="${buildroot}/${target}"
if [ ! -d "${buildpath}" ]; then
mkdir -p "${buildpath}"
fi
ncc build --source-map -d --asset-builds --target es2022 -o ${buildpath} src/offline.ts
rm -rf node_modules
mv ../node_modules.bak node_modules
EDIT: i notice it shouldn't actually be ANDROID_LIBNODE_PATH
, but rather just LIBNODE_PATH
Thanks for sharing your script @jrobeson.
Maybe we could provide an automatic rebuild of native dependencies for mobile platforms in the future. But honestly I don't see such a feature soon, as I haven't worked with native modules yet and have other priorities at the moment.
the cordova plugin did a lot of work to compile/recompile deps, but i wouldn't wanna handle it the context of the android build myself. It'd be done better as part of your node application's own build steps. It might be nice to find a way to plug it into vite or webpack though as part of your ionic or pure capacitor setup though.
Until I find time to look into it, the prebuild-for-nodejs-mobile tool could be used to compile native node.js modules for mobile devices.