hampoelz / Capacitor-NodeJS

📱 A full-fledged Node.js runtime for Capacitor apps.
MIT License
77 stars 16 forks source link

support for native node modules build #16

Open sce9sc opened 1 year ago

sce9sc commented 1 year ago

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 .

hampoelz commented 1 year ago

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.

ghost commented 1 year ago

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

hampoelz commented 1 year ago

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.

ghost commented 1 year ago

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.

hampoelz commented 10 months ago

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.