fastify-autoload
fastify-autoload copied to clipboard
Typescript complication error when running tests using Vitest
Prerequisites
- [X] I have written a descriptive issue title
- [X] I have searched existing issues to ensure the bug has not already been reported
Fastify version
3.28.0
Node.js version
16
Operating system
macOS
Operating system version (i.e. 20.04, 11.3, 10)
12.3
Description
I would like to test my fastify app using vitest, however I have noticed there is a typescript error I can't seem to get around.
When I run my tests Fastify errors, fastify-autoload cannot import plugin ... . To fix this error compile TypeScript to JavaScript or use 'ts-node' to run your app.
.
I can successfully run the tests when I compile them to Javascript and import the javascript version in the test. This does however, feel a bit hacky. It can also impact the code coverage (depending on how you are generating the javascript).
Steps to Reproduce
Stackbliz link: https://stackblitz.com/edit/node-sdwsoh
Run the npm run test
command.
Expected Behavior
Tests can be run in vitest using Typescript without having to compile first, and import the javascript version.
Just FYI I worked on this issue for a while and tried solving it by adding a ts-node register call instead of throwing here, that would handle all require calls for typescript files, transpiling and typechecking them before executing.
I had some typescript errors that I wasn't able to solve. It complained about the file not having exports despite having a default export. I also tried using a named export or using both but the error persisted and it also threw errors regarding missing fastify types that were being imported. I tried multiple settings without success and kinda ran out of options.
I'm also not entirely sure about the performance implications a change like this would have. I assume it probably wouldn't be that bad since it would only affect performance when initializing the plugins, but this should be verified if this approach ends up being used.
I think that would be an amazing fix. However ts-node could not be there, so we must catch those error specifically and provide some instructions. Would you like to send a Pull Request to address this issue? Remember to add unit tests.
We decided to put this on hold because we couldn't come to a solution within a reasonable timeframe, but we may go back to this some time in the future
I'm getting similar error when trying to use autoload
plugin with vite-plugin-node.
I've created reproducible project on stackblitz.
Is there a way to help resolving this issue as I currently can't use autoload with vite
+ typescript
Update, I decided to remove vite
and vite-plugin-node
and use other tools to have a fast typescript environment during development.
I've tried @esbuild-kit/esm-loader
@swc-node/register
tsx
and none of them worked.
At the end I looked at the code for this library and I saw there is a special case for tsm
, tried that and it worked perfectly.
Conclusion: use node -r tsm ./src/server.ts
and make sure you don't have type: module
in your package.json
.
Unfortunately all those tools needs special handling in this library to work :(. I don't know if there is a way to handle it otherwise.
PRs are welcomed!
Can you explain why each tool need different handling?
As I understand these tools transpile modules on the fly from ts
to js
.
After that step everything should work the same, no?
Unfortunately their ways of doing things is different, specifically when targeting ESM.
Reopen due to 6adc2966ba5f9414139af22033eb78b3cb0c1f91
Just now seeing that #264 broke things mentioned in #266. Will take a look at that tomorrow and hopefully have a PR next week.
I have the same issue with jest global setup, when I use autoload in globalSetup.ts I got the same error
fastify-autoload cannot import plugin ... . To fix this error compile TypeScript to JavaScript or use 'ts-node' to run your app.
There's some active conversation about this in a vitest issue here: https://github.com/vitest-dev/vitest/issues/2028
I think getting autoload
to actually run in vitest again will not be hard, but the problem I ran into is the code coverage from vitest is very whacky when using autoload
because vitest is not aware of the files that autoload
loads. To me this makes vitest not a workable solution so I'm hoping we can figure out a solution with some of the vitest contributors 🤞
@alrramezani - If you use version 5.3.0 of autoload
your Jest tests should work. You can see that working here: https://github.com/kylerush/vitest-v-tap
While setting up a repro for a "vitest alias" issue, I came across different kind of issues I never came across with my main app. One of the things is getting @fastify/autoload
to work. For now I got it working with following versions (and no additional config):
"dependencies": {
"@fastify/autoload": "5.3.0",
"@fastify/cors": "^8.1.0",
"@fastify/env": "^4.1.0",
"@prisma/client": "^4.4.0",
"@trpc/server": "10.0.0-proxy-beta.15",
"fastify-plugin": "^4.2.1",
"fastify": "^4.8.1",
"zod": "^3.19.1"
},
"devDependencies": {
"@trpc/client": "10.0.0-proxy-beta.15",
"@types/node": "^18.8.4",
"cross-env": "^7.0.3",
"dotenv-cli": "^6.0.0",
"esbuild": "^0.15.10",
"esbuild-plugin-pino": "1.2.4",
"fastify-tsconfig": "^1.0.1",
"pino": "^8.6.1",
"pino-pretty": "^9.1.1",
"prisma": "^4.4.0",
"tiny-glob": "^0.2.9",
"tsx": "^3.10.1",
"typescript": "^4.8.4",
"vitest": "^0.24.1",
"ts-node": "^10.9.1"
},
Somehow, for my main app I have the same versions, except no ts-node
explicitly installed 🤔
After some investigation it also seems that @fastify/autoload
is overriding the alias
config of vitest
. I'm currently using 5.3.0
since it's the only version I come close to get it working.
I understand that code coverage should be working, but I'm not sure if it should be blocking to make @fastify/autoload
work with vitest again? @kylerush
I'm willing to help wherever I can to resolve this issue.
See also https://github.com/vitest-dev/vitest/issues/2135
You just need a way to detect if you are running vitest. Like a set environment variable or so. Compare with #271
process.env.VITEST_MODE
and check if it's set or not?
But even then further down it results in some issues because the use of require or that the imported ".ts" files are not recognized.
But even then further down it results in some issues because the use of require or that the imported ".ts" files are not recognized.
You can force to use import
if it does matter by vitest
.
After some investigation it also seems that @fastify/autoload is overriding the alias config of vitest.
And @fastify/autoload
do nothing on the file path, it just call either import
or require
. It means that vitest
just don't work with it somehow.
https://github.com/fastify/fastify-autoload/blob/c41e96eb70fcad58ef37620da4ee718950d091d0/index.js#L239-L241
Yeah so I tried that.
I added a const isVitestEnvironment = process.env.VITEST_MODE !== undefined
, added it to the typescriptSupport
and then on those lines you highlighted I also added the check if it's vitest
to use the await import
, but then I'm getting errors like Error: unknown file extension ".ts"
for the plugins folder (e.g. cors.ts
, env.ts
, ... in my repro).
I also gave import.meta.url
a shot as i've seen it being used by vite in a vue 3 context, but then it complains that it's not being used inside an ESM environment (thus package.json
doesn't contain type: "module"
)
For now I'm just "working around" it by not using @fastify/autoload
and no aliases.
It's pretty funny because at vitest
they say that @fastify/autoload
changes the aliases which cause the errors I'm getting, but here we can see it's the import/require
that's not working 😅
I have a potential PR
I quite dont understand now the issue you meant?!
see #273
Please check the discussion in the potential solution #273
Provided an alternative approach to set forceESM instead of ts-node #274
Can't wait to test it 😄
You could test it by setting the repo and the branch for the package in package.json
{
"dependencies": {
...
"@fastify/autoload": "fastify/fastify-autoload#forceESM-for-vitest"
...
}
}
@jclaessens97
If it works, than please give feedback to have higher confidence that the PR solves the issue in a real environment.
I didn't have the time yesterday to check, but I do have time today, if it's still needed?
we released today the new version ;)
Might be a config issue on my side, but when I now try my repro again (with the updated package), I get the following:
TypeError: Unknown file extension ".ts" for /Users/jclaessens/dev/github/vitest-alias-repro/packages/api/src/plugins/cors.ts
Serialized Error: {
"code": "ERR_UNKNOWN_FILE_EXTENSION",
}
This is the same issue I got when I tried to do the changes myself.
Again, it might be a config issue on my side, but it's unclear to me at this point.
ERR_UNKNOWN_FILE_EXTENSION is a node error https://github.com/nodejs/node/blob/main/lib/internal/modules/esm/get_format.js#L75-L76