jonkwheeler / tsconfig-replace-paths

Replace absolute paths to relative paths for package compilation
MIT License
72 stars 11 forks source link

ESM | typescript | node | support for imports having extensions #23

Open kareem-abdul opened 2 years ago

kareem-abdul commented 2 years ago

Hi, in a node typescript ESM project, the modules are imported with extensions, ie,

import { a } from '../../service/index.service.js'

so for such a case, we could provide a path in tsconfig as bellow

{
   ...
   "baseUrl": "./src",
   "paths": [
     "@services": [ "app/service/index.service.js"]
   ]
   ...
}

But providing such a path in ts-config would break the current setup as there are no js files on the source directory during compilation. Most probably the base-url would be pointing to the ./src folder and there would be no way to point it to the dist folder as doing so would cause eslint or tsc to fail. So is it possible to add support for extensions? or did I miss something?

Attaching my tsconfig.json, package.json, and a verbose output of tsconfig-replace-paths bellow

tsconfig

{
  "compilerOptions": {
    "target": "es2016",
    "module": "ESNext",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "rootDir": "./src",
    "outDir": "./dist",
    "baseUrl": "./src",
    "paths": {
      "@service": [
        "service/index.service.js"
      ]
    }
  }
}

package.json

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "start": "node ./dist/index.js",
    "build": "tsc -p tsconfig.json && tsconfig-replace-paths -v -p tsconfig.json"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "tsconfig-paths": "^3.12.0",
    "tsconfig-replace-paths": "^0.0.11",
    "typescript": "^4.5.2"
  }
}

build output

> test@1.0.0 build
> tsc -p tsconfig.json && tsconfig-replace-paths -v -p tsconfig.json

Using tsconfig: /home/abc/workspace/node/test/tsconfig.json
Using compilerOptions.rootDir from your tsconfig
Using src: /home/abc/workspace/node/test/src
Using compilerOptions.outDir from your tsconfig
Using out: /home/abc/workspace/node/test/dist
baseUrl: ./src
rootDir: /home/abc/workspace/node/test/src
outDir: /home/abc/workspace/node/test/dist
paths: {
  "@service": [
    "service/index.service.js"
  ]
}
basePath: /home/abc/workspace/node/test/src
outPath: /home/abc/workspace/node/test/dist
aliases: [
  {
    "prefix": "@service",
    "aliasPaths": [
      "/home/abc/workspace/node/test/src/service/index.service.js"
    ]
  }
]
../dist/index.js (source: index.js):
        import '@service'
        could not replace @service
Replaced 0 paths in 0 files
jonkwheeler commented 2 years ago

I can take a look at this soon. Thanks for your patience.

kareem-abdul commented 2 years ago

any updates on this @jonkwheeler

sourcecodes2 commented 2 years ago

We have recently begun migrating our projects over to ESM modules and ran into this issue.

Does https://github.com/jonkwheeler/tsconfig-replace-paths/pull/28 fix this issue?

jonkwheeler commented 2 years ago

@sourcecodes2 I'll have to take a peek. Sorry for the delay all. I had a kid born recently and life has gotten a bit chaotic.

There's an easy fix to this though.

"@services": [ "app/service/index.service.js"]

This could easily be @service/index or @service and then app/service/index.js export default index.service.js. Am I missing something?

jonkwheeler commented 2 years ago

Alright, I just did this in one of my repo's and had no issue at all.

The original file has this import

import { typeSystem } from '@typeSystem'

My tsconfig has this

"paths": {
  "@typeSystem": ["./src/variables/typeVars/typeSystem.js"]
},

And the CommonJS output was this

var _typeSystem = require("../../variables/typeVars/typeSystem.js");

Everything worked perfectly. Am I missing something? Is there a repo I can have to replicate this?

sourcecodes2 commented 2 years ago

Alright, I just did this in one of my repo's and had no issue at all.

The original file has this import

import { typeSystem } from '@typeSystem'

My tsconfig has this

"paths": {
  "@typeSystem": ["./src/variables/typeVars/typeSystem.js"]
},

And the CommonJS output was this

var _typeSystem = require("../../variables/typeVars/typeSystem.js");

Everything worked perfectly. Am I missing something? Is there a repo I can have to replicate this?

My mistake, having re-read the original issue @kareem-abdul submitted, it is a slightly different issue to the one I have experienced.

I need to specify the ".js" extension within the imports (import { a } from '@services/foo/bar.service.js'). I am simply using the tsconfig paths array to alias the directory, as normal ("@services/*": "services/*").

The issue I'm specifically experiencing is the ".js" file extension suffix in the import path, which appears to be required when using ES modules. Beforehand with commonjs modules I was omitting the .js extension (import { a } from '@services/foo/bar.service) but this appears to be no longer possible with the latest version of Typescript and ES modules.