fastify / fastify-autoload

Require all plugins in a directory
MIT License
320 stars 66 forks source link

Cannot detect `@swc-node/register` loaded by `fastify-cli` with the `-r` option #404

Open zetaraku opened 1 month ago

zetaraku commented 1 month ago

Prerequisites

Fastify version

4.28.1

Plugin version

5.10.0

Node.js version

20.x

Operating system

Windows

Operating system version (i.e. 20.04, 11.3, 10)

10

Description

I'm using fastify start -r @swc-node/register app.ts to start my app written in TypeScript.

However, this plugin cannot detect @swc-node/register loaded by fastify-cli and the following error is thrown:

Error: @fastify/autoload cannot import plugin at '~/fastify-app/plugins/sensible.ts'. To fix this error compile TypeScript to JavaScript or use 
'ts-node' to run your app.

Related PR:

PR https://github.com/fastify/fastify-autoload/pull/191 fixed the case with node -r @swc-node/register but not with fastify start -r @swc-node/register.

Current workaround:

I have to manually set the FASTIFY_AUTOLOAD_TYPESCRIPT environment variable.

Additional information:

The current checkPreloadModules() util checks the process._preload_modules array, but it's empty when the package is required with fastify-cli.

Link to code that reproduces the bug

https://github.com/zetaraku/fastify-app

Expected Behavior

The plugin should be able to detect the @swc-node/register package loaded by fastify start -r @swc-node/register.

jean-michelet commented 1 month ago

Is it an autoloader or a fastify-cli related issue? Maybe we should transfer this issue?

zetaraku commented 1 month ago

@jean-michelet

@fastify/autoload is relying on a Node.js internal variable to check if a module is loaded.

https://github.com/nodejs/node/blob/be7a0c578026dda29a1c9e76d5a0e04b71f25601/lib/internal/process/pre_execution.js#L259-L265

I don't think this is fastify-cli's issue since -r in fastify-cli is not guaranteed to be exactly the same as the -r in node, but it would be great if it's possible for fastify-cli to require modules the same as node does.

If not, maybe fastify-cli can provide another way for plugins to check for loaded modules, or @fastify/autoload can use another method to detect specific modules.

jean-michelet commented 1 month ago

If no answer from other collaborators, are you willing to investigate and push a PR on the right repo plz?

zetaraku commented 1 month ago

Imitating Node.js behavior by adding the following lines in fastify-cli's preloadCJSModules() does solve this issue, but I don't know if this is the right way to solve it.

I'll wait for more comments.

Object.defineProperty(process, '_preload_modules', {
  __proto__: null,
  writable: false,
  configurable: true,
  enumerable: true,
  value: opts.require,
})
jean-michelet commented 1 month ago

I don't know if this is the right way to solve it.

Wdyt @mcollina?

I still think this issue should be transfered to fastify-cli imo.

I have to manually set the FASTIFY_AUTOLOAD_TYPESCRIPT environment variable.

Or we can also document this workaround here.

mcollina commented 1 month ago

I think the problem is in this repo, we should not be checking that. Maybe we should check the require cache as well.

jean-michelet commented 1 month ago

Looking into it

zetaraku commented 1 month ago

Now I believe we should solve it in fastify-cli, because once require is called, the info of module name is lost and become many absolute paths in require.cache, checking it will become inefficient and non-trivial.