ts-loader: webpack with project references: ERROR TS6059: xxx is not under 'rootDir'

Trying to migrate our multiple typescript projects to monorepo by using project references. Everything seems to be fine, but in one project when running through ts-loader (5.3.3) I get this strange error:

ERROR in /Users/gytis/work/front/portal/tsconfig.json
[tsl] ERROR
      TS6059: File '/Users/gytis/work/front/icons/src/FaIcon.tsx' is not under 'rootDir' '/Users/gytis/work/front/portal/app'. 'rootDir' is expected to contain all source files.

If I simply do run tsc -b tsconfig.json on the same project - all ok, no errors. I’ve tried looking at output with traceDependencies, but it does seem ok to me:

======== Resolving module './FaIcon' from '/Users/gytis/work/front/icons/dist/index.d.ts'. ========
Module resolution kind is not specified, using 'NodeJs'.
Loading module as file / folder, candidate module location '/Users/gytis/work/front/icons/dist/FaIcon', target file type 'TypeScript'.
File '/Users/gytis/work/front/icons/dist/FaIcon.ts' does not exist.
File '/Users/gytis/work/front/icons/dist/FaIcon.tsx' does not exist.
File '/Users/gytis/work/front/icons/dist/FaIcon.d.ts' exist - use it as a name resolution result.
======== Module name './FaIcon' was successfully resolved to '/Users/gytis/work/front/icons/dist/FaIcon.d.ts'. ========

tsconfig.json is pretty simple:


{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "declaration": false,
    "allowSyntheticDefaultImports": true,
    "jsx": "react",
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "sourceMap": true,
    "strictNullChecks": false,
    "alwaysStrict": false,
    "rootDir": "app",
    "outDir": "dist"
  },
  "exclude": [
      "server", "dist"
  ],
  "references": [
    { "path": "../itinerary-view/" },
    { "path": "../grid/" },
    { "path": "../header/" },
    { "path": "../form/" },
    { "path": "../icons/" },
    { "path": "../item-card/" },
    { "path": "../commons/" },
  ]
}

Webpack ts-loader entry also is ordinary:

 { test: /\.tsx?$/, loader: 'ts-loader', options: {
        configFile:  path.resolve(__dirname, "tsconfig.json")
        }
      } 

Any hints how I could troubleshoot this?

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 7
  • Comments: 16 (6 by maintainers)

Most upvoted comments

My solution:

Delete rootDir config from tsconfig.json.

So after almost 2 hours of fucking around with this, I think I’ve solved it (at least for anyone using electron-webpack…). If you are using said package and you’re using typescript they kindly have a package you can add called electron-webpack-ts which adds the ts-loader in for you, so kind! They also allow you to specify the key webpackConfig in the electron-webpack.json file to do manual overrides of the config, again so kind!

The issue is, the ts addon is loaded in after that file is run, causing any overrides you make to be overriden, which is not so kind. The way I got round it was by ditching electron-webpack-ts entirely, and just importing it myself in the override file, like so;

/* eslint-disable no-param-reassign, @typescript-eslint/no-var-requires */

const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');

module.exports = {
	target: 'electron-main',
	resolve: {
		extensions: ['.ts'],
		plugins: [
			new TsconfigPathsPlugin(),
		],
	},
	module: {
		rules: [{
			test: /\.ts$/,
			loader: 'ts-loader',
			options: {
				projectReferences: true,
			},
		}],
	},
};

They also supply 3 other items into the options for you, namely transpileOnly, appendTsSuffixTo, and configFile. I’ve elected to ignore all three here as I don’t think they really make sense for my use case, but they may for you so add them back if you wish.

It’s times like this I wish I’d never gotten into this god forsaken job.

Hmm, it looks like ts-loader isn’t recognizing that front/icons is a project reference. Is there anything different about that composite project’s structure or configuration? Honestly the only way I could troubleshoot something like this is by debugging, setting breakpoints in ts-loader itself. If you can share your repo, or a repo that reproduces the same problem, I can help with that. If you want to try it yourself, you can do so like this:

  1. instead of running webpack {arguments}, run node --inspect-brk node_modules/webpack/bin/webpack.js {arguments}
  2. use your favorite debugger (e.g. VS Code, ndb) to connect to the paused node process you just started
  3. set a breakpoint in node_modules/ts-loader/dist/index.js on the equivalent of this line. The line numbers will be different since this is transpiled JS, but it should be quite readable. https://github.com/TypeStrong/ts-loader/blob/c1f3c4e69975497692e362cf8ef97e5be9840ff6/src/index.ts#L74

You can use a conditional breakpoint or continue until filePath refers to something in front/icons. Then step in and you should be able to narrow down why getAndCacheProjectReference seems to be returning undefined.

I ran into a similar issue. First, let me define here the scenario: I had project client, which uses webpack to compile. client was referencing project files code-lib. Then, project server-tests from which I wanted to reference client code, to test it. In order to reference the code, I had to set the client project as composite=true, but the moment I did that, the webpack no longer compiled the client project, having an error ERROR TS6059. The error stated, that file from referenced code-lib was not under client project root. Which it really was not. So it seemed that the webpack did not recognize the referenced projects. I did some digging, and looked at other webpack.jsons from other stackoverflow problems. Then, I tried to set the webpack.json as

        rules: [{
            test: /\.ts$/,
            use: {
                loader: 'ts-loader',
                options: {
                    "projectReferences": true
                }
            },
            exclude: [
                /node_modules/,
                '/src/index.ts'
            ]
        },
        {
            test: /\.(scss)$/,
            use: ['style-loader', 'css-loader', 'sass-loader']
        }]
    }

So, I added this part to the ts-loader: options: { "projectReferences": true }

And luckily, it worked. This may help future people.

Thanks for sharing your findings @0xdeafcafe

It’s times like this I wish I’d never gotten into this god forsaken job.

I am sorry for your pain.

Also, hello fellow Londoner!