Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: How to resolve absolute modules paths for node.js?

I need modules to be resolved basing on baseUrl so output code is usable for node.js

this is my src/server/index.ts

import express = require('express');
import {port, databaseUri} from 'server/config';

...

and this is my src/server/config/index.ts

export const databaseUri: string = process.env.DATABASE_URI || process.env.MONGODB_URI;
export const port: number = process.env.PORT || 1337;

Running tsc I'm able to compile all files without erros, but output: dist/server/index.js is

"use strict";
var express = require("express");
var config_1 = require("server/config");

...

Resulting with Cannot find module 'server/config' if I'm trying to use it with node dist/sever/index.js.

Why server/config path is not resolved in any way so it would be possible to use compiled code or how to make it resolve it. Or what am I doing or thinking wrong way?

My tsc --version is 2.1.4

This is my tsconfig.json:

{
  "compileOnSave": true,
  "compilerOptions": {
      "baseUrl": "./src",
      "rootDir": "./src",
      "module": "commonjs",
      "target": "es5",
      "typeRoots": ["./src/types", ".node_modules/@types"],
      "outDir": "./dist"
  },
  "include": [
      "src/**/*"
  ],
  "exclude": [
      "node_modules",
      "**/*.spec.ts"
  ]
}

Note I don't want to use ../../../../relative paths.

like image 493
Adam Pietrasiak Avatar asked Dec 15 '16 19:12

Adam Pietrasiak


1 Answers

This post on Microsoft's typescript github explains their module resolution process. In the comments they explain that what you're trying to do can't be done.

this feature, along with the rest of the module resolution capabilities, are only to help the compiler find the module source given a module name. no changes to the output js code. if you require "folder2/file1" it will always be emitted this way. you might get errors if the compiler could not find a folder2/file1.ts, but no change to the output. https://github.com/Microsoft/TypeScript/issues/5039#issuecomment-206451221

and

The compiler does not rewrite module names. module names are considered resource identifiers, and are mapped to the output as they appear in the source https://github.com/Microsoft/TypeScript/issues/5039#issuecomment-232470330

So, the emitted JS from typescript does NOT rewrite the module path for the discovered modules you give to require. If you run your app in node after compilation (which it looks like you are with express), then it will use the node module system to resolve the module references after typescript compilation. This means that it will only respect relative paths in your module and then it will fall back to node_modules to find dependencies.

that is how it is meant to work. the compiler needs the paths to find the declaration of your module. module names are resource identifiers and should be emitted as is and not altered. https://github.com/Microsoft/TypeScript/issues/5039#issuecomment-255870508

You have basically confirmed this for yourself in the emitted output in your question.

like image 101
jmq Avatar answered Sep 22 '22 03:09

jmq