ts-node: Importing a file outside of the project folder causes: Emit skipped error
Im trying to import a file outside of the project. It’s a shared file between the frontend and the server.
When i try import it it throws this error:
node_modules/ts-node/src/index.ts:370
throw new TypeError(`${relative(cwd, fileName)}: Emit skipped`)
^
TypeError: project/my_file.ts: Emit skipped
at getOutput (/Users/.../node_modules/ts-node/src/index.ts:370:15)
at Object.compile (/Users/.../node_modules/ts-node/src/index.ts:558:11)
at Module.m._compile (/Users/.../node_modules/ts-node/src/index.ts:439:43)
at Module._extensions..js (internal/modules/cjs/loader.js:713:10)
at Object.require.extensions.(anonymous function) [as .ts] (/Users/.../node_modules/ts-node/src/index.ts:442:12)
at Module.load (internal/modules/cjs/loader.js:612:32)
at tryModuleLoad (internal/modules/cjs/loader.js:551:12)
at Function.Module._load (internal/modules/cjs/loader.js:543:3)
at Module.require (internal/modules/cjs/loader.js:650:17)
at require (internal/modules/cjs/helpers.js:20:18)
I’m able to import it from my angular project which is a sibling.
I’ve tried adding the file to my tsconfig under includes and files. This is what my tsconfig looks like:
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/backend",
"rootDir": "./",
"module": "commonjs",
"types": [
"node"
]
},
"files": [
"../lib/shared_file_to_import.ts" // Can't import this file
],
"include": [
"./**/*.ts"
]
}
And this is my tsconfig file that the project extends:
{
"compileOnSave": false,
"extends": "./node_modules/gts/tsconfig-google.json",
"compilerOptions": {
"baseUrl": "./",
"rootDir": ".",
"outDir": "./dist",
"sourceMap": true,
"strict": true,
"strictPropertyInitialization": false,
"declaration": false,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"noImplicitAny": true,
"target": "es5",
"strictNullChecks": true,
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2017",
"dom"
]
},
"include": [
"./lib/shared_file_to_import.ts"
]
}
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 21
- Comments: 41 (4 by maintainers)
Commits related to this issue
- refactor: remove "rootDir" in tsconfig.json avoid "ts-node Emit skipped allowjs" error https://github.com/TypeStrong/ts-node/issues/693 — committed to textlint/textlint by azu 3 years ago
- Drop to support Node.js 10.x (#773) * CI: drop support Node.js 10.x * fix(textlint): update engines field for ESM * style: apply prettier * CI: support Node.js 16 * chore: fix type * c... — committed to textlint/textlint by azu 3 years ago
- Update dependency ts-node to v10.5.0 (#1156) This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [ts-node](https://typestrong.org/ts-node) ([source](http... — committed to Calciumdibromid/CaBr2 by deleted user 2 years ago
Also leaving a comment in case it is useful to someone: this error can also occur if you have
"allowJs": true
and have a stray*.js
file that corresponds to a*.ts
file in your project.I found a combination that worked for me, something about allowJs broke it: tsconfig.json
This actually resolved my problem of running
ts-node
10.1.0FYI: just in case this is useful some someone. using mocha + typescript + node, I received the same error, and it was because I had a .js file that got written next to the source .ts file. Presumably, even though ts-node isn’t writing the .js files out, it detected that one was there and stopped.
I got the “Emit skipped” error when trying to compile TypeScript code which was not under the ‘rootDir’ (tsconfig.json).
Any solution to this other than turning off
allowJs
? Would like to compile both versions (.ts
&.js
) and use each where appropriate. Migrating from JavaScript to TypeScript…i get
Emit skipped
error when"allowJs": true
is true toohttps://github.com/bluelovers/is-req-https
@blakeembrey I have used the latest and greatest:
My
tsconfig.json
looks like this:I tried to use
ts-node
for my mocha tests which were located in./test
but myrootDir
was set to./src
so the following command failed with the message “Emit skipped”:I have to admit that the error message sounded a little cryptic to me so I tried to run
tsc
andtsc
failed too and gave me the hint that some of my TS files (the test code) is not in myrootDir
, so I moved my tests from./test
to./src/test
and adjusted my mocha script:Now everything works like expected. 😃
The solution for me was removing rootDir
@jeanlescure I see, I think our
scope
option is the right choice for you. I put an explanation at the bottom of this comment.The expansion is actually done by
node
. You can see this withrequire.resolve('b')
. I believe either TypeScript diagnostics orts-node
display the error with a relative path for readability, butnode
is the one resolving to an absolute path ending indist/index.js
. Node also follows symlinks by default.ts-node
’s decision to compile is not based on whether the path is relative or not. It’s based on TypeScript’sallowJs
andjsx
options to decide which file extensions are compiled, andts-node
’signore
,skipIgnore
,scope
, andscopeDir
options to decide which paths are allowed.I can understand why your project does not want
ts-node
to compile other modules in the workspace, but that’s not the case for all projects. Some want to write code across the monorepo and test it all viats-node
without needing to recompile anything manually. Understanding your use-case has been helpful for me, so I appreciate the detailed response.How to use scope on your project today
scope
limitsts-node
to compiling files only within a given directory,scopeDir
. In v10scope
andscopeDir
were moved to be API-only options, andTS_NODE_SCOPE
was deprecated (Release notes) However, if this option is important to your project, we can un-deprecate it and allow specifying them via tsconfig and CLI flags.To test this today, I believe you can set env var
TS_NODE_SCOPE=true
and run your code.scopeDir
defaults to yourrootDir
so it should exclude anything in theb
module.If this works for you, please let me know and we can add it to Discussions as an official recipe.
I have a repo with two packages (let’s call them
a
andb
).I use yarn workspaces to be able to use package
b
as a dependency on packagea
.When package
a
imports from packageb
, it is importing the generated js files underdist
(basically as if it was importing from most packages available usingyarn add
/npm install
).I set up some tests on package
a
. When I run them usingts-node
I get the error:It would seem that
ts-node
is resolving the symbolic link that yarn sets up pointing to packageb
as a relative path (hence the../b
in the error) and thus treating that external js as if it was part of the local code.In my case setting
allowJs: false
works to solve the problem, confusingly somehow (?), but it seems to be probably an undesired side-effect, that also restricts me from being able to have js files on packagea
.For now I’m glad to have a workaround.
Hope this helps others and hope it sheds a light on a possible solution for the TypeScript team.
Cheers
I have since fixed this “emit skipped” error, so recent versions of ts-node should not have this issue. It comes from TypeScript in typechecking mode, where TS may typecheck a file and yet refuse to emit JS for it. I now detect when this happens and use an alternative method to emit to JS. The result is: typechecking still works, and this error goes away.
And of course, nothing changes for transpileOnly mode: the error never existed in that mode. So everything still works.
On Tue, Jun 21, 2022, 4:27 AM Daniel @.***> wrote:
I have the same problem as @jeanlescure. Using yarn workspaces,
ts-node
refuses to launch a script importing things from another workspace package, and fails with thisEmit skipped
error.From experimentation this appears to be happening when using
ts-node --files
withrootDir
. I suspect related to the explanation here https://github.com/Microsoft/TypeScript/issues/9858Note that modern versions of ts-node entirely avoid this emit skipped error. We detect when the typechecker skips emit, and we fallback to an alternative transpilation. The end result is that users of modern ts-node never see emit skipped even when typechecking.
It disables type checking, and emit skipped is an issue due to the type checker. It won’t compile files outside the typescript project when it’s type checking them.
@cspotcode scope is exactly what I need. I’ve tested adding
TS_NODE_SCOPE=true
as you suggested, it works, if I change myrootDir
.You’ve hit the nail in the head because I would actually need to have separate
scopeDir
androotDir
. In my case I’m only usingts-node
to run unit tests which are in a separate directory thansrc
(which is myrootDir
), so settingscopeDir
to the directory that contains bothsrc
andunit-tests
by CLI flag ortsconfig.test.json
would be ideal.My vote is for un-deprecate ✋🏼 😄
@cspotcode , as you put it, I’m going to correct you, the assumption is wrong and opposite to what we want 😅
In my case I do not want
b
to be compiled. No compilation is needed becauseb
is already compiled. A workspace in yarn/npm workspaces is a separate package on the project with its own set of compilation scripts and config. As far asa
is concerned,b
should be seen as a dependency just like typescript, react, etc.I think the piece of context missing here is that this is what the import looks like:
There is no relative path, this is something that yarn/npm workspaces allows because in the node_modules directory a symbolic link is created.
So what we are saying is, even though the import suggests that
b
is referring to a package,ts-node
is somehow expanding the import to the relative path the symbolic link points to, and in turn interpreting the import as a relative path, thus trying to compile something it’s not supposed to.I then understand that, with
allowJs
set to false, this allows node to execute theb/dist/index.js
from disk without any compilation. IMHO the logic that allows this should not be attached toallowJs
since I want both to be able to have js files in mya
package and be able to import the symlinked version ofb
without it being compiled (as long as the import implies thatb
is a package and not a relative path to local js code).As this issue is still open I would like to share my piece. Reading this discussion I found this comment with a lot of likes; https://github.com/TypeStrong/ts-node/issues/693#issuecomment-576123718 which also solved my problem.
How did it happen?
I found that I once compiled my project without specifying an outdir that resulted in every TS file being compiled to JS files in the same path, next time I ran the project the throw a
new TypeError('${relative(cwd, fileName)}: Emit skipped')
.Solution
Delete every JS file with the same name in the same directory as the TS file, add
'outDir': "Some/path"
in your tsconfig.json and you are safe. PS: I experienced Webstorm collapse the JS files in the TS file (If they are called the same) in the IDE, you will have to use the explore to delete the JS or expand every TS file.Don’t
Do not do
allowJs: false
to solve this issue, this will literally ignore the TS files and use the compiled JS files, meaning next time you change something in the TS files it won’t use the TS files but the old compiled JS files.Conclusion
It would be awesome if it was possible to add a error message that explained this issue so people don’t have to face this issue since it can be annoying, for use those people that have
allowJs: false
as default because they won’t notice anything besides that their TS projects are not using the latest changes unless they compile every time they change something.@marchand-software If you change to
require('./foo')
then everything can load the .ts file. So you can delete the .js file.