don
don

Reputation: 4532

Using paths in TypeScript in a NodeJS project

I'm trying to use the paths property in tsconfig.json in a NodeJS project.

In tsconfig.json I have something like this:

"baseUrl": ".",
"paths": {
  "@myApp/server/*": [
    "server/src/*"
  ],
  "@myApp/common/*": [
    "common/src/*"
  ]
},

Running tsc outputs all JS files as expected, but they retain the @myApp... imports. As a result, node won't run as it can't resolve all modules having as path @myApp....

I can't find a way to convert the paths I've set in tsconfig.json to a value that can be used by node. I've only found this question on SO, but it's quite outdated and it does not lead to a clean solution.

Do we have a way to transpile TS to JS in a way in which we are able to use paths?

Upvotes: 10

Views: 21573

Answers (4)

FacePalm
FacePalm

Reputation: 11728

If anyone out here is using with nodejs and tsconfig-paths. You can use the following commands to make the absolute paths work:

// With ts-node    
ts-node -r tsconfig-paths/register src/main.js

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

Got this from here: https://github.com/dividab/tsconfig-paths/issues/61

Upvotes: 13

don
don

Reputation: 4532

Until today I was using tspath as suggested in the accepted answer, but I started to get some issues with relative paths having as baseUrl: '../'.

I switched to a webpack based approach, with this webpack.config.ts config:

import { TsConfigPathsPlugin } from 'awesome-typescript-loader';
import * as fs from 'fs-extra';
import { join } from 'path';
import * as webpack from 'webpack';

const packageConfig = fs.readJSONSync('./package.json', { encoding: 'utf-8' });

const externals = {};
for (const packageName in packageConfig.dependencies)
  externals[packageName] = packageName;

const serverConfig: webpack.Configuration = {
  entry: {
    index: './src/index.ts'
  },
  resolve: {
    extensions: ['.ts', '.js'],
    plugins: [
      new TsConfigPathsPlugin({ configFileName: 'tsconfig.json' })
    ]
  },
  target: 'node',
  node: {
    __dirname: false
  },
  externals,
  output: {
    path: join(__dirname, 'dist'),
    filename: '[name].js',
    library: '[name]',
    libraryTarget: 'umd'
  },
  module: {
    rules: [{
      test: /\.ts$/,
      loader: 'awesome-typescript-loader'
    }]
  },
  plugins: [
    new webpack.BannerPlugin(`Copyright © 2018-${new Date().getFullYear()} BOHR. All rights reserved.`)
  ],
  mode: 'production',
  optimization: {
    minimize: false
  }
};

// tslint:disable-next-line:no-default-export
export default [serverConfig];

Note the imports, you will need to add few packages to use this configuration.

Upvotes: 2

don
don

Reputation: 4532

I've found this npm package that converts all absolute paths to relative paths: https://www.npmjs.com/package/tspath.

Running tsc will produce the files with the absolute paths (e.g. @myApp/server/my-library). Then run tspath will convert all paths to the relative path.

Upvotes: 1

Yakov Fain
Yakov Fain

Reputation: 12376

Why won't you just use the path module in the code and resolve the path to rest of the directories relative to the one where you started the server from?

Take a look at the line 6 in this example: https://github.com/Farata/angulartypescript/blob/master/code-samples/Angular6/chapter12/server/rest-server-angular.ts.

The __dirname points at the directory where the server was started from, and public is a subdirectory of this directory. I didn't use the paths option of tsc.

Upvotes: -1

Related Questions