Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoiding relative paths in Angular CLI

I'm using the latest Angular CLI, and I've created a custom components folder which is a collection of all components.

For example, TextInputComponent has a TextInputConfiguration class which is placed inside src/components/configurations.ts, and in src/app/home/addnewuser/add.user.component.ts where I use it there is:

import {TextInputConfiguration} from "../../../components/configurations"; 

This is fine but as my app gets larger and deeper the ../ increases, how do I handle this?

Previously, for SystemJS, I would configure the path through system.config.js as below:

System.config({ ..  map : {'ng_custom_widgets':'components' },  packages : {'ng_custom_widgets':{main:'configurations.ts', defaultExtension: 'ts'}, )}; 

How do I produce the same for webpack using Angular CLI?

like image 722
Pratik Kelwalkar Avatar asked Jan 04 '17 09:01

Pratik Kelwalkar


People also ask

How do you avoid relative paths in typescript?

To fix this, all you need is to set a compilerOptions. baseUrl config in your project's tsconfig. json file. So, if we want to make the src folder (which sits at the root of the project) as the base of every import, we can set it like so.

Why is it better to use relative paths instead of absolute paths?

Relative links show the path to the file or refer to the file itself. A relative URL is useful within a site to transfer a user from point to point within the same domain. Absolute links are good when you want to send the user to a page that is outside of your server.

Should you use relative paths?

Relative paths rely on the current working directory. This is a form of global state, and as such it should be avoided whenever possible. Depending on the structure of your application, the current working directory may not be guaranteed to be constant through all code paths that can reach a certain routine.

How do you convert relative path to absolute path?

The absolutePath function works by beginning at the starting folder and moving up one level for each "../" in the relative path. Then it concatenates the changed starting folder with the relative path to produce the equivalent absolute path.


2 Answers

Per this comment, you can add your application source via paths in tsconfig.json:

{   "compilerOptions": {     ...,       "baseUrl": ".",     "paths": {       ...,       "@app/*": ["app/*"],       "@components/*": ["components/*"]     }   } } 

Then you can import absolutely from app/ or components/ instead of relative to the current file:

import {TextInputConfiguration} from "@components/configurations"; 

Note: baseUrl must be specified if paths is.

See also

  • https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
like image 88
jonrsharpe Avatar answered Sep 20 '22 15:09

jonrsharpe


Thanks to jonrsharpe's answer for pointing me in right direction. Although, after adding the paths, as defined in answer, I was still not able to make it work. For anyone else facing same problem as me in future, here's what I did to fix the issues.

I have a shared module and its services are being used in multiple components, so...

tsconfig.json:

{     "compilerOptions": {         ...         "baseUrl": ".", //had to add this too         "paths": {             "@shared/*": ["src/app/modules/shared/*"]         }     } } 

After this, VS Code was able to resolve the import but I still got following error from webpack while compilation.

Module not found: Error: Can't resolve

To fix this I had to add

  1. baseUrl of tsconfig in webpack's resolve.modules
  2. paths of tsconfig in webpack's resolve.alias

webpack.config.js:

resolve: {   extensions: ['*', '.js', '.ts'],   modules: [     rootDir,     path.join(rootDir, 'node_modules')   ],   alias: {     '@shared': 'src/app/modules/shared'   } }, 

component.ts:

import { FooService } from '@shared/services/foo.service' import { BarService } from '@shared/services/bar.service' import { BazService } from '@shared/services/baz.service' 

To make it even more cleaner, I added an index.d.ts inside services folder and exported all my services from there, like this:

index.d.ts:

export * from './foo.service'; export * from './bar.service'; export * from './baz.service'; 

and now inside any component:

import { FooService, BarService, BazService } from '@shared/services'; 
like image 39
Syed Ali Taqi Avatar answered Sep 19 '22 15:09

Syed Ali Taqi