Ts-node: Importing a file outside of the project folder causes: Emit skipped error

Created on 24 Sep 2018  Â·  27Comments  Â·  Source: TypeStrong/ts-node

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"
  ]
}
bug

Most helpful comment

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.

All 27 comments

@DustinJSilk Do you have an example that could be referenced? Also, what version of ts-node and arguments are you using?

I was using version 7.0.1, with typescript 2.9.2 and without any arguments so it would have been default.

I can upload an example tomorrow evening and will send you a link. I switched to compiling down with just tsc in the meantime and dont have a branch with the original ts-node setup at the moment

I got the "Emit skipped" error when trying to compile TypeScript code which was not under the 'rootDir' (tsconfig.json).

@bennyn Thanks for following up! Can you include the version (ts-node and typescript), your tsconfig.json and the file your tried importing? Does this compile with tsc?

@blakeembrey I have used the latest and greatest:

  • typescript v3.3.3
  • ts-node v8.0.2
  • mocha v5.2.0

My tsconfig.json looks like this:

{
  "compilerOptions": {
    "module": "commonjs",
    "moduleResolution": "node",
    "outDir": "dist",
    "rootDir": "src",
    "target": "es5"
  },
  "exclude": [
    "dist",
    "node_modules"
  ]
}

I tried to use ts-node for my mocha tests which were located in ./test but my rootDir was set to ./src so the following command failed with the message "Emit skipped":

mocha --bail --require ts-node/register --reporter spec test/main/*/.ts

I have to admit that the error message sounded a little cryptic to me so I tried to run tsc and tsc failed too and gave me the hint that some of my TS files (the test code) is not in my rootDir, so I moved my tests from ./test to ./src/test and adjusted my mocha script:

mocha --bail --require ts-node/register --reporter spec src/test/main/*/.ts

Now everything works like expected. 😃

From experimentation this appears to be happening when using ts-node --files with rootDir. I suspect related to the explanation here https://github.com/Microsoft/TypeScript/issues/9858

I am getting this same error within my project.
I don't even have a 'rootDir' in my tsconfig.json file

{
    "compilerOptions": {
        "allowJs": true,
        "target": "es2015",
        "moduleResolution": "node",
        "allowSyntheticDefaultImports": true,
        "module": "es2015",
        "sourceMap": false,
        "listEmittedFiles": true,
        "alwaysStrict": true,
        "esModuleInterop": true,
        "resolveJsonModule": true,
        "skipLibCheck": true
    },
    "include": [
        "lib/**/*",
        "bin/*",
        "tests/*.test.*"
    ],
    "exclude": [
        "node_modules",
    ]
}

Simply tried to do a

USWHBML00208269:umgc_node_api baindor$ node --experimental-modules -r esm -r ts-node/register ./bin/launch.ts

/Users/baindor/projects/umgc_node_api/node_modules/ts-node/src/index.ts:365
        throw new TypeError(`${relative(cwd, fileName)}: Emit skipped`)
              ^
/Users/baindor/projects/umgc_node_api/node_modules/ts-node/src/index.ts:1
TypeError: lib/HealthChecks/LinkHealthCheck.js: Emit skipped
    at getOutput (/Users/baindor/projects/umgc_node_api/node_modules/ts-node/src/index.ts:365:15)
    at Object.compile (/Users/baindor/projects/umgc_node_api/node_modules/ts-node/src/index.ts:395:32)
    at Object.m._compile (/Users/baindor/projects/umgc_node_api/node_modules/ts-node/src/index.ts:473:43)
    at Module._extensions..js (internal/modules/cjs/loader.js:879:10)
    at Object.require.extensions.<computed> [as .js] (/Users/baindor/projects/umgc_node_api/node_modules/ts-node/src/index.ts:476:12)

It's strange because we have this working with esnext as the compile target and module target and then using gulp and babel as such:

gulp && pm2-runtime start --node-args='--experimental-modules --use_strict --no-warnings --require=@babel/register' bin/launch.js

But I want to skip the gulp step, and babel altogether and compile directly down to es2015 from typescript.

I found a combination that worked for me, something about allowJs broke it:
tsconfig.json

{
    "compilerOptions": {
        "allowJs": false,
        "target": "ES6",
        "moduleResolution": "node",
        "allowSyntheticDefaultImports": true,
        "module": "commonjs",
        "sourceMap": false,
        "listEmittedFiles": true,
        "alwaysStrict": true,
        "esModuleInterop": true,
        "resolveJsonModule": true,
        "skipLibCheck": true
    },
    "include": [
        "lib/**/*",
        "bin/*",
        "tests/*.test.*"
    ],
    "exclude": [
        "node_modules",
    ]
}

Im getting this error when I just try to add typeRoots because of this issue: https://github.com/TypeStrong/ts-node/issues/745

I add
"typeRoots": ["./src/types","../../node_modules/@types"]

I have this tsconfig:

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "./dist",
    "moduleResolution": "node",
    "jsx": "react",
    "esModuleInterop": true,
    "typeRoots": ["./src/types","../../node_modules/@types"]
  },
  "include": [
    "./src"
  ],
  "exclude": [
    "../../node_modules", "node_modules"
  ],
}

and this as root

{
  "compilerOptions": {
      "allowJs": true,
      "module": "commonjs",
      "target": "ES2017",
      "sourceMap": true,
      "strict": true,
      "noFallthroughCasesInSwitch": true,
      "noImplicitReturns": true,
      "noEmitOnError": true
  },
  "exclude": [
      "node_modules"
  ]
}

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

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 get Emit skipped error when "allowJs": true is true too

https://github.com/bluelovers/is-req-https

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.

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

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.

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

@marchand-software Are you saying you have two files with exactly the same filename except for the file extension? For example, foo.js and foo.ts? That's what the comment was referring to.

@cspotcode yes, correct. It seems easiest for my project structure to duplicate the .js file and convert it to .ts but leaving the .js file for all other existing .js files that require it.

Essentially what I'm trying to do is work backwards on my dependency graph and eventually be able to delete all the .js files

@marchand-software are all your require statements including file extensions? Are you doing require('./foo.js') instead of require('./foo')? If so, why is the extension needed?

@cspotcode correct again. _Well, kind of..._ I was mistakenly using a mix of both ways you mentioned... I tried changing all require('./foo.js') to require('./foo') given the nature of your comment.

Still getting the same Emit skipped error.

@marchand-software If you change to require('./foo') then everything can load the .ts file. So you can delete the .js file.

@cspotcode nailed it. Thanks a bunch. I was mislead into thinking .js files couldn't require/import .ts files...

I have a similar problem while trying to import a .json file without resolveJsonModule: true in tscofig.json. I'm using this setup to be able to import JSON files from outside he rootDir. It works fine with tsc, and if I add resolveJsonModule: true in tsconfig.json, it fails with '../lib/settings.json' is not under 'rootDir'. So resolveJsonModule: true must not be in tsconfig.json.

When I run ts-node on a file that depends on settings.json, I get this error from ts-node:

TSError: ⨯ Unable to compile TypeScript:
src/modules/MyModule.ts(21,27): error TS2732: Cannot find module '../../../lib/settings.json'. Consider using '--resolveJsonModule' to import module with '.json' extension

Nice one @bennyn, that was my problem

require('path without extension') does not work for Webpack, because webpack requires setting rules for each extensions. For example, .ts => handled by ts-loader, anything else is handled by raw loader.
So, if I do require('path without extension'), then it will go to raw loader to be handled.
Path with extension still need to be supported by 'require' in order for it to work properly in webpack.

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.

I know we have "thumbs up" for this, but thank you @jordanrastrick !

From experimentation this appears to be happening when using ts-node --files with rootDir. I suspect related to the explanation here microsoft/TypeScript#9858

The solution for me was removing rootDir

From experimentation this appears to be happening when using ts-node --files with rootDir. I suspect related to the explanation here microsoft/TypeScript#9858

The solution for me was removing rootDir

Also fixed by removing rootDir.

I have a repo with two packages (let's call them a and b).

I use yarn workspaces to be able to use package b as a dependency on package a.

When package a imports from package b, it is importing the generated js files under dist (basically as if it was importing from most packages available using yarn add/npm install).

I set up some tests on package a. When I run them using ts-node I get the error:

TypeError: ../b/dist/index.js: Emit skipped

It would seem that ts-node is resolving the symbolic link that yarn sets up pointing to package b 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 package a.

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

Was this page helpful?
0 / 5 - 0 ratings