19

Let's suppose I've a project, and its main source directory is:

C:\product\src

Based on this directory, every import path would be relative to it. I.e., suppose:

// Current script: C:\product\src\com\name\product\blah.ts

import { thing } from '/com/name/product/thing';

same as:

// Current script: C:\product\src\com\name\product\blah.ts

import { thing } from '../../../com/name/product/thing';

My entry compilation file would be at:

C:\product\src

for instance. So, is there a way to specify this such entry path (C:\product\src, for example) at the compiler options? I need to specify this in the tsconfig.json file, because I'll use webpack.

I've tried my above example, but TypeScript says the requested module cannot be found:

// Current script: A.ts

import { B } from '/com/B';


// Current script: B.ts

export const B = 0;

My tsconfig.json file (inside another project, but both similiar):

{
    "compilerOptions": {
        "module": "commonjs",
        "noImplicitReturns": true,
        "noImplicitThis": true,
        "noUnusedLocals": true,
        "preserveConstEnums": true,
        "removeComments": true,
        "sourceMap": true,
        "strictNullChecks": true,
        "target": "ES6"
    },

    "include": [
        "./src/**/*.ts",
        "./src/**/*.d.ts"
    ]
}
Klaider
  • 3,140
  • 3
  • 20
  • 49
  • `C:\product\src` + `../../../com/name/product/thing` is not `C:\product\src\com\name\product\blah.ts`. Am I missing something? You want disallow `..`ing up a certain root directory? – Tomáš Hübelbauer Feb 08 '17 at 21:42
  • @TomášHübelbauer The `// C:\product\src\com\name\product\blah.ts` comment means that the following script with import declaration is the blah.ts file, it's not related to the import path. Sry! Not sure what you meant by `..`, I'm not very good at English :/. –  Feb 08 '17 at 22:43
  • 1
    Please post your tsconfig.json – Teddy Sterne Feb 12 '17 at 22:00
  • @TeddySterne Added. – Klaider Feb 12 '17 at 22:16

5 Answers5

16

(Re-posting my answer to avoid puppy-socket.)

Using the compilerOptions.baseUrl property I was able to do the below import. This allowed me to have a complete root-to-expected-path, which helps my code maintainance, and works in any file, independently of the current folder. The below examples will have the src folder of my project as the modules root.

Important advice: this baseUrl property doesn't affect the entry webpack file (at least for me?), so separate a main file inside the src folder with this example, and run it from the entry (i.e., import { Main } from './src/Main'; new Main;), only once.

// browser: directory inside src;
//   * net: A TS file.
import { URLRequest } from 'browser/net';

tsconfig.json example:

{
    "compilerOptions": {
        "baseUrl": "./src",
        "module": "commonjs",
        "noImplicitReturns": true,
        "noImplicitThis": true,
        "noUnusedLocals": true,
        "preserveConstEnums": true,
        "removeComments": true,
        "sourceMap": true,
        "strictNullChecks": true,
        "target": "ES6"
    },

    "include": [
        "./src/**/*.ts",
        "./src/**/*.d.ts"
    ]
}

However, it won't directly work with webpack. The same thing must be done at the webpack options. This is how it worked in webpack 2:

module.exports = {
  ...
  , resolve: {
      ...
      , modules: [ path.join(__dirname, './src') ]
    }
}
Klaider
  • 3,140
  • 3
  • 20
  • 49
  • 6
    Awesome, answer but don't forget to also put node_modules in there. – Eyal Perry Jun 07 '17 at 12:12
  • 1
    I found the includes section unnecessary and will even attempt to compile what's in node_modules. I set baseUrl, rootDir, ouputDir in tsconfig. In webpack I added node_modules as @EyalPerry pointed out. Seems to be working great. – Greg Sep 11 '17 at 05:00
  • I'm using `create-react-app` and setting only `baseUrl` was sufficient. Thanks! – porges Aug 16 '19 at 21:25
11

I needed to set both baseUrl and rootDir to point to my src folder in tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "./src",
    "rootDir": "./src",
  ...
}

I could then import .tsx files without needing a prefixed '/' or a relative path.

e.g. import BreadCrumb from 'components/BreadCrumb'

janniks
  • 2,300
  • 3
  • 16
  • 29
Damian Green
  • 4,887
  • 1
  • 25
  • 32
6

TypeScript imports use / at the start of a path to denote the root directory. To import a file relative to your current file either leave off the initial slash or use ./.

// Current script: C:\product\src\com\name\product\blah.ts
import { thing } from './com/name/product/thing';

By default the TypeScript compiler assumes the root of the project is the same as the location of your tsconfig.json.

You can specify a new root by specifying the rootDir property of the compilerOptions property in the tsconfig.

For a list of all available property settings consult the tsconfig definition found here.

Teddy Sterne
  • 11,834
  • 1
  • 37
  • 46
  • 1
    Thanks for the assumption of the root directory, however I can't still import a file relative to its root, as TypeScript continues saying that the import module doesn't exist/can't be found. I've tried with and without slash, but nothing, same with `./`. – Klaider Feb 12 '17 at 21:34
  • Try switching `module` to `node` – Teddy Sterne Feb 12 '17 at 22:27
  • 1
    No success so far :/ ! – Klaider Feb 12 '17 at 22:49
  • 8
    **`/` always refers to the file system root.** [More details](https://stackoverflow.com/a/46229294/380229) – raphinesse Sep 14 '17 at 22:56
1

Just for record

If you want use absolute import from your project, Do not use / as prefix, such as /src/config/cfg, just use as src/config/cfg

As https://stackoverflow.com/a/46229294/7529562 pointed, / stand for System root,

tsc will complain cannot find module

nuclear
  • 2,284
  • 2
  • 12
  • 25
0

Solution for your import statement in thing.ts will be

import {} './product/blah'

and your project structure might be as

enter image description here

Other Possible options with explanation


I have the following application structure and I place it in

C:\\Users\\(username)\\Documents\firstAngular2App

as in the screenshot.

enter image description here

I am importing components to the app.module.ts as

  1. ./ will show the current folder (app)

    import { } from './'; 
    

enter image description here

  1. ../ will refer to the root folder (firstAngular2App-master)

    import { } from '../'; 
    

enter image description here

  1. ../../ will refer to the root folder (Documents folder)

    import { } from '../../'; 
    

enter image description here

  1. ../app/ refers to the app folder but it is referred from the root(firstAngular2App)

    import {} from '../app/';
    

enter image description here

Aravind
  • 36,165
  • 14
  • 84
  • 102
  • Thanks for the elaboration, however that's not broadly exactly what I was looking for. I know I can use the `..` and `./` tokens for relative-importing, there's yet an example in my question. – Klaider Feb 13 '17 at 01:11
  • what is that you were looking for – Aravind Feb 13 '17 at 01:19
  • 1
    I'm trying to avoid deep-relative paths, I want to specify a relative path from the project root, not by the current file root. For example, my root would now be the src folder. Suppose I've a file `src/blah/Class.ts`, in which `import { Export } from 'export'` would refer to `src/Export.ts`. I don't want to depend on `..` or `./` tokens, unfortunately they made me almost create a new programming language to replace TypeScript, they made my code maintainance ugly. – Klaider Feb 13 '17 at 01:27
  • I've got a solution, but anyways thanks for your help and collaboration! – Klaider Feb 13 '17 at 01:30
  • is there anything else you want me to help? – Aravind Feb 13 '17 at 01:30
  • I'm satisfied, don't worry... and I'm still gonna award a bounty occasionaly – Klaider Feb 13 '17 at 01:31
  • 1
    If so reach me out in fb @aravind2109 – Aravind Feb 13 '17 at 01:33
  • You can update the answer freely, I can still award . – Klaider Feb 13 '17 at 01:36
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/135538/discussion-between-aravind-and-handoncloud). – Aravind Feb 13 '17 at 01:37