I switched my project over to Node16 module resolution, and now WebStorm is failing to resolve imports. This is very much a tooling question, as the application compiles just fine, and WebStorm even resolves the imported types correctly - yet it still complains about the codebase.
https://youtrack.jetbrains.com/issue/WEB-59941/WebStorm-and-Typescript-fighting-over-Node16-module-resolution-absolute-imports
#Is something wrong with my project's tsconfig?
1 messages · Page 1 of 1 (latest)
If you're wondering why I'm posting here instead of JB - It's because they closed my question without a definitive answer. FYI, I am posting in their discord too.
Is something wrong with my project's tsconfig?
@manic moat node16 must be used when using ESM
so your import must have a file extension, as specified in the ESM "spec"
as you mentionned in your issue, TS doesn't allow using .ts as file extension
but you can use a .js, it should work just fine
The application doesn't compile like that
what do you mean by that?
SO question has more details
// error - ./src/pages/index.tsx:13:0
// Module not found: Can't resolve '@/utils/helpers.js'
import { classNames } from "@/utils/helpers.js";
also it makes 100% sense your issue got closed on JetBrains's website, since it's your code being wrong, and not the editor (and it's TS server) having an issue
you are using ESNext as your module system
meaning you are using ESM
TS will output imports using the import object from "package" syntax
and ESM requires a file extension for the imports
TS can compile your code without them
but your code won't run, node won't allow it
No, it does run. I am able to start my code and run the site.
there is a difference between "it compiles" and "it runs"
without the file extension using ESM?
Yes
Let me check my code again real quick, I wanna make sure I'm not getting confused.
not possible
notice VSCode catching the error
and node throwing an error
but when adding the extesion, it works juts fine
how are you running your code btw?
It is a next JS project and I'm running it inside my IDE
But my laptop just ran out of battery and I have hot food waiting for me. I'll ping you whenever I have more details, but I think I have a reasonable idea of a fix.
I think the include paths are for TS files only whenever a .JS path is referenced. Perhaps adding .JS would fix?
Cool. Still wanna prove to you that it was running even without extensions.
because next uses swc (babel for the older versions), which not not behave like the typescript compiler
that's why you have different results between using next and calling tsc
Oh gotcha.
Thanks for the tips, was worried I would have to drop this switch after fighting with it for hours.
but like
do you fully understand what moduleResolution: "node16" does?
is there a specific reason you need it?
because it doesn't seem like there is a need for ESM when using nextjs
If there is a good replacement module for true-myth I might prefer using that, but I'm not really sure what I'm searching for here.
I believe so. Sorta. Maybe not so much the purpose though - there's quite a bit going on here overall.
Also, true-myth has a version 5 which doesn't use node16 moduleResolution, so I should've perhaps just switched to that rather than fight with this for a couple hours. I'm stupidly stubborn.
node16 doesn't mean working with node16+
well, kinda, but it mainly means "working with ESM"
and with NextJs, there is little to no reason to use ESM
espcially when next comes with a decent bundler
(there have been discussions about renaming that "node16" option iirc)
node16 means "this was what node 16 had in its module resolution"; kinda have to pick a name and so that's it. What you'll really want is moduleResolution=bundler, coming soon in TS 5.0
Why not? Sorry if this is a dumb question. I literally do not know.
well, imo, setting up a project with ESM is more work
have to configure the package.json, have a compatible nodejs version, add extensions to all the imports, maybe even add a bundler in the mix
also some older packages don't come with an ESM version
more work compared to commonjs, especially if the code si meant to run on nodejs anyway
also the benefits aren't really worth it
like, what do you get? top level await? is that it?
Truthfully i have the opposite opinion and say that Node 16 / NodeNext are the best modes, as they'll have the most accurate types
I wouldn't know how to use true-myth without ESM, though
Would it work just fine if I just undid all this ESM stuff?
in 5.0 you'll be able to disable the extensions (if using noEmit)
but, reasonably, node resolution is "fine" for now if you're bundling
well, what I described is mainly when the code is intended to run in node directly
but if it's for web stuff, then I'm all in for ESM
hah, in node I have squarely moved myself to the "ESM only" camp 😄
obviously in web you're bundling or ESM so you're good there
no kidding
ever worked with C++ before? 🙃
languages without package managers are my favorite 🙃
Fortunately no. My manager gave me C, so the issue was mostly digging up really old documentation and spinning in circles testing different things.
Kinda scared of the day I have to learn C/C++ package and library management.
My brush with Qt5 in the past did not make it look easy.
can't learn what doesn't exist 😉
but yeah, incredible build system like make and cmake, libraries management, and their versions, compiler-specific directives, architecture-specific options, metaprogramming with macos, etc.
lots of fun
{
"compilerOptions": {
"target": "es2020",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "Node16",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"noUncheckedIndexedAccess": true,
"baseUrl": "./src/",
"paths": {
"@/*": [
"./*"
]
},
"plugins": [
{
"name": "next"
}
]
},
"include": [
"next-env.d.ts",
"src/**/*.ts",
"src/**/*.js",
"src/**/*.tsx",
"**/*.cjs",
"**/*.mjs"
],
"exclude": [
"node_modules"
]
}
import ThreadList from "@/components/ui/ThreadList";
import { classNames } from "@/utils/helpers.js";
Still fails to compile
wait - compiling / (client and server)...
error - ./src/pages/index.tsx:13:0
Module not found: Can't resolve '@/utils/helpers.js'
Found a solution
Still find the .js files kinda ugly. Guess that will be fixed in TS 5.0 though?
That's "okay" if you're using a bundler, but generally an abuse of paths
What's the proper solution here? Totally lost.
I would just continue to use node resolution until 5.0, if you're really not liking the .js extensions
Well, it seems like I can't use node resolution with true-myth 6.0...
You might be able to get away with ESNext temporarily
Or, use v5
that's what the authors say to do in the readme
Mhm. The rewrite to use .js, this weirdy hacky solution for NextJS, and Webstorm barely keeping it together - it's too expensive.