Daniel
Daniel

Reputation: 1611

Typescript non-relative import with node js and ES modules does not work

I am trying to create a simple Typescript script that uses ES modules, execute it with node and have sourcemaps for debugging.

The script executed with node test.ts:

import foo from './foo'

//import bar from './../src/util/bar' //works
//import bar from 'src/util/bar' // does not work. Linter nor tsc show any warning, but when trying to execute, error says bar can't be found
import bar from '@util/bar' // same as above

console.log('test 0')
console.log(foo + bar)

export {}

foo.ts:

export default "foo_module"

bar.ts is very similar.

Here is tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",                       /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
    "module": "ESNext",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    "allowJs": true,                       /* Allow javascript files to be compiled. */
    "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    "sourceMap": true,                     /* Generates corresponding '.map' file. */
    "outDir": "lib",                          /* Redirect output structure to the directory. */
    "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    "baseUrl": ".",                       /* Base directory to resolve non-absolute module names. */
    "paths": {
      "*":[ "./../*" ],
      "@util/*":[ "./../src/util/*" ],
    },                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    "allowSyntheticDefaultImports": true,     /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
    "esModuleInterop": true                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
  },
}

When all imports are relative, everything works fine.

When bar.ts is imported using non-relative import (src/util/bar), tsc and linter do not complain, but when trying to execute it with node the following error appears:

internal/modules/esm/default_resolve.js:100
  let url = moduleWrapResolve(specifier, parentURL);
            ^

Error: Cannot find package '@util/bar' imported from <...omitted>\scripts\lib\scripts\test.js
    at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:100:13)
    at Loader.resolve (internal/modules/esm/loader.js:72:33)
    at Loader.getModuleJob (internal/modules/esm/loader.js:156:40)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:42:40)
    at link (internal/modules/esm/module_job.js:41:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

Minimal example for reproduction is here

Upvotes: 2

Views: 1291

Answers (1)

Mickey Puri
Mickey Puri

Reputation: 889

Looks like Typescript does not support converting paths back to relative. this feels like a Typescript missing feature.

Upvotes: 1

Related Questions