ts-node-dev: paths option(tsconfig.json) is ignored
Settings
tsconfig.json
Other options are omiited for brevity.
{
"compilerOptions": {
"baseUrl": "./src"
"paths": {
"#/*": ["./*"]
}
}
}
command
ts-node-dev --respawn --transpileOnly src/index.ts
src/index.ts
import { foo } from '#/foo'
console.log(`index.ts uses ${foo}`)
Problem
When I edit foo.ts, which index.ts depends on, ts-node-dev does not respawn. I guess it’s because ts-node-dev does not consider the paths option in tsconfig.json.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 33
- Comments: 18 (4 by maintainers)
For anyone finding this and want a two-liner here it is:
npm i -D tsconfig-paths
then in your package.json add a script like this:
"dev": "tsnd --respawn -r tsconfig-paths/register *pathtoyourmainfile* "
@whitecolor I would recommend to add a note about this (also mentioning
baseUrl
, since one really doesn’t have to usepaths
for things to break) inpoints of notice
in theREADME
.Because while I love
ts-node-dev
for the reason you mentioned in this issue, I almost just threw in the towel until I stumbled across your recommendation to usetsconfig-paths
. Which is so simple to set up but… why would one even think about looking for it in the first place? At least all I perceived was an inconsistency betweentsc
andts-node-dev
and assumed it was a bug (hence then looking for it here).If anyone has issues with this, try the module-alias plugin. So far it’s the cleanest solution I’ve found and it is working all right!
Given a directory structure like the following:
Create a
src/aliases.ts
file like this:Then, in the
src/index.ts
file, or in whatever is your entry file, add this as first import:Finally, set
tsconfig.json
like this (mostly to make typescript and your IDE recognise the path):@whitecolor tsconfig paths does not seem to work with
ts-node-dev
. It worked well previously with nodemon and ts-node.Running via
npx ts-node-dev --project tsconfig.json -r tsconfig-paths/register src/server/server.ts
My aliased paths do not resolve.
my original answer to fix ts-node paths problem here: https://github.com/TypeStrong/ts-node/issues/138
if ts-node-dev also support to read “ts-node” configuration on tsconfig.json, i think it may help
Workaround
Here is a workaround for folks with the same problem.
Install concurrently (or another preferred alternative) and node-dev (or maybe another like nodemon).
Then run
This would incrementally compile editted .ts files(
tsc -w
), and node-dev would respawn by detecting compiled .js files. Obviously, this is logically identical to what ts-node-env does, but nowtsc
respects the “paths” option.@whitecolor Thanks for the recommendation again. The main point of this issue is asking if ts-node-dev would repect
paths
. I think it’s cool and necessary. How do you think?This is strange “workaround” =)
Should this even work with node.js without special plugins?
TS compiler doesn’t transform require paths like ‘#/foo’, so it should just give the error
Cannot find module '#/foo'
There is a module https://github.com/dividab/tsconfig-paths allows to handle tsconfig’s paths option with node.js
It doesn’t work for me, but I have a -P path/to/tsconfig.json as well… It might be throwing things off?
Edit: It works with ts-node but not with ts-node-dev …
Edit Edit: got it working with cross-env TS_NODE_PROJECT=‘./src/some/folder/tsconfig.json’ ts-node-dev …
Thanks @microcipcip for directing me to module-alias plugin, since the other comments e.g
tsconfig-paths
did not work.I created a
src/aliases.ts
file like this:Then, in the
src/index.ts
file, I added this as first import:Inside my
tsconfig.json
I added this so my IDE can recognise the path:I have a
dev
script inside mypackage.json
fileThis is a task for another package, as I said you may use https://github.com/dividab/tsconfig-paths to achieve that if needed, setup is quite transparent.
Thanks @soupman99 it works like charm
@whitecolor
Thank you for the recommendation 😃 I’ve been using link-module-alias, which automatically creates symlinks in node_modules (And by this aspect, it has some other benefits, especially on plain node project, by the way). Whereas tsconfig-paths works on runtime, link-module-alias should be executed (only once) before running node.
The compiler doesn’t transform but compiles it “as-is” (
import foo from '#/foo'
->const foo = require('#/foo')
), without an error or warning.For example, I set a symlink
node_modules/#
->dist
through link-module-alias. So#/foo
is valid on compiled js.So, I let ts compiler check types by looking “paths”, and node find modules by symlinks. Maybe you can read https://dev.to/larswaechter/path-aliases-with-typescript-in-nodejs-4353 if you want.
What I suggest is, of course, different from
tsc
’s behavior. Though ts compiler compiles modules aliases as-is, ts-node-dev should dynamically stitch ts files by looking “baseUrl” and “paths”. This only requires reading tsconfig.json and doing some regex, so I guess It’d be not a big deal.Sometimes, project structure gets deeper and wider, so using absolute path provides significant benefit. If ts-node-dev doesn’t care them, people using aliases have to find other ways like the “workaround” I suggested. And what we should consider is, people negatively feel to fragmented setting. They prefer setting as consistent as possible through projects, no matter big or small. If ts-node-dev doesn’t support, then they might just avoid using it at all even on projects without aliases.
P.S.
“strange”…? Hmm, why? Well, I personally think it’s also a quite good approach. There would be pros and cons.
pros
tsc --watch
is stable, so straight-forward and beginner-friendly.tsc --watch --incremental
supports both ones.)cons
tsc -w
) is completed, which would cause an initial error message printed. (However, it’s actually not a problem as it would be restarted automatically just after .ts modules are all compiled.)It works smoothly. jjangga0214/ts-boilerplate is a working example. You can clone it, run
yarn/npm dev
, and then edit .ts files. Then it would automatically restart the node process seamlessly.