william
william

Reputation: 635

How to use TS Path Mapping with Firebase Cloud Functions

How do I use TS Path Mapping with Firebase Cloud Functions? I tried without success:

"baseUrl": ".",
  "paths": {
    "@custom-path/*": ["src/utils/*"],
    "@other-path/*": ["../other/path/*"]
  }

Upvotes: 26

Views: 3694

Answers (5)

Leonardo Barbosa
Leonardo Barbosa

Reputation: 1406

It's 2024 and the neatest way to do this is to use tsc-alias.

On tsconfig.json, add baseUrl and add your paths under compilerOptions. Something like:

{
  "compilerOptions": {
    ...
    "baseUrl": "./src",
    "paths": {
      "@constants/*": ["api/constants/*"],
      "@interfaces/*": ["api/interfaces/*"],
      "@middlewares/*": ["api/middlewares/*"],
      "@modules/*": ["api/modules/*"],
      "@services/*": ["api/services/*"]
    },
    ...
}

Then, change your serve and build scripts, under package.json. Like:

...
  "scripts": {
    "build": "tsc && tsc-alias",
    "build:watch": "concurrently \"tsc -w\" \"tsc-alias -w\"",
    "serve": "concurrently --kill-others \"firebase emulators:start --only functions\" \"npm run build:watch\"",
    ...
  },
...

☝️ here I'm using concurrently, but feel free to use whatever you like.

And that's it. You can now import stuff using your defined paths, like:

import { messages } from '@constants/responses'
import CandidatesService from '@modules/candidates/candidates.service'
import { IModule } from '@interfaces/module.interface'

etc...

Upvotes: 19

Ezzabuzaid
Ezzabuzaid

Reputation: 568

for anyone who still struggles with this issue, but the below code at the top of the entry point file (main.ts). don't forget to adjust the tsconfig.json file path if it is not in the default location

const tsConfig = require('../tsconfig.json');
const tsConfigPaths = require('tsconfig-paths');
tsConfigPaths.register({
    baseUrl: __dirname,
    paths: tsConfig.compilerOptions.paths,
});

Upvotes: 2

banyan
banyan

Reputation: 4192

I was able to do this with @zerollup/ts-transform-paths NPM package.

  1. Install @zerollup/ts-transform-paths as dev dependency: yarn add -D @zerollup/ts-transform-paths
  2. Setup following config of webpack + ts-loader.
const tsTransformPaths = require('@zerollup/ts-transform-paths');

module.exports = {
  ... // other config
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/,
        loader: 'ts-loader',
        options: {
          getCustomTransformers: (program) => {
            const transformer = tsTransformPaths(program);

            return {
              before: [transformer.before], // for updating paths in generated code
              afterDeclarations: [transformer.afterDeclarations] // for updating paths in declaration files
            };
          }
        }
      }
    ]
  }
};

See more in detail: https://github.com/zerkalica/zerollup/tree/5aee60287647350215c81d0b2da5a30717d9dccb/packages/ts-transform-paths

Upvotes: 0

Alexander Baron
Alexander Baron

Reputation: 51

The problem is the rule no-implicit-dependencies: true on the tslint.json. You can pass additional params to whitelist your custom paths:

"no-implicit-dependencies": [true, ["@custom-path", "@other-path"]],

Upvotes: 2

idudinov
idudinov

Reputation: 147

Finally I was able to do this with module-alias NPM package.

  1. Install it as non-dev dependency: yarn add module-alias @types/module-alias
  2. Create a file fixTsPaths.ts or whatever with content like this:
import * as ModuleAlias from 'module-alias';

ModuleAlias.addAliases({
    'common': __dirname + '/../../../common',
});

Here's the trick about the path /../../../common: in my case this folder is outside functions, and Typescript replicates folders structure during the build, so that's could be the reason why https://github.com/dividab/tsconfig-paths was not working out of the box. So in every case one needs to check this path and find appropriate '..' count :)

  1. And finally import this file in your index.ts at the very top:
import './fixTsPaths';

Hope this helps!

Upvotes: 12

Related Questions