Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

paths option(tsconfig.json) is ignored #95

Closed
jjangga0214 opened this issue Sep 19, 2019 · 18 comments
Closed

paths option(tsconfig.json) is ignored #95

jjangga0214 opened this issue Sep 19, 2019 · 18 comments

Comments

@jjangga0214
Copy link

jjangga0214 commented Sep 19, 2019

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.

@jjangga0214
Copy link
Author

jjangga0214 commented Sep 19, 2019

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).

npm uninstall ts-node-dev
npm install concurrently node-dev --save-dev

Then run

concurrently 'tsc -w' 'node-dev --respawn dist/index.js'

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 now tsc respects the "paths" option.

@wclr
Copy link
Owner

wclr commented Sep 19, 2019

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

@jjangga0214
Copy link
Author

jjangga0214 commented Sep 19, 2019

@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.

TS compiler doesn't transform require paths like '#/foo', so it should just give the error Cannot find module '#/foo'

The compiler doesn't transform but compiles it "as-is"
(import foo from '#/foo' -> const foo = require('#/foo')),
without an error or warning.

Should this even work with node.js without special plugins?

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.

This is strange "workaround" =)

"strange"..? Hmm, why?
Well, I personally think it's also a quite good approach. There would be pros and cons.

pros

  • Able to choose tools we prefer. concurrently, npm-run-all, parallelshell, node-dev, nodemon, forever, pm2 or whatever.
  • tsc --watch is stable, so straight-forward and beginner-friendly.
  • Able to compose various options of different tools by ourselves. It can be more fine-grained than options ts-node-dev provides.
  • More closer to production-like condition. Node process would directly and statically consume the entire file system source code is in. (While this logcally doesn't neccessarily mean ts-node-dev has a disadvantage.)
  • Incremental compilation can be enabled. (I know ts-node-dev supports "dynamic" watching compilation, but don't know if it supports "static" incremental compilation. But tsc --watch --incremental supports both ones.)

cons

  • node process could start before compilation(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.)
  • tsc compiles even when 'modules entrypoint (e.g. index.ts) does not depend on' (e.g. test files) changes. (But this is very unlikey because there's generally no reason to place such a file without "excluding" it on tsconfig.)
  • Maybe it looks not so "neat" ?

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.

@wclr
Copy link
Owner

wclr commented Sep 21, 2019

tsc --watch creates *.js files, which ts-node (not ts-node-dev, but ts-node) was created to avoid.

If you ok with this *.js filles all around while dev, it is just another approach.

Also I prefer to use yarn workspaces instead of tsconfig paths and other "workarounds" like mentioned link-module-alias.

@jjangga0214
Copy link
Author

jjangga0214 commented Sep 22, 2019

@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?

@wclr
Copy link
Owner

wclr commented Sep 22, 2019

This 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.

@jjangga0214
Copy link
Author

jjangga0214 commented Sep 26, 2019

Closing this issue. Thanks for the suggestion anyway :)

@microcipcip
Copy link

microcipcip commented Nov 5, 2019

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:

- build/                 // Here is the typescript outDir folder
- src/                   // Here is where we have all the app files
- src/index.ts
- src/app.ts
- package.json

Create a src/aliases.ts file like this:

import moduleAlias from 'module-alias';
import path from 'path';

const IS_DEV = process.env.NODE_ENV === 'development';
const rootPath = path.resolve(__dirname, '..', '..');
const rootPathDev = path.resolve(rootPath, 'src');
const rootPathProd = path.resolve(rootPath, 'build');
moduleAlias.addAliases({
  '@src': IS_DEV ? rootPathDev : rootPathProd,
});

Then, in the src/index.ts file, or in whatever is your entry file, add this as first import:

import './aliases'; // MUST BE FIRST!!

// Now you can use the `@src` for absolute imports
import { app } from '@src/app';

Finally, set tsconfig.json like this (mostly to make typescript and your IDE recognise the path):

{
  "compilerOptions": {
     "outDir": "./build/",
     "baseUrl": ".",
     "paths": {
       /* IMPORTANT: this must be the same of 'src/aliases.ts' */
       "@src/*": ["src/*"]
     },    
}

@s-h-a-d-o-w
Copy link

s-h-a-d-o-w commented Jan 24, 2020

@whitecolor I would recommend to add a note about this (also mentioning baseUrl, since one really doesn't have to use paths for things to break) in points of notice in the README.

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 use tsconfig-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 between tsc and ts-node-dev and assumed it was a bug (hence then looking for it here).

@coler-j
Copy link

coler-j commented Nov 4, 2020

@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.

@wclr
Copy link
Owner

wclr commented Nov 4, 2020

Not sure why it may not work, when I used it, it worked ok.

@coler-j
Copy link

coler-j commented Nov 4, 2020

Please disregard. I was a bit confused when running a nextjs customer server, that first passed through ts-node for the server and than passed through webpack for the react code. Think I have it figured out now.

@soupman99
Copy link

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* "

@cyraid
Copy link

cyraid commented Jun 25, 2021

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* "

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 ...

@dennislo
Copy link

dennislo commented Jul 18, 2021

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:

import moduleAlias from 'module-alias'

moduleAlias.addAliases({
  '#v1': __dirname + '/',
  '#v2': __dirname + '/v2'
})

Then, in the src/index.ts file, I added this as first import:

import './aliases'; // MUST BE FIRST!!

// Now you can use the `#v1` for absolute imports
import { app } from '#v1/app';

Inside my tsconfig.json I added this so my IDE can recognise the path:

    "baseUrl": "." /* Base directory to resolve non-absolute module names. */,
    "paths": {
      "#v1/*": ["./src/*"],
      "#v2/*": ["./src/v2/*"]
    } /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */,

I have a dev script inside my package.json file

"dev": "ts-node-dev --respawn --transpile-only ./src",

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:

- build/                 // Here is the typescript outDir folder
- src/                   // Here is where we have all the app files
- src/index.ts
- src/app.ts
- package.json

Create a src/aliases.ts file like this:

import moduleAlias from 'module-alias';
import path from 'path';

const IS_DEV = process.env.NODE_ENV === 'development';
const rootPath = path.resolve(__dirname, '..', '..');
const rootPathDev = path.resolve(rootPath, 'src');
const rootPathProd = path.resolve(rootPath, 'build');
moduleAlias.addAliases({
  '@src': IS_DEV ? rootPathDev : rootPathProd,
});

Then, in the src/index.ts file, or in whatever is your entry file, add this as first import:

import './aliases'; // MUST BE FIRST!!

// Now you can use the `@src` for absolute imports
import { app } from '@src/app';

Finally, set tsconfig.json like this (mostly to make typescript and your IDE recognise the path):

{
  "compilerOptions": {
     "outDir": "./build/",
     "baseUrl": ".",
     "paths": {
       /* IMPORTANT: this must be the same of 'src/aliases.ts' */
       "@src/*": ["src/*"]
     },    
}

@IvanovRoman
Copy link

And ignored baseUrl in tsconfig.json

@fatihaziz
Copy link

fatihaziz commented Sep 24, 2021

my original answer to fix ts-node paths problem here: TypeStrong/ts-node#138

if ts-node-dev also support to read "ts-node" configuration on tsconfig.json, i think it may help

@ndpniraj
Copy link

Thanks @soupman99 it works like charm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests