summit tech
summit tech

Reputation: 21

Node.js SyntaxError: Invalid or unexpected token (but its weird)

I have never seen this error in my life

weird error?

And I just found it so odd...

My code here is seen like this:

const no = require('noparenth');

(at index.js:1)

and I have literally never seen this in my life...


the library in question is one that just allows you to invoke a function without parenthesis. I made it so it would make it easier to code + make it faster. the code is as seen here:

Function.prototype.valueOf = function() {
    this.call(this);
    return 0; 
};

Thats it...

actual error:

C:\Users\summit\testing\index.js:1
��c


SyntaxError: Invalid or unexpected token

Upvotes: 1

Views: 4657

Answers (2)

Lorenzo Lim
Lorenzo Lim

Reputation: 1

I ran into this exact issue. I created the file using "echo 'test' > test.js" and just removed the string "test" in the js file and added my code. But when I compiled there was random characters before the const that I had no clue where it came from.

Solution: I deleted the file and created the file manually using the UI by right clicking on my folder and clicking on New File and my code compiled fine. If this doesn't work, I copy and pasted an existing JS file I had from another project into my folder and that worked too.

Disclaimer: This was not researched and purely anecdotal but it's what worked for me, hopefully it can help someone else.

Upvotes: 0

qrsngky
qrsngky

Reputation: 2916

One possible way to get that type of characters is to save a file as UTF-16 LE and load it as if it were UTF-8.
If you use PowerShell, it's easy to produce a file in UTF-16 LE encoding, for example if you run echo "" > index.js. If you open the resulting file in VSCode, you can see at the bottom right that it's UTF-16 LE.

Note that the resulting file is not really empty, and you can verify that by inputting require('fs').readFileSync('index.js') in the Node.js REPL. You'll get <Buffer ff fe 0d 00 0a 00> which, when interpreted in UTF-16 LE, consists of byte order mark (U+FEFF), carriage return (U+000D) and new line character (U+000A).

Even if you open that file with a text editor and replace everything with your text, the byte order mark will still be there (as long as you still save in UTF-16 LE). For example, if you save const x = 0 the buffer will become like ff fe 63 00 ..., notice that the ff fe still is there.

When a program attempts to load it as UTF-8, it will get <invalid character> <invalid character> c <null character> and so on. What you're seeing in the output is exactly from <invalid character> <invalid character> c (Unicode: U+FFFD U+FFFD U+0063), obviously not a valid token in Node.js.


As for your actual function, it will only be invoked when you have type coercions (like +myFunction or myFunction + "") or if you directly call it like myFunction.valueOf(). And I expect it to make it (slightly) slower, because it calls a user-defined function rather than just native code.

And apart from the bad idea of modifying prototypes of objects you don't own, there is limited usefulness (if any) to this.
The this.call(this) means that you can't add more arguments to the function call.
Also, it's like myFunction.call(myFunction), I'm not sure why you would want to do that. And when used on a method of an object, it's like myObject.myMethod.call(myObject.myMethod) (with this equal to the function itself) rather than myObject.myMethod.call(myObject)

And it will break things that depend on the behavior of myFunction + "" etc.
It seems not that easy to find an example, nevertheless I found this example : isNative(Math.sin) was originally supposed to return true, but after modifying the prototype the way shown above, it became 3

Upvotes: 5

Related Questions