apify/fingerprint-suite

ENOENT: no such file or directory, open '/var/task/node_modules/fingerprint-injector/utils.js'

danthareja opened this issue · 2 comments

Describe the bug

I'm not sure if this is a Remix thing, a Vercel thing, or a FingerprintInjector thing. Can you help me narrow down the problem?

When running new FingerprintInjector() on Remix, deployed on Vercel, I'm getting the following error:

Error: ENOENT: no such file or directory, open '/var/task/node_modules/fingerprint-injector/utils.js'
    at Object.openSync (node:fs:600:3)
    at readFileSync (node:fs:468:35)
    at FingerprintInjector._loadUtils (/var/task/node_modules/fingerprint-injector/fingerprint-injector.js:148:47)
    at new FingerprintInjector (/var/task/node_modules/fingerprint-injector/fingerprint-injector.js:18:25)
    at loader (/var/task/build/index.js:79:5)
    at Object.callRouteLoaderRR (/var/task/node_modules/@remix-run/server-runtime/dist/data.js:41:22)
    at commonRoute.loader (/var/task/node_modules/@remix-run/server-runtime/dist/routes.js:48:50)
    at callLoaderOrAction (/var/task/node_modules/@remix-run/router/dist/router.cjs.js:3516:34)
    at /var/task/node_modules/@remix-run/router/dist/router.cjs.js:3255:68
    at Array.map (<anonymous>)

To Reproduce

Reproduced by running new FingerprintInjector() in a loader route in the Remix template repo, deployed on Vercel

app/routes/fingerprint.jsx

const { FingerprintInjector } = require("fingerprint-injector");

export function loader() {
  try {
    new FingerprintInjector();
  } catch (e) {
    console.error(e);
    return {
      error: e.message,
      stack: e.stack,
    };
  }

  return {
    success: true,
  };
}

Expected behavior

In this example, I'd expect the endpoint to return the success payload:

{ success: true }

System information:

  • OS: [e.g. MacOS]
  • Node.js version 18

Hi and thanks for submitting this issue!

I'm not sure if this is a Remix thing, a Vercel thing, or a FingerprintInjector thing

It's actually all of them (sort of). Vercel's bundler tries to trace all the imported files and dependencies to minimize the build size - it's actually pretty impressive, see here.

The downside to this is that sometimes, it doesn't work as expected. FingerprintInjector loads the utils.js using fs.readFileSync with a dynamic path - all of this is probably already too much for the tracer to follow. The utils.js file then doesn't get included in the final build and you get the ENOENT error.

Until I fix this (shouldn't be that hard, but I don't want to rush it and break something else), I sent you a PR to your repo that uses the patch-package library to simplify the utils.js import in the injector so that the Vercel tracer understands it. Vercel demo is running here. Hope that helps :)

Anyway, I'll leave this issue open until I fix this in the injector itself, so feel free to ask any additional questions if you have any.

Wow thank you so much @barjin for both your thorough explanation of the problem and your fix for it.

I really appreciate it, you rock!