In TypeScript, what is the proper config to make module alias work when building the dist folder?
Asked Answered
K

1

9

I was experimenting on module alias for typescript and it works during dev, but when I try to build it I always get cannot find module because it is pointing to src file even on build.

I tried replacing dist to moduleAliases in package.json. It compiled, however, when I run yarn run dev, it is using the dist folder source code instead of my src. I also tried introducing tsconfig-paths to my dev e.g "dev": "NODE_ENV=development ts-node -r tsconfig-paths/register ./src/index.ts", but the system is still reading the moduleAliases. Maybe someone here have encountered similar issue while doing module paths.

Here is my project structure:

|-project
|---src
|-------index.ts  // (where I put require('module-alias/register');)
|-------app (business logic) // where I start using modules e.g import config from '@config/index.config';
|-----------index.ts
|-----------routes
|-------config
|---dist
|---node_modules
|---.env
|---.eslintrc
|---package.json
|---tsconfig.json
|---yarn.lock

Snippet of my package.json

"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
  "dev": "NODE_ENV=development ts-node-dev --respawn --transpileOnly ./src/index.ts",
  "prod": "yarn run build && node -r ./dist/index.js",
  "build": "NODE_ENV=production yarn run build-ts",
  "build-ts": "tsc -p .",
},  
"_moduleAliases": {
  "@config": "./src/config",
  "@routes": "./src/app/routes",
},

My tsconfig.json

{
  "compilerOptions": {
    "incremental": true,
    "target": "es6",
    "module": "commonjs",
    "declaration": true,
    "sourceMap": true,
    "outDir": "./dist",
    "removeComments": true,
    "strict": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "noUnusedLocals": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "suppressImplicitAnyIndexErrors": true,
    "moduleResolution": "node",
    "baseUrl": "./src",
    "paths": {
      "@config/*": ["config/*"],
      "@routes/*": ["app/routes/*"],
    },
    "allowSyntheticDefaultImports": true, 
    "esModuleInterop": true 
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

My .eslintrc (not sure if it matters or relevant to this problem)

{
  "extends": ["airbnb-typescript/base"],
  "rules": {
    "import/prefer-default-export": 0
  },
  "settings": {
    "import/resolver": {
      "babel-module": {}
    }
  }
}

How I use it

import config from '@config/index.config';
Knossos answered 25/9, 2019 at 12:49 Comment(1)
This question has already been resolved in an issue I opened at github github.com/ilearnio/module-alias/issues/… :)Knossos
A
0

At the moment there's no need for any packages to use aliases in typescript when build to a dist or another folder.

In tsconfig.json you need to set a baseUrl, paths and outDir and some other settings.

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "baseUrl": "./src",
    "paths": {
      "#config/*": ["./config/*"],
      "#routes/*": ["./routes/*"]
    },
    "outDir": "./dist",
    "isolatedModules": true,    
    "esModuleInterop": true    
  },
  "include": ["src/**/*"],
  "exclude": [
    "node_modules"
  ],
  "ts-node": {
    // Tell ts-node CLI to install the --loader automatically
    "esm": true
  }
}

Then in package.json you need to set the imports directive

  "main": "dist/index.js",
  "imports": {
    "#config/*": "./dist/config/*",
    "#routes/*": "./dist/routes/*"
  },

And then you can use imports with the aliases symbol (#). Make sure to use .js extension in your ts file import, that's needed for build to run successfully.

-src/config/config.ts
-src/routes/index.ts

// use imports everywhere in your project
import { some_option } from '#config/config.js';
import routes from '#routes/index.js';
Afroasiatic answered 22/9 at 9:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.