ts-loader: Build fails if importing a component from node_modules library

I added a custom library from node_modules (something like: node_modules/@my-lib) imported a typescript component from this library in my code with: import { MyComponent } from '@my-lib/component/my-component';

The typescript loader fails with the following message: Module build failed: Error: Typescript emitted no output for /Users/.../my-app/node_modules/@my-lib/component/my-component.ts at Object.loader (/Users/.../my-app/node_modules/ts-loader/index.js:456:15).

ts-loader version: 0.8.2 webpack version: 1.13.1 tsc version: 1.8.10

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 21
  • Comments: 48 (27 by maintainers)

Most upvoted comments

Unfortunately shipping js/d.ts files is not a solution for me. I have 2 private repositories:

  • project-web
  • project-common

Both repos are written in Typescript. project-web depends on project-common so I decided to fetch project-common github repository by using npm and just do something like this in project-web:

import { CommonComponents } from 'project-common'

The problem is that I can’t provide precompiled js/d.ts (mainly because of inlining sass files in ts files which is handled by webpack like: { styles: [require('sample.sass')] } so I need to bundle/compile two pure TS repos together to one bundle file (one comes from node_modules). Of course error occurs. The funny thing is that it occurs randomly… Any solutions?

ERROR in ../~/project-common/index.ts
Module build failed: Error: Typescript emitted no output for /Users/kpudlik/project-web/node_modules/project-common/index.ts
    at Object.loader (/Users/kpudlik/project-web/node_modules/ts-loader/index.js:458:15)
 @ ./app/app.module.ts 3:26-54

I get so many issues on this I’m wondering about enabling this behaviour behind an opt-in flag

Execute the foowing command line :

npm install typescript@1.8.10 -g
npm install typescript@1.8.10 -D
npm install typescript@1.8.10

It will install typescript v1.8.10 as global package, dev dependencies package and local package.

OK - if someone wants to put together a PR which enables this I’ll happily take a look.

Ideal implementation:

  • New allowTsInNodeModules option for ts-loader that, if true does not perform the check that leads to throwing the You should not need to recompile .ts files in node_modules message here

  • Suffix the existing You should not need to recompile .ts files in node_modules... message with advice on how to opt into using this. Something suitably “warning-y” like But if you really want to do this; use the allowTsInNodeModules option

Don’t worry about fixing the tests; I can help with that.

Advice to any library authors shipping .ts files as the main way for ts consumption: I did the same for typestyle as an experiment and the results were not satisfactory and will never go there again. Reasons covered here : https://github.com/typestyle/typestyle/releases/tag/v0.7.0 Suggest you use outDir + .js + .d.ts as well 🌹 ❤️

@johnnyreilly https://github.com/skysteve/ts-bug-example-2 is about the simplest example I could get. Let me know if you need any more details, but certainly on my mac on node v 6.6 I can replicate the issue.

Update

If I update the tsconfig.json file to remove the “allowJS” flag, the error seems to go away (branch https://github.com/skysteve/ts-bug-example-2/tree/disallow-js). Which is fine in this simple project, but in my real world project I need to mix JS and TS so that’s not a proper fix

I have the lost the will to implement it and would not recommend anyone to write a package that ships .ts + .js and instead people should use outDir + .d.ts + .js.

Again for those interested reasons, the following bad things happen if you ship .ts + .js files :

  • If your package is used in nodejs by someone using outDir, your package messes up other peoples outDir option.
  • As new stricter TypeScript compiler options are implemented they cannot be used by people that use your package unless you update your package to compile with those options as well.

Help wanted 🌹

We can provide an additional error message if path contains node_modules that says:

Since the file is in node_modules you should not need to recompile .ts files in node_modules and should contact the package author to request them to use --declaration --outDir. More https://github.com/TypeStrong/ts-loader/issues/278

@ritmos yes, something similar ended up being the issue for me, not a bug with ts-loader after all

Hello dear typescripters. The issue is not because of ts-loader, but because tsc defaults to exclude node_modules folder (https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). They have a bad example showing how to exclude files with “node_modules” in it which leads to confusion. I have oppened an issue for that.

In any case, in order to allow ts-loader consume typescript source files directly from node_modules: edit tsconfig.json and add all the needed packages there. Like for example:

tsconfig.json

{
"compilerOptions": { },
"include": [
   "node_modules/@company", // all modules bellow from the company will be available
   "node_modules/@company/module", // specific module from the company
    "node_modules/module" // specific module
  ]
}

Another option that also worked in my case is to set ts-loader option transpileOnly to true

For an NPM package, if we ship js files in tsconfig.json’s outDir (e.g., dist/ or build/) and ship ts files in src, would this still mess up other people’s outDir option? (I hope not.)

No. Be sure to add typings path to your package.json 🌹

I’m not sure if it is relevant. But https://github.com/laco0416/light-ts-loader 's approach is quite interesting. It skips all type checking at build time. (Checking is done in editor or separate tsc call).

Maybe you can try the transpileOnly flag in ts-loader.

FWIW it might be worth turning your findings into a blog post (if you’re so minded). It’s always an idea to spread the word when it comes to good practice and it seems like this is still new territory. Have you any idea if the TypeScript team have published any thoughts on this?

Can’t stop thinking of this:

Somewhat overplayed I’m sure 😄

@johnnyreilly the lesson was painful. But the setup isn’t:

  • tsconfig
  • code in src/
  • outDir in lib/
  • Done 🌹