Absolute Paths in NestJS

In order to import application components via a relative path in a nodeJS application, it might be better to use absolute paths. With absolute paths, you can move your components wherever you want, and you can see exactly on the import path what an import is all about.

To activate this in a TypeScript project, like all NestJS-Application, you need to add a “path” configuration to the tsconfig.json like this:

"paths": {
"@app/*": ["./src/*"]
}

Now all files under src can be referred to with “@app/…”. But this does only work for typescript. When typescript is compiled to JavaScript for production, this definition is not valid anymore. For the JavaScript part, there is a package “module-alias” to reference packages via an alias as “@app”. The package must be installed with the package manager in use. With npm: npm install module-alias. Or with yarn: yarn add module-alias. Documentation to “module-alias” can be found here. For the module configuration, there should be an entry “_moduleAliases” inside the package.json of the project. In this configuration, the alias ‘@app’ is mapped to the ‘./dist’ directory. Thus because in production, the JavaScript-Sources are stored in the ./dist directory.

That’s nearly all. One little thing is left. As mentioned in the documentation, the module should only be activated in JavaScript with the following line:

require('module-alias/register')

But only if the program is running in production. So in the main.ts add at the very top this code:

if( process.env.IS_PROUCTION) {
  require('module-alias/register')
}

In development define an Environment-Variable “IS_PROUCTION” that would prevent the require-statement from being executed.

The minimal react application (with TypeScript)

To create a new React application, enter the following command:

npx create-react-app react-app --template typescript

A minimal react application contains an index.html page with an element marked with id=”root” and an index.tsx (TypeScript with jsx included) with the following content:

// Importing ReactDOM. Needed to render the page.
import ReactDOM from "react-dom";

// Build a minimal React-Function Component as a Function
// that returns some Content
const App = () => {
return <div>
<h1>Hello React</h1>
</div>
}

// Use imported ReactDOM to render a Component at the
// Element marked wiht id="root"
// The Component to render is referred to via it's name
// as <App />
ReactDOM.render(
<App />
, document.querySelector("#root")
);

This Application does not use any TypeScript at all. To add a little TypeScript support, it is possible to make the App-FunctionComponent of type React.FC (shortcut for React.FunctionComponent).

...
// Import React from "react"
import React from "react";

/**
 * Make the App of type React.FC. This will give your IDE the
 * access to auto completion functionality.
 * @constructor
 */
const App:React.FC<any> = () => {
...

With this little add-on, your IDE can now give you correct auto-completion. For example, WebStorm can now present the “display-name” property when typing “App.” and pressing control-space.