I successfully used vs code to write the sample program to script Node.js from C#. I use the following code block directly from https://github.com/tjanczuk/edge:
using System;
using System.Threading.Tasks;
using EdgeJs;
class Program
{
public static async Task Start()
{
var func = Edge.Func(@"
return function (data, callback) {
callback(null, 'Node.js welcomes ' + data);
}
");
Console.WriteLine(await func(".NET"));
}
static void Main(string[] args)
{
Start().Wait();
}
}
The above is working successfully with .NET Framework 4.5.2 and 4.8.0
Also, I successfully wrote a program in Node.js to invoke a GET request using Newman:
const newman = require('newman'); // require newman in your project
const theCollec = '.\\collections\\vs code test.postman_collection.json';
//call newman.run to pass `options` object and wait for callback
newman.run({
collection: require(theCollec),
reporters: 'cli'
}, function (err) {
if (err) { throw err; }
console.log('collection run complete!');
});
Now, I am trying to include the Newman code block in the C# program, but it is not working. I am getting the following errors when I run the program using dotnet run
:
using System;
using System.Threading.Tasks;
using EdgeJs;
namespace TestNodeJSNET
{
class Program
{
public static async Task Start()
{
var func = Edge.Func(@"
var newman = require('newman'); // require newman in your project
const examples = require('.\\..\\examples.js');
return function (data, callback) {
// var WebSocketServer = require('ws').Server;
const theCollec = '.\\..\\collections\\Postman Echo.postman_collection.json';
// call newman.run to pass `options` object and wait for callback
newman.run({
collection: require(theCollec),
reporters: 'cli'
}, function (err) {
console.log('This is the function part of Newman.');
console.log(err);
if (err) { throw err; }
callback(null, 'Node.js welcomes ' + data + ' - ' + theCollec + ' - examples hi :' + examples.say());
console.log('collection run complete!');
});
console.log('This is from NodeJS in .NET');
// callback(null, 'Node.js welcomes ' + data + ' - ' + theCollec + ' - examples hi :' + examples.say());
}
");
Console.WriteLine(await func(".NET"));
}
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Console.WriteLine("Hello World 3!");
Start().Wait();
}
}
}
I am getting the following errors:
Unhandled Exception: System.AggregateException: One or more errors occurred. ---> System.Exception: C:\Projects\TestNodeJSNET\node_modules\ws\lib\websocket.js:460
...options
^^^
SyntaxError: Unexpected token ...
at createScript (vm.js:74:10)
at Object.runInThisContext (vm.js:116:10)
at Module._compile (module.js:533:28)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:503:32)
at tryModuleLoad (module.js:466:12)
at Function.Module._load (module.js:458:3)
at Module.require (module.js:513:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (C:\Projects\TestNodeJSNET\node_modules\ws\index.js:3:19)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at TestNodeJSNET.Program.<Start>d__0.MoveNext()
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at TestNodeJSNET.Program.Main(String[] args)
See the snapshot below of the code that caused the error.
I appreciate your help to resolve this issue.
Update 1
I confirmed that the problem is from the NuGet Edge.js
. I used NPM newman
version 4.6.1 and the problem is resolved. I used an example package with the spread operator and used outside Edge.js and inside, and the problem triggered only within Edge.js
from C#.
Following is the examples.js
module I used to pinpoint the root cause of the issue:
console.log("evaluating example.js");
var invisible = function () {
console.log("invisible");
}
exports.message = "hi";
exports.arr = [1,2,3,4,5];
exports.obj = {name:"Tarek", subject:"Math"};
exports.say = function () {
console.log(exports.message);
console.log("Testing the spread operator for arr: ", ...exports.arr);
//var obj2 = {...exports.obj};
var obj2 = {key:"Obj 2", val:"val of obj2"};
console.log("Testing the spread operator for obj: ", obj2);
return "Competed log of " + exports.message;
}
Now, I can live with that solution, but I’d like to do more.
I can transpile the Newman Module and all its dependencies to a lower version using Babel. I did some research, and most probably it will work, but still not clear how to do that. I need to do more research.
However, the only issue with using Babel is how to make it a reliable solution. This means I need to set up my project in such a way that it will install Newman’s latest version using npm install newman
then trigger the Babel transpiler to compile the modules to a lower version using minimal manual interventions, and yet, still be able to use the node API require("newman")
. I still didn’t figure out how to wrap my head around this issue.
I think we need to create a task using vs code or script build
in package.json
to call Babel transpiler to compile the Newman code in the node_module
folder and create the output in say node_module_dist
or something like that. How is that possible?
I am looking for help to implement the transpiler option using Babel or with any other alternative.
Update 2:
I managed to set up Babel and used the following babel.config.js
:
module.exports = function (api) {
api.cache(true);
const presets = [
// "@babel/preset-env",
// ['@babel/preset-env', {targets: {node: 'current'}}],
['@babel/preset-env', { targets: { node: 'current' }, modules: "auto" }],
"@babel/preset-typescript",
['@babel/preset-react', { targets: { node: 'current' } }],
// ['es2015', {modules: false}]
];
const plugins = [
"@babel/plugin-transform-typescript", "@babel/plugin-syntax-jsx",
"@babel/plugin-transform-strict-mode",
["@babel/plugin-transform-modules-commonjs", {
"strictMode": false
}]
];
const include =
["node_modules/postman-collection/lib/collection/item.js",
"node_modules/csv-parse/lib/index.js",
"node_modules/mkdirp/lib/opts-arg.js",
"node_modules/newman/lib/node-version-check/index.js",
"./node_modules/@babel/helper-define-polyfill-provider/src/browser/dependencies.js",
".\\node_modules\\@babel\\helper-define-polyfill-provider\\src\\node\\dependencies.js",
".\\node_modules\\@babel\\plugin-syntax-typescript\\test\\fixtures\\disallow-jsx-ambiguity\\type-parameter-unambiguous\\output.js",
".\\node_modules\\has-symbols\\test\\shams\\core-js.js",
".\\node_modules\\has-symbols\\test\\shams\\get-own-property-symbols.js",
".\\node_modules\\postman-sandbox\\lib\\sandbox\\index.js",
];
const exclude = [
];
return {
presets,
plugins,
include,
exclude,
parserOpts: { allowReturnOutsideFunction: true },
generatorOpts: { compact: true }
};
}
I am using this command to transpile the node_modules
under the sub-folder required_modules
of the project root, and the output is 'node_module_dist':
cd required_modules
npx babel .\node_modules\ --out-dir .\node_modules_dist\
This setup is actually working and did transpile about 20 JavaScript files to remove the JavaScript features not working because of Edge.js
.
However, the final error I got which I cannot resolve using any bable preset or plugin:
SyntaxError: C:\Projects\TestNodeJSNET\required_modules\node_modules\postman-sandbox\lib\sandbox\index.js: Deleting local variable in strict mode. (73:20)
71 | // We don't need direct access to the global bridge once it's part of execution closure.
72 | // eslint-disable-next-line no-global-assign, no-implicit-globals, no-delete-var
> 73 | bridge = undefined; delete bridge;
| ^
74 |
at instantiate (C:\Projects\TestNodeJSNET\node_modules\@babel\parser\lib\index.js:72:32)
at constructor (C:\Projects\TestNodeJSNET\node_modules\@babel\parser\lib\index.js:358:12)
at Object.raise (C:\Projects\TestNodeJSNET\node_modules\@babel\parser\lib\index.js:3335:19)
at Object.parseMaybeUnary (C:\Projects\TestNodeJSNET\node_modules\@babel\parser\lib\index.js:12474:16)
at Object.parseMaybeUnary (C:\Projects\TestNodeJSNET\node_modules\@babel\parser\lib\index.js:10708:20)
at Object.parseMaybeUnaryOrPrivate (C:\Projects\TestNodeJSNET\node_modules\@babel\parser\lib\index.js:12284:61)
at Object.parseExprOps (C:\Projects\TestNodeJSNET\node_modules\@babel\parser\lib\index.js:12291:23)
at Object.parseMaybeConditional (C:\Projects\TestNodeJSNET\node_modules\@babel\parser\lib\index.js:12261:23)
at Object.parseMaybeAssign (C:\Projects\TestNodeJSNET\node_modules\@babel\parser\lib\index.js:12214:21)
at Object.parseMaybeAssign (C:\Projects\TestNodeJSNET\node_modules\@babel\parser\lib\index.js:10631:20) {
code: 'BABEL_PARSE_ERROR',
reasonCode: 'StrictDelete',
loc: Position { line: 73, column: 20, index: 3644 },
pos: [Getter/Setter]
I am not sure if this is the right path, and I really appreciate your help. It seems that Babel is unable to transpile this feature Deleting local variable in strict mode
and may encounter many more issues.