node.js - sökvägar från tsconfig.json fungerar inte efter tsc


I mitt Express-projekt importerar jag från sökvägar som @common/foo. Tack vare paths i tsconfig.json är det bara en alias till ../common/src/foo. Det är fantastiskt och fungerar i utveckling med detta skript i nodemon.json:

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

Problemet är att jag inte kan få det att fungera i produktionsläge.

Jag bygger projektet med tsc, och om jag undersöker de genererade filerna, importerar de saker från @common/ och inte från ../common/src/. Till en början trodde jag att det var okej, eftersom tsconfig-paths fungerar vid körning, så jag behöver bara inkludera det i start-skriptet på följande sätt:

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

Tyvärr fungerade det inte, och jag får de där Cannot find module '@common/foo'-felmeddelandena i konsolen.

Vad är problemet? Har jag konfigurerat det fel?

Min package.json (har tagit bort alla irrelevanta delar):

{
  "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"
  }
}

Min tsconfig.json (har tagit bort alla irrelevanta delar):

{
  "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"
    }
  ]
}

Svar #1

för alla som fortfarande sitter fast på detta:

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

detta är vad du behöver göra.

Svar #2

Detta frågades runt på många ställen, och tydligen kan Typescript skapa sökvägsalias för utveckling, men inte för produktion (Citat mig inte på det, har arbetat med det i knappt en månad).

För att komma runt det installerade jag 'module-alias', ett paket som löser sökvägsproblemet efter byggandet, utan att störa utvecklingen.

Jag byggde en Express-js-app och hade dessa filer:

server.js:

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

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

tsconfig.json (relevanta delar):

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

Detta löste sökvägen under utvecklingskörning, men inte efter att ha byggt med 'tsc'. För att kringgå det lade jag till paketet 'module-alias' och gjorde följande ändringar:

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`,
});

Detta säkerställde att @env skulle lösas både under utvecklingskörning och efter byggandet. Hoppas det hjälper!

Relaterade artiklar