Skip to content

TSC fails to emit required files when run below node_modules #28432

Open
@yofreke

Description

@yofreke

TypeScript Version: 3.2.0-dev.20181107

Search Terms: node_modules

Code

/tmp/node_modules/tsc-test/tsconfig.json

{
  "compilerOptions": {
    "outDir": "dist"
  },
  "files": [
    "src/index.ts"
  ]
}

/tmp/node_modules/tsc-test/src/index.ts

import { A } from './A';

export const main = () => {
  console.log('A=', A);
};

/tmp/node_modules/tsc-test/src/A.ts

export const A = 'A';

Expected behavior:

Output files:

  • /tmp/node_modules/tsc-test/dist/index.js
  • /tmp/node_modules/tsc-test/dist/A.js

Actual behavior:

Output files:

/tmp/node_modules/tsc-test/dist/index.js

"use strict";
exports.__esModule = true;
var A_1 = require("./A");
exports.main = function () {
    console.log('A=', A_1.A);
};

No A.js is output

Notes:

I wanted to build a typescript project as part of an npm postinstall script, to enable installation from npm or from git. In the case of installation from npmjs, dist/ will already exist. In the case of installation from git, dist/ will be missing and build will be run.

After setting this up, I noticed that only files listed in my tsconfig files list were being emitted when installing from git. I looked around for tsconfig or tsc options that may change this behavior, but realized it probably had to do with 'node_modules' being in the path.

I debugged the issue by modifying the built tsc.js. In my case, the problematic code is in nodeModuleNameResolverWorker/tryResolve, specifically here:

const { path: candidate, parts } = normalizePathAndParts(combinePaths(containingDirectory, moduleName));
const resolved = nodeLoadModuleByRelativeName(extensions, candidate, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true);
// Treat explicit "node_modules" import as an external library import.
return resolved && toSearchResult({ resolved, isExternalLibraryImport: contains(parts, "node_modules") });

The call to contains(parts, "node_modules") should likely consider the project root directory, and ignore "node_modules" in the path parts above the root.

Metadata

Metadata

Assignees

No one assigned

    Labels

    In DiscussionNot yet reached consensusSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions