0

I'm creating a command-line script, using classes from the main express app.

Script resides in the folder:

bin/utils/
├── sync-buyers.ts
└── tsconfig.json

The main express app is in /app use uses import '@/foo/bar/thing.

This is set up in the tsconfig.json of the main app, as follows:

"paths": {
        "@/*": ["*"],
        "*": [
            "node_modules/*",
            "app/typings/*"
        ]
    }
},
"include": ["app/**/*", "test/**/*"],
"exclude": ["app/**/*.test.ts", "/__tests__/", "/__mocks__/", "/__snapshots__/", "app/**/__mocks__/"],
"files": ["typings/global.d.ts"]

Script Execution

I'm testing to see if I can import from the main app, so I created a sayHello() function.

#!/usr/bin/env ts-node
/* tslint:disable */

import { sayHello } from '../../app/services/v2/oapp';
sayHello();

When I run it:

TSError: ⨯ Unable to compile TypeScript:
../../app/services/v2/oapp.ts(9,19): error TS2307: Cannot find module 
'@/helpers/fetch'.
../../app/services/v2/oapp.ts(10,31): error TS2307: Cannot find module 
'@/services/v2/buyer'.
../../app/services/v2/oapp.ts(11,51): error TS2307: Cannot find module 
'@/http/HttpHeader'.

Summary:

Does ts-node support '@' style of import? If so, how do I set it up?

Jasper Blues
  • 28,258
  • 22
  • 102
  • 185

1 Answers1

1

So the TypeScript paths configuration only applies to TypeScript's type resolution and checking, meaning that it will allow TypeScript to understand those imports for the purposes of type-checking only, but the code it generates won't automatically rewrite those imports to the correct locations.

There's two common approaches for solving this:

  1. Update the Node resolver to understand the TypeScript paths config. The generated files will still refer to those paths by their @-name.

    Most commonly, the tsconfig-paths module is used for this. You can require that module from the node command directly:

    node -r tsconfig-paths/register main.js
    
  2. Rewrite the generated files so that the @-names get replaced with the "real" local relative path locations.

    There's a standalone module for this, tspath - you simply run tspath after compiling your TypeScript, and it updates the generated files with the correct paths.

    If you're using Webpack, you can also use tsconfig-paths-webpack-plugin, which will take care of configuring Webpack's resolver to correctly locate those @-name paths.

    And finally if you're using Babel, you might be interested in babel-plugin-module-resolver which does a similar thing for the Babel toolchain, however the downside here is it doesn't read the paths config from tsconfig.json, so you essentially have to duplicate your paths config in the alias config of this plugin.

Personally I'd recommend tsconfig-paths if this is a Node script or server that's compiled with tsc directly and tsconfig-paths-webpack-plugin if this is a frontend Webpack build.

Jacob Gillespie
  • 3,981
  • 3
  • 23
  • 33