Ts-node: Change in 8.0 - TypeScript not resolved globally

Created on 23 Jan 2019  ยท  12Comments  ยท  Source: TypeStrong/ts-node

(I looked at #764 and, while I believe it's related, I think my issue is more specific and replicable.)

In my CLI Gluegun, if I have [email protected] it works fine. If I upgrade to 8.0.1, I get this error:

โฏ gluegun
Error: Cannot find module 'typescript'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:603:15)
    at Function.resolve (internal/modules/cjs/helpers.js:28:19)
    at Object.register (/Users/jh/Code/Node/gluegun/node_modules/ts-node/src/index.ts:208:28)
    at Object.<anonymous> (/Users/jh/Code/Node/gluegun/bin/gluegun:19:22)
    at Module._compile (internal/modules/cjs/loader.js:721:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:732:10)
    at Module.load (internal/modules/cjs/loader.js:620:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
    at Function.Module._load (internal/modules/cjs/loader.js:552:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:774:12)

The only change is bumping the ts-node version.

(Note this is only when running locally.)

Steps to reproduce

git clone https://github.com/infinitered/gluegun.git
cd ./gluegun
yarn
yarn upgrade [email protected]
yarn link
cd ..
gluegun
# observe that it works fine
cd ./gluegun
yarn upgrade [email protected]
cd ..
gluegun
# observe error

(Note that it _does_ work fine as long as you run the binary _inside_ the gluegun folder.)

This seems like a regression to me, unless there's something I missed in the release notes that I should have done.

Most helpful comment

@jamonholmgren ~You can pass cwd: __dirname and have it resolve typescript relative to gluegun.~ It's hard to say if this is expected behaviour but I'm leaning towards yes, even though it is a change between 7 and 8 (but that's what major version changes are for, right).

Edit: Whoops, no you can't change cwd from registration right now. Sorry, mixed up with the other CLIs I work on. How would you feel about a feature to override the cwd for compiler registration? Also, the other thing you can do is pass compiler: require.resolve('typescript', { paths: [__dirname] }) . Can you try this and see if it resolves your use-case?

All 12 comments

@jamonholmgren This is a feature and, I believe, how it was intended to work. It sounds like you're relying on typescript being co-located with ts-node. Is there any way you can rely on typescript being in a different location? Can you describe how it uses ts-node and maybe we can find a workaround that works for all use-cases?

@blakeembrey Here is a minimal CLI that exhibits the same behavior:

https://github.com/jamonholmgren/tsdemo

The CLI I'm working on is much more complex than that, but you can take a look at it too:

https://github.com/infinitered/gluegun/blob/f85dac357d66f7ad44940b26e8eacca4b2d89f4b/bin/gluegun#L19

I have same issue here with typescript installed globally in Docker:

> ts-node ./lib/server.ts

Error: Cannot find module 'typescript'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
    at Function.resolve (internal/modules/cjs/helpers.js:32:19)
    at Object.register (/usr/local/lib/node_modules/ts-node/src/index.ts:208:28)
    at Object.<anonymous> (/usr/local/lib/node_modules/ts-node/src/bin.ts:108:17)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
npm ERR! code ELIFECYCLE
npm ERR! errno 1

Docker install error with ts-node:

Step 3/6 : RUN npm install -g typescript
 ---> Running in 3f1f32de6b7b
/usr/local/bin/tsc -> /usr/local/lib/node_modules/typescript/bin/tsc
/usr/local/bin/tsserver -> /usr/local/lib/node_modules/typescript/bin/tsserver
+ [email protected]
added 1 package from 1 contributor in 2.642s
Removing intermediate container 3f1f32de6b7b
 ---> 09f7d5c94179
Step 4/6 : RUN npm install -g ts-node
 ---> Running in 9f64cad9eb11
/usr/local/bin/ts-node -> /usr/local/lib/node_modules/ts-node/dist/bin.js
npm WARN [email protected] requires a peer of typescript@>=2.0 but none is installed. You must install peer dependencies yourself.

+ [email protected]
added 9 packages from 42 contributors in 1.79s
Removing intermediate container 9f64cad9eb11
 ---> 798210c18452

@Antarian You need to install typescript locally.

@jamonholmgren ~You can pass cwd: __dirname and have it resolve typescript relative to gluegun.~ It's hard to say if this is expected behaviour but I'm leaning towards yes, even though it is a change between 7 and 8 (but that's what major version changes are for, right).

Edit: Whoops, no you can't change cwd from registration right now. Sorry, mixed up with the other CLIs I work on. How would you feel about a feature to override the cwd for compiler registration? Also, the other thing you can do is pass compiler: require.resolve('typescript', { paths: [__dirname] }) . Can you try this and see if it resolves your use-case?

@blakeembrey Could you mention this in README installation part of project?
I already solved this by local installation, but many tutorials on web are going with global typescript and ts-node install.

@Antarian Sure, would you like to make a PR with the changes you think are appropriate to https://github.com/TypeStrong/ts-node#installation?

I know its doing it wrong, but pm2 installs ts-node and typescript itself, outside of a project's npm stuff. I had been trying to figure out why it stopped working for the past week until today and saw this issue. Quite frustrating. How do you propose installing in that case?

@blakeembrey That worked! Thank you for the fix.

Here's the diff:

https://github.com/infinitered/gluegun/commit/8b12bdbf9bae9bce2ecefa2bfc781cdbc1965204

And the code in question:

  // hook into ts-node so we can run typescript on the fly
  require('ts-node').register({
    project: `${__dirname}/../tsconfig.json`,
    compiler: require.resolve('typescript', { paths: [__dirname] }),
  })

I will close this now since my problem is fixed. If people can't use the solution posted just above here, please open a new issue.

Thanks @blakeembrey. Changing { paths: [cwd] } (BTW, is this by design?) to { paths: [cwd, __dirname] } would make me able to contribute ts-node to Homebrew as a global cli. Is there any way to fix it as you have mentioned?

https://github.com/TypeStrong/ts-node/blob/74147523da8853a41b70bf04578125e2d6f84731/src/index.ts#L195

Was this page helpful?
0 / 5 - 0 ratings

Related issues

max-block picture max-block  ยท  4Comments

watzon picture watzon  ยท  3Comments

nehalist picture nehalist  ยท  3Comments

JoseLion picture JoseLion  ยท  3Comments

remojansen picture remojansen  ยท  4Comments