添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
import { User } from '../../user/model';
import { Article } from '../../article/model';
import { Cache } from '../../../../cache';
import { MongoDB } from '../../../../mongodb';
    Enter fullscreen mode
    Exit fullscreen mode

Noticed these dots ('../') to access upper modules?

The problem we have here is that the deeper your project tree is the more '../' are required to access modules in higher layers. Actually, this doesn't look very beautiful to be honest. Fortunately we can change that.

The solution: path aliases

In TypeScript you can avoid these "bad" looking imports with the help of path aliases. With path aliases you can declare aliases that map to a certain absolute path in your application.

Here a quick example:

import { User } from '@modules/user/model';
import { Article } from '@modules/article/model';
import { Cache } from '@services/cache';
import { MongoDB } from '@services/mongodb';
    Enter fullscreen mode
    Exit fullscreen mode

Let's get into it and setup some path aliases. Note that I won't explain how to setup a TypeScript project in Node.js. I assume that you did this already.

Imagine we have the following project structure:

folder structure
└───src
   └───rest
   │   │
   │   └───modules
   │   │   │
   │   │   └───article
   │   │   │
   │   │   └───user
   │   │
   │   │   server.ts
   └───services
   │   │    cache.ts
   │   │    mongodb.ts
   │   index.ts
    Enter fullscreen mode
    Exit fullscreen mode

Now, you can use the new path aliases for module imports in your application. There occur any errors in your IDE (in my case VSC) or when you compile the code.

However, we are not done yet. When you try compile the TS code into JS you won't see any errors. But as soon as you run your compiled JS code you will get an error:

For example:

Error: Cannot find module '@modules/user'
    Enter fullscreen mode
    Exit fullscreen mode

Note that 'dist' is the folder where the compiled JS files are located.

Last but not least we have to register the path aliases in our application.
Add the following line at the top of your startup file:

import 'module-alias/register';
    Enter fullscreen mode
    Exit fullscreen mode
          

I've just released a new package Alias HQ, which allows you to reuse your js/tsconfig.json path aliases in Webpack, Jest, Rollup, or any other library.

Just call hq.get('<library name>') in the config file you want to use aliases in, and you're done:

github.com/davestewart/alias-hq

resolve: { extensions: ['.js', '.ts', '.tsx', '.styl'], mainFields: ['module', 'browser', 'main'], alias: Object.keys(tsconfig.compilerOptions.paths).reduce((aliases, aliasName) => { aliases[aliasName] = path.resolve(__dirname, `src/${tsconfig.compilerOptions.paths[aliasName][0]}`) return aliases }, {}) Enter fullscreen mode Exit fullscreen mode

Had an issue with zeit/pkg because the generated files (in the dist folder) still had the @/dir/to/your/file references, which pkg could not handle.

In case you need to change your js files from the @/your-file back into their ../../../your-file form, you can use ef-tspm to bring it back. Note, if you do so, you won't need to deal with the extra steps for the module-alias specified above. Trade-off is you have an additional build step. So first you would tsc to build the typescript code, then ef-tspm to properly remove the module aliases.

I also kept receiving module_not_found while running ts-node.
The way that worked for me (taken from stackoverflow.com/questions/566507...

In tsconfig.json add the following section:

"ts-node": {
      "require": ["tsconfig-paths/register"]
    Enter fullscreen mode
    Exit fullscreen mode
"scripts": {
      "start": "TS_NODE_BASEURL=./dist node -r tsconfig-paths/register dist/index.js"
    Enter fullscreen mode
    Exit fullscreen mode
          

These aliases -- which I've grown used to on the frontend frameworks which use webpack -- are a VERY welcome addition to writing typescript on the backend (or in other library code). My one question comes down to testing. I have a library with hundreds of tests but right now none of them run because I'm using Mocha/Chai with ts-node and I'm not sure but I think that ts-node is not able to use the alias.

The command I use is:

./node_modules/.bin/mocha --no-timeouts --require ts-node/register --exit
    💻  Software Developer: lu-vuong-le.me
👥  Mentor and sharing career experience
📝  Blogger: dev.to/coderarchive
📝  Content Creator: youtube.com/@CoderArchive
      

Built on Forem — the open source software that powers DEV and other inclusive communities.

Made with love and Ruby on Rails. DEV Community © 2016 - 2024.