node-jsc enables node.js to use JavaScriptCore, WebKit's javascript engine, allowing node.js to run on iOS devices (and other platforms supported by node.js and JavaScriptCore). While node-jsc was successully tested on iOS (has already managed to succesfully run a test express.js project with websockets), it is a very early work in progress, and is far from being ready for production use.
Currently based on node v8.11.1, with slightly newer npm version, but will be updated to a more recent version of node.
A separate project, node-native-script native extension, allows javascript code running in node-jsc to directly call iOS platform APIs.
The core part of what makes node-jsc work is jscshim, which implements the parts of v8's API used by node.js on top of JavaScriptCore (JSC), WebKit's javascript engine. Similar to node-chakracore's ChakraShim and spidernode's spidershim, jscshim aims to implement as much of v8's APIs as possible, as close as possible, hopefully making it transperant to node.js and native extensions. See jscshim's documentation for more detailed design and implementation information. Note that as v8 API is quite extensive, jscshim currently doesn't implement all of it. See jscshim status and known issues to see what jscshim currently implements.
jscshim uses its own fork of WebKit. See WebKit fork and compilation for more information, or see our fork's repo.
Besides jscshim, changes were made to node's build files, source code and dependencies in order to support using jscshim (and WebKit) and to support iOS (some of it taken from the great work done in nodejs-mobile).
node-jsc is experimental, but:
node-jsc's initial goal was to eventually provide a stable, production ready, node.js running on iOS devices. When I started working on it, there were a few other projects to consider:
Evantually, I chose JavaScriptCore for mainly two reasons:
Besides that:
Homebrew is recommended for installing the required tools (if they aren't already installed). To install Homebrew, from the terminal:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Prerequisites
xcode-select --install
brew install cmake
git clone https://github.com/mceSystems/node-jsc
cd node-jsc
sudo deps/jscshim/webkit/Tools/Scripts/configure-xcode-for-ios-development
Building for iOS
To build node-jsc, use build_ios.sh
from the root directory. Before using it for the first time, make sure the script is executable:
chmod +x build_ios.sh
then:
./build_ios.sh
Which will build:
int node_start(int argc, char *argv[]);
It is highly recommended to use the NodeIOS framework, rather than using the libraries directly.
Prerequisites
Building
From the command line, at the node-jsc root directory, use vcbuild.bat to generate a Visual Studio solution and build it:
vcbuild.bat vs2017 x64 nosnapshot noetw noperfctr jsc
When the build process is finished, node.exe will be found under the "Release" directory.
Note that this will run WebKit's build script, which will download additional support libraries for WebKit the first time it is used.
While node-jsc haven't been tested on other platforms yet, as long as a platform is supported by both node and WebKit, node-jsc should support it, or should be able to support it with some platform specific fixes. If you try to build\run node-jsc on another platform - let us know if it works, and feel free to open an issue about it (or even better - a pull request) if needed.
It is recommended to use the iOS framework (built by build_ios.sh
), found at tools/NodeIOS/Release-iphoneos:
1) Add the framework to your Xcode project.
2) Add your node.js source files, in a directory, to you project.
3) In your native source code:
#import <NodeIOS/NodeIOS.h>
NSString * entryPointFilePath = [[NSBundle mainBundle] pathForResource:@"loader" ofType:@"js" inDirectory: @"js"];
const char * nodeArgs[] = { "node", [loaderFilePath UTF8String] };
node_start(2, nodeArgs);
Note that node_start is blocking, so it is recommended to run it in its own thread (see NodeIOS Demo Project for an example). 4) Since the current directory is not the js sources directory, it is recommended to change the current dir from the javascript code. For example:
process.chdir(__dirname);
See NodeIOS Demo Project for an example project, which:
process.chdir(__dirname + "/app");
require("./app");
While the javascript app itself is under the js/app directory
Native modules are supported, through cross compiling with node-gyp. See node-native-script for an example. Prerequisites:
security find-identity -v -p codesigning
For more information, see "inside-code-signing".
To build your native extension project for arm64, from the terminal:
<node-jsc dir>/deps/npm/node_modules/node-gyp/bin/node-gyp.js configure --nodedir=<node-jsc dir> --arch=arm64 --OS=ios --node_engine=jsc
<node-jsc dir>/deps/npm/node_modules/node-gyp/bin/node-gyp.js build --nodedir=<node-jsc dir> --arch=arm64 --OS=ios --node_engine=jsc
codesign --sign "<code signing identity>" --force ./build/Release/<Your project name>.node
See node-native-script's build script for an example on how to bundle the steps above into a bash script.
As node-jsc is experminetal and still an early proof of concept, a lot is still missing:
As node-jsc isn't the first project trying to use another javascript engine or support iOS, the great work done in other projects really helped node-jsc's development:
See the LICENSE file at the node-jsc's root directory.