tsconfig-paths icon indicating copy to clipboard operation
tsconfig-paths copied to clipboard

How can I debug the path resolution?

Open edaqa-uncountable opened this issue 4 years ago • 6 comments

I'm using ts-node with tsconfig-paths. My tsconfig.json file has a baseUrl and paths. My module resolution isn't working and I'm looking for a way that I can debug my setup. Are the options for tsconfig-paths to show which paths it is resolving to?


I use a command-line like this:

node_modules/.bin/ts-node --project ./tsconfig.json -r tsconfig-paths/register test/js/sample.ts

Where there is a paths section in the tsconfig.ts file

  "compilerOptions": {
    "baseUrl": "js",
    "paths": {
      "some_base/*": ["base/*"],
    }

And then I try to import via it:

// this fails
import { checkConstraints } from 'some_base/comp'

// this works (not using path aliases)
import { checkConstraints } from 'base/comp'

edaqa-uncountable avatar Mar 09 '21 08:03 edaqa-uncountable

I'm having a similar issue. I am trying to debug in vscode. If I launch from there or attempt to run from the command line it does not resolve. I have the correct baseUrl and paths and am able to execute in a container, but cannot run locally.

In my case, I am trying to import OrganizationService using the alias, but it resides in the /application-layer/nodejs/services directory.

import {OrganizationService} from '/opt/nodejs/services/organization.service'

tsconfig:

{
    "extends": "@tsconfig/node14/tsconfig.json",
    "compilerOptions": {  
      "baseUrl": ".",
      "paths": {
        "/opt/nodejs/*": [ "api-layer/nodejs/*", "application-layer/nodejs/*", "domain-layer/nodejs/*", "data-layer/nodejs/*", "libraries/nodejs/*"]
      },
      "removeComments": true,
      "preserveConstEnums": true,
      "sourceMap": true,
      "moduleResolution": "node",
      "resolveJsonModule": true,
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "strictPropertyInitialization": false,
      "esModuleInterop": true,
      "allowJs": true
    },
    "include": ["utilities/**/*", "libraries/**/*", "api-layer/**/*", "domain-layer/**/*", "data-layer/**/*", "application-layer/**/*", "**/package.json", "handlers/**/*"],
    "exclude": ["node_modules", "**/*.spec.ts", "**/*.test.ts"]
}

launch.json:

{
    "type": "node",
    "name": "Launch Create Organization",
    "request": "launch",
    "skipFiles": [
        "<node_internals>/**"
    ],            
    "runtimeArgs": [
        "-r",
        "tsconfig-paths",
        "-r",
        "ts-node/register",
    ],
    "args": [
        "${workspaceFolder}/handlers/organization/create-organization/organization.ts"
    ],
    "sourceMaps": true,
    "smartStep": true,
    "env": {
        "NODE_ENV": "development"
    }
}

Running from the command line:

$ node -r ts-node/register -r tsconfig-paths/register handlers/organization/create-organization/organization.ts
Error: Cannot find module '/opt/nodejs/services/organization.service'
Require stack:
- /Users/mtalbert/Projects/Vubi/vubi-api/handlers/organization/create-organization/organization.ts
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:925:15)
    at Function.Module._resolveFilename (/Users/mtalbert/Projects/Vubi/vubi-api/node_modules/tsconfig-paths/lib/register.js:75:40)
    at Function.Module._load (node:internal/modules/cjs/loader:769:27)
    at Module.require (node:internal/modules/cjs/loader:997:19)
    at require (node:internal/modules/cjs/helpers:92:18)
    at Object.<anonymous> (/Users/mtalbert/Projects/Vubi/vubi-api/handlers/organization/create-organization/organization.ts:6:1)
    at Module._compile (node:internal/modules/cjs/loader:1108:14)
    at Module.m._compile (/Users/mtalbert/Projects/Vubi/vubi-api/node_modules/ts-node/src/index.ts:1056:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1137:10)
    at Object.require.extensions.<computed> [as .ts] (/Users/mtalbert/Projects/Vubi/vubi-api/node_modules/ts-node/src/index.ts:1059:12)

mtalbert avatar Mar 28 '21 15:03 mtalbert

Issue 128 looks like the culprit in my case.

mtalbert avatar Mar 28 '21 15:03 mtalbert

Removing the line mentioned in Issue 128 helped me get past the error from the command line, but launching in vscode still cannot resolve the alias. The stack trace would indicate that tsconfig-paths is not being used for resolution:

Screen Shot 2021-03-28 at 11 00 28 AM

mtalbert avatar Mar 28 '21 16:03 mtalbert

Removing the line mentioned in Issue 128 helped me get past the error from the command line, but launching in vscode still cannot resolve the alias. The stack trace would indicate that tsconfig-paths is not being used for resolution:

Screen Shot 2021-03-28 at 11 00 28 AM

I discovered the issue for the vscode execution as well. I had missed the /register portion on tsconfig-paths in my launch.json as seen above.

mtalbert avatar Mar 28 '21 16:03 mtalbert

FWIW when I need to debug module resolution I manually edit node_modules/tsconfig-paths/lib/register.js to include a console.log at the points of interest. For example:

  // ...
  // Patch node's module loading
  // tslint:disable-next-line:no-require-imports variable-name
  const Module = require("module");
  const originalResolveFilename = Module._resolveFilename;
  const coreModules = getCoreModules(Module.builtinModules);
  // tslint:disable-next-line:no-any
  Module._resolveFilename = function (request: string, _parent: any): string {
    console.log(`Module._resolveFilename called`, request, _parent); // <----- added this line (can be pretty noisy)
    const isCoreModule = coreModules.hasOwnProperty(request);
    if (!isCoreModule) {
      const found = matchPath(request);
      if (found) {
        const modifiedArguments = [found, ...[].slice.call(arguments, 1)]; // Passes all arguments. Even those that is not specified above.
        console.log(`Module._resolveFilename found match!`, found, modifiedArguments); // <----- added this line
        // tslint:disable-next-line:no-invalid-this
        return originalResolveFilename.apply(this, modifiedArguments);
      }
    }
    // tslint:disable-next-line:no-invalid-this
    return originalResolveFilename.apply(this, arguments);
  };
  // ...

then I see output like this when running:

Module._resolveFilename called @src/util
Module._resolveFilename found match! /path/to/app/build/src/util [
  '/path/to/app/build/src/util.js',
  Module {
    id: '/path/to/app/build/src/scale.js',
    path: '/path/to/app/build/src',
    exports: {},
    parent: null,
    filename: null,
    loaded: false,
    children: [],
    paths: [
      '/path/to/app/build/src/scale.js/node_modules',
      '/path/to/app/build/src/node_modules',
      '/path/to/app/build/node_modules',
      '/path/to/app/node_modules',
      '/path/to/node_modules',
      '/path/node_modules',
      '/node_modules'
    ]
  },
  false
]

jacobq avatar Sep 10 '21 13:09 jacobq

Removing the line mentioned in Issue 128 helped me get past the error from the command line, but launching in vscode still cannot resolve the alias. The stack trace would indicate that tsconfig-paths is not being used for resolution: Screen Shot 2021-03-28 at 11 00 28 AM

I discovered the issue for the vscode execution as well. I had missed the /register portion on tsconfig-paths in my launch.json as seen above.

Relating to #128, you can change your paths key from "/opt/nodejs/*": [...] to "@/opt/nodejs/*": [...] and also add the "@" for these imports. It seems that a starting '/' is always handled as an absolute path as mentioned in my comment

Cheers Peter

qbasic16 avatar Dec 02 '21 14:12 qbasic16