Joshua
Joshua

Reputation: 6241

How to use Webpack alias with TypeScript Declaration

I am writing a NPM package with TypeScript but I could not find a way to convert Webpack alias in TypeScript Declaration.

webpack.config.js

{
  // ...more Webpack configurations
  resolve: {
  extensions: [".ts", ".js"],
  alias: {
    "@": resolvePath("src")
  }
}

tsconfig.json

{
  "compilerOptions": {
    // More options
    "paths": {
      "@/*": ["src/*"]
    }
  }
}

I am using babel-loader with @babel/preset-typescript but it does not output declaration files.

tsc --emitDeclarationOnly emits declaration files but it does not replace @/ with correct path. Same for ts-loader.

I am able to get it working in Jest with moduleNameMapper. If I can get it working building declaration files, I not longer need to write somethings like ../../../../model.

Most of the answers I found online is about compiling JavaScript files, which I don't have a problem with. Any help will be appreciated.

Upvotes: 7

Views: 3585

Answers (3)

Andrei Kniazev
Andrei Kniazev

Reputation: 309

I have a similar issue and I managed to solve it like this.

Install ts-patch and the "typescript-transform-paths" starts working.

Repo here: https://github.com/worldpwn/tsc-declaration-alias-issue

package.json

{
  "name": "a",
  "version": "0.0.1",
  "main": "dist/index.js",
  "scripts": {
    "prepare": "ts-patch install -s",
    "build": "tsc",
    "build-webpack": "webpack --mode=production"
  },
  "devDependencies": {
    "ts-loader": "^9.2.6",
    "ts-patch": "^2.0.1",
    "tsconfig-paths-webpack-plugin": "^3.5.2",
    "typescript": "^4.5.2",
    "typescript-transform-paths": "^3.3.1",
    "webpack": "^5.64.4",
    "webpack-cli": "^4.9.1"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "src",
    "declaration": true,
    "rootDir": "src",
    "outDir": "dist",
    "paths": {
      "@alias/*": [
        "alias-folder/*"
      ],
    },
    "plugins": [
      {
        "transform": "typescript-transform-paths",
        "afterDeclarations": true
      }
    ]
  },
  "files": [
    "src/index.ts"
  ],
}

webpack.config.js

const path = require('path');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');

module.exports = {
  entry: './src/index.ts',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      }
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
    plugins: [new TsconfigPathsPlugin()]
  },
  plugins: [
  ],
  output: {
    library: {
      name: 'a',
      type: 'umd'
    },
    filename: 'index.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

If you will use typescript compiler to generate declaration with paths/aliases you will get a d.ts file like this:

import { AliasClass } from "@alias";
export declare class A {
    private readonly aliasClass;
    do(): AliasClass;
}

It seems like TypeScript compiler doesn't use this transformation:

"plugins": [
      {
        "transform": "typescript-transform-paths",
        "afterDeclarations": true
      }
    ]

Do apply those transformations you need to install ts-patch and it works!

import { AliasClass } from "./alias-folder/index";
export declare class A {
    private readonly aliasClass;
    do(): AliasClass;
}

Upvotes: 0

WingC.
WingC.

Reputation: 21

Updated answer from 2021

No, we can’t have path alias resolved in declaration files. ttsc used to be an option, but it’s not being maintained for 2 years, and the newest version of ttsc doesn’t look compatible with TypeScript 4 and beyond. See this issue.

Writing the relative path is still the only way to go on TypeScript package developments, as the TypeScript team is still declining to have this supported officially on tsc.

Upvotes: -1

Joshua
Joshua

Reputation: 6241

I finally find a solution. You need ttypescript and typescript-transform-paths. You add the following to compilerOptions in tsconfig.json

"plugins": [
  { "transform": "typescript-transform-paths", "afterDeclarations": true }
]

and run

ttsc --emitDeclarationOnly

I wrote an article on this.

Upvotes: 6

Related Questions