Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2edd052

Browse files
authoredMar 16, 2022
plugin: new JS API startWithArgs()
From PR nodejs-mobile#9 * Added methods for starting project with custom arguments * Provide arguments in inline command * Fix passing args on iOS * Updated documentation for startWithArgs feature
1 parent 8686371 commit 2edd052

File tree

5 files changed

+116
-0
lines changed

5 files changed

+116
-0
lines changed
 

‎README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ import nodejs from 'nodejs-mobile-react-native';
120120
```
121121

122122
- `nodejs.start`
123+
- `nodejs.startWithArgs`
123124
- `nodejs.startWithScript`
124125
- `nodejs.channel.addListener`
125126
- `nodejs.channel.post`
@@ -138,6 +139,15 @@ import nodejs from 'nodejs-mobile-react-native';
138139

139140
Starts the nodejs-mobile runtime thread with a file inside the `nodejs-project` directory.
140141

142+
### nodejs.startWithArgs(command [, options])
143+
144+
| Param | Type |
145+
| --- | --- |
146+
| command | <code>string</code> |
147+
| options | <code>[StartupOptions](#ReactNative.StartupOptions)</code> |
148+
149+
Starts the nodejs-mobile runtime thread with a file inside the `nodejs-project` directory and passes provided arguments down to it.
150+
141151
### nodejs.startWithScript(scriptBody [, options])
142152

143153
| Param | Type |

‎android/src/main/java/com/janeasystems/rn_nodejs_mobile/RNNodeJsMobileModule.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,43 @@ public void run() {
189189
}
190190
}
191191

192+
@ReactMethod
193+
public void startNodeProjectWithArgs(final String input, ReadableMap options) throws Exception {
194+
// A New module instance may have been created due to hot reload.
195+
_instance = this;
196+
if(!_startedNodeAlready) {
197+
_startedNodeAlready = true;
198+
199+
List<String> args = new ArrayList<String>(Arrays.asList(input.split(" ")));
200+
201+
String absoluteScriptPath = nodeJsProjectPath + "/" + args.get(0);
202+
203+
// Remove script file name from arguments list
204+
args.remove(0);
205+
206+
final List<String> command = new ArrayList<String>();
207+
208+
command.add("node");
209+
command.add(absoluteScriptPath);
210+
211+
command.addAll(args);
212+
213+
final boolean redirectOutputToLogcat = extractRedirectOutputToLogcatOption(options);
214+
215+
new Thread(new Runnable() {
216+
@Override
217+
public void run() {
218+
waitForInit();
219+
startNodeWithArguments(
220+
command.toArray(new String[0]),
221+
nodeJsProjectPath + ":" + builtinModulesPath,
222+
redirectOutputToLogcat
223+
);
224+
}
225+
}).start();
226+
}
227+
}
228+
192229
@ReactMethod
193230
public void sendMessage(String channel, String msg) {
194231
sendMessageToNodeChannel(channel, msg);

‎index.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ declare module "nodejs-mobile-react-native" {
66
* @param options
77
*/
88
start: (scriptFileName: string, options?: StartupOptions) => void
9+
/**
10+
* Starts the nodejs-mobile runtime thread with provided arguments
11+
* @param command
12+
* @param options
13+
*/
14+
startWithArgs: (command: string, options?: StartupOptions) => void
915
/**
1016
* Starts the nodejs-mobile runtime thread with a script body
1117
* @param scriptBody

‎index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ const start=function(mainFileName, options) {
8787
options = options || {};
8888
RNNodeJsMobile.startNodeProject(mainFileName, options);
8989
};
90+
91+
const startWithArgs=function(command, options) {
92+
if (typeof command !== 'string') {
93+
throw new Error('nodejs-mobile-react-native\'s startWithArgs expects to receive the main .js entrypoint filename with optional arguments, e.g.: nodejs.startWithArgs("main.js -c custom");');
94+
}
95+
options = options || {};
96+
RNNodeJsMobile.startNodeProjectWithArgs(command, options);
97+
};
98+
9099
const startWithScript=function(script, options) {
91100
options = options || {};
92101
RNNodeJsMobile.startNodeWithScript(script, options);
@@ -117,6 +126,7 @@ registerChannel(eventChannel);
117126

118127
const export_object = {
119128
start: start,
129+
startWithArgs: startWithArgs,
120130
startWithScript: startWithScript,
121131
channel: eventChannel
122132
};

‎ios/RNNodeJsMobile.m

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,42 @@ -(void)callStartNodeProject:(NSString *)mainFileName
101101
[[NodeRunner sharedInstance] startEngineWithArguments:nodeArguments:nodePath];
102102
}
103103

104+
-(void)callStartNodeProjectWithArgs:(NSString *)input
105+
{
106+
NSArray* command = [input componentsSeparatedByString: @" "];
107+
NSString* script = [command objectAtIndex:0];
108+
109+
NSMutableArray* args = [command mutableCopy];
110+
[args removeObject:[args objectAtIndex:0]];
111+
112+
NSString* srcPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@/%@", NODEJS_PROJECT_RESOURCE_PATH, script] ofType:@""];
113+
114+
NSMutableArray* nodeArguments = nil;
115+
116+
NSString* dlopenoverridePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@/%@", NODEJS_PROJECT_RESOURCE_PATH, NODEJS_DLOPEN_OVERRIDE_FILENAME] ofType:@""];
117+
// Check if the file to override dlopen lookup exists, for loading native modules from the Frameworks.
118+
if(!dlopenoverridePath)
119+
{
120+
nodeArguments = [NSMutableArray arrayWithObjects:
121+
@"node",
122+
srcPath,
123+
nil
124+
];
125+
126+
[nodeArguments addObjectsFromArray:args];
127+
} else {
128+
nodeArguments = [NSMutableArray arrayWithObjects:
129+
@"node",
130+
@"-r",
131+
dlopenoverridePath,
132+
srcPath,
133+
nil
134+
];
135+
136+
[nodeArguments addObjectsFromArray:args];
137+
}
138+
[[NodeRunner sharedInstance] startEngineWithArguments:nodeArguments:nodePath];
139+
}
104140

105141
RCT_EXPORT_METHOD(startNodeWithScript:(NSString *)script options:(NSDictionary *)options)
106142
{
@@ -136,6 +172,23 @@ -(void)callStartNodeProject:(NSString *)mainFileName
136172
}
137173
}
138174

175+
RCT_EXPORT_METHOD(startNodeProjectWithArgs:(NSString *)command options:(NSDictionary *)options)
176+
{
177+
if(![NodeRunner sharedInstance].startedNodeAlready)
178+
{
179+
[NodeRunner sharedInstance].startedNodeAlready=true;
180+
NSThread* nodejsThread = nil;
181+
nodejsThread = [[NSThread alloc]
182+
initWithTarget:self
183+
selector:@selector(callStartNodeProjectWithArgs:)
184+
object:command
185+
];
186+
// Set 2MB of stack space for the Node.js thread.
187+
[nodejsThread setStackSize:2*1024*1024];
188+
[nodejsThread start];
189+
}
190+
}
191+
139192
-(void) sendMessageBackToReact:(NSString*)channelName:(NSString*)message
140193
{
141194
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{

0 commit comments

Comments
 (0)
Please sign in to comment.