Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

paths from tsconfig.json doesn't work after tsc

In my Express project, I import from paths like @common/foo. Thanks to paths in tsconfig.json, it's just an alias to ../common/src/foo. That's awesome and works in development with this script in nodemon.json:

{
    "watch": ["src", "../common/src"],
    "ext": "ts",
    "ignore": ["src/public"],
    "exec": "ts-node -r tsconfig-paths/register src/index.ts"
  }

The problem is that I can't make it work in production mode.

I build the project with tsc, and if I inspect the generated files, they import stuff from @common/ and not from ../common/src/. At first I thought it's fine, since tsconfig-paths works in runtime, so I just need to include it in the start script as such:

node -r tsconfig-paths/register dist/index.js

Unfortunately it didn't work, and I get those Cannot find module '@common/foo error messages in console.

What's the problem? Did i configured it wrong?


My package.json (dropped all irrelevant parts):

{
  "main": "index.js",
  "scripts": {
    "start": "cross-env NODE_ENV=prod node dist/index.js",
    "build": "rimraf ./dist/ && cross-env NODE_ENV=prod tsc"
  },
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "@types/express": "^4.17.4",
    "@types/node": "^13.11.0",
    "cross-env": "^6.0.3",
    "rimraf": "^3.0.2",
    "ts-node": "^8.8.2",
    "tsconfig-paths": "^3.9.0",
    "typescript": "^3.8.3"
  }
}

My tsconfig.json (dropped all irrelevant parts):

{
  "compilerOptions": {
    "module": "commonjs",
    "baseUrl": "./",
    "outDir": "dist",
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "noImplicitAny": false,
    "target": "es6",
    "emitDecoratorMetadata": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "types": [
      "node"
    ],
    "typeRoots": [
      "node_modules/@types"
    ],
    "paths": {
      "@common/*": [
        "../common/src/*"
      ]
    }
  },
  "include": [
    "./src/**/*.ts"
  ],
  "exclude": [
    "./src/dist/"
  ],
  "references": [
    {
      "path": "../common"
    }
  ]
}
like image 545
Itay Ganor Avatar asked Apr 21 '20 11:04

Itay Ganor


People also ask

Does TS-node use Tsconfig?

ts-node supports a variety of options which can be specified via tsconfig.

What does Tsconfig spec json do?

The tsconfig. json file specifies the root files and the compiler options required to compile the project. JavaScript projects can use a jsconfig. json file instead, which acts almost the same but has some JavaScript-related compiler flags enabled by default.

Where do I put Tsconfig json?

The tsconfig. json is generally put in the root folder of the project.


2 Answers

for anyone still stuck on this:

node -r ts-node/register/transpile-only -r tsconfig-paths/register dist/index.js

this is what you need to do.

like image 80
hanan hamza Avatar answered Nov 03 '22 19:11

hanan hamza


This was asked around in many places, and apparently Typescript can make path aliases for development, but not production (Don't quote me on that, have been working with it for barely a month).

To work around that, I installed 'module-alias', a package that solves the path issue after build, without interfering with development.

I was building an Express-js app, and had these files:

server.js:

import env from '@env';
import app from './app';

app.listen(env.SERVER_PORT || 3000);

tsconfig.json (relevant parts):

{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "@env": ["path/to/env"]
    }
  }
}

This resolved the path during development runtime, but not after building with 'tsc'. To work around it, I added the 'module-alias' package and did the following changes:

server.js:

import './paths';
import env from '@env';
import app from './app';

app.listen(env.SERVER_PORT || 3000);

paths.js

import 'module-alias/register';
import { addAliases } from 'module-alias';

addAliases({
  '@env': `${__dirname}/path/to/env`,
});

This ensured that @env would resolve in both dev runtime and after building. Hope it helps!

like image 41
Victor Monteiro Cunha Avatar answered Nov 03 '22 17:11

Victor Monteiro Cunha