(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.
cc @arcanis from https://github.com/TypeStrong/ts-node/issues/697.
@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?
Most helpful comment
@jamonholmgren ~You can pass
cwd: __dirnameand have it resolvetypescriptrelative togluegun.~ 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
cwdfrom registration right now. Sorry, mixed up with the other CLIs I work on. How would you feel about a feature to override thecwdfor compiler registration? Also, the other thing you can do is passcompiler: require.resolve('typescript', { paths: [__dirname] }). Can you try this and see if it resolves your use-case?