Script Node.js from C# in vscode - Edge.js - Unexpected token

546 Views Asked by At

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.

Unexpected token spread operator from newman

0

There are 0 best solutions below