Pkg: Calling function.toString() returns `[native code]`

Created on 3 May 2019  路  7Comments  路  Source: vercel/pkg

I just tried pkging an application which injects JavaScript code into a Selenium-driven browser. The JS code/injection looks something like:

var browserCode = (something) => {
  // Do various things... but for the sake of this contrived example, we'll change the <body>
  document.body.innerHTML = something
}

var error = await webdriverInstance.executeAsyncScript(`
  var __selenium_callback__ = arguments[arguments.length - 1]

  try {
    (
      ${browserCode.toString()}
    )(
      "${someValue}"
    )

    __selenium_callback__(null)
  } catch (error) {
    __selenium_callback__(error)
  }
`);

if (error) {
  throw new Error(error.message);
}

This yields a SyntaxError, as the injected code resembles something like:

var __selenium_callback__ = arguments[arguments.length - 1]

try {
  (
    [native code]
  )(
    "hello world"
  )

  __selenium_callback__(null)
} catch (error) {
  __selenium_callback__(error)
}

This seems very related to https://github.com/zeit/pkg/issues/62, but it's not exclusively caused by calling Class#toString().

All 7 comments

Looks like this is intentional, based on the updated spec: https://tc39.github.io/Function-prototype-toString-revision/#proposal-sec-function.prototype.tostring.

Closing for now.

I misread the spec. This is still an issue.

@stephenmathieson is there a workaround for this?

Just did a quick test:

test.js file:

const aFunction = () => 'Hello World';

console.log(typeof aFunction);
console.log(aFunction);
console.log(aFunction());
console.log(aFunction.toString());

console.log('end');

Return with node test.js:

[Function: aFunction]
Hello World
() => 'Hello World'
end

After running pkg:
pkg --targets node12-macos-x64 test.js
./test

[Function: aFunction]
Hello World
function aFunction() { [native code] }
end

As you can see with pkg Function.prototype.toString() returns
function aFunction() { [native code] } instead of the actual function.

JavaScript Reference

CC: @igorklopov

My workaround was to not .toString() functions. I was not able to get this to work otherwise.

@igorklopov, others, is there a workaround for this? I'm trying to run https://github.com/microsoft/playwright and it heavily relies on function.toString().

If source code is stripped while packaging, then toString has nothing to show, that's why [native code]. But if you force pkg to leave source code for that js file, then toString will likely work as in node.js environment. For example --public option leaves source code of most js files intact. Also you can use any kind of config (package.json or something.json with -c something.json) and specify something like

{
  "pkg": {
    "assets": [
      "file-to-leave-sources-in-executable.js"
    ]
  }
}

Awesome, thanks @igorklopov , worked like a charm!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Araknos picture Araknos  路  4Comments

Admiral-Enigma picture Admiral-Enigma  路  3Comments

j-brown picture j-brown  路  4Comments

Nilesh0101 picture Nilesh0101  路  4Comments

jflayhart picture jflayhart  路  4Comments