What are all the index.ts used for?
Asked Answered
P

4

193

I've been looking at a few seed projects and all the components seem to have a index.ts that exports * from that component. I can't find anywhere what it's actually used for?

E.g https://github.com/mgechev/angular2-seed/tree/master/src/client/app/%2Bhome

Thanks

Paquito answered 1/6, 2016 at 9:38 Comment(1)
Relevant to this discussion is this issue on github. You may want to read through it before using barrel files with your Angular projectOrelia
B
293

From the Angular.io v2's archived glossary entry for Barrel*:

A barrel is a way to rollup exports from several modules into a single convenience module. The barrel itself is a module file that re-exports selected exports of other modules.

Imagine three modules in a heroes folder:

// heroes/hero.component.ts
export class HeroComponent {}

// heroes/hero.model.ts
export class Hero {}

// heroes/hero.service.ts
export class HeroService {}

Without a barrel, a consumer would need three import statements:

import { HeroComponent } from '../heroes/hero.component.ts';
import { Hero }          from '../heroes/hero.model.ts';
import { HeroService }   from '../heroes/hero.service.ts';

We can add a barrel to the heroes folder (called index by convention) that exports all of these items:

export * from './hero.model.ts';   // re-export all of its exports
export * from './hero.service.ts'; // re-export all of its exports
export { HeroComponent } from './hero.component.ts'; // re-export the named thing

Now a consumer can import what it needs from the barrel.

import { Hero, HeroService } from '../heroes'; // index is implied

The Angular scoped packages each have a barrel named index.

See also EXCEPTION: Can't resolve all parameters


* NOTE: Barrel has been removed from more recent versions of the Angular glossary.

UPDATE With latest versions of Angular, barrel file should be edited as below,

export { HeroModel } from './hero.model';  
export { HeroService } from './hero.service'; 
export { HeroComponent } from './hero.component';
Bonsai answered 1/6, 2016 at 9:41 Comment(14)
When I do equivalent of export * from './hero.model.ts', I get a message like "'an import path cannot end with a '.ts''" So I just change to export * from './hero.model'. Also worth repeating your comment about Angular not recommending barrels anymoreDiscophile
@TheRedPea thanks for the hint. I don't want to change it because it's a quote from (an earlier version of the) linked pageSelfrestraint
Do you know is there any helper library or command to generate index.js automatically?Newton
@aokaddaoc I don't know, but I'm not using TS (only Dart)Selfrestraint
The section of the guide you mentioned also contains a note at the very end: You can often achieve the same result using NgModules instead. Could you explain what they mean here, probably, with some example?Housebreak
@AlexanderAbakumov actually, no idea. Sounds a bit far-feched to me.Selfrestraint
Ok, thank you anyway! Just wondering if there is a better alternative to the barrels (an extra source file in every module to manage).Housebreak
I guess the alternative is to just import what you need directly. Perhaps the comment about NgModule was about creating modules for "small5 parts of your application and direct imports within a module and then only import modules into each other. This should reduce the need for TS imports a lot if you split the app into modules wisely.Selfrestraint
@AlexanderAbakumov Since a component, directive or pipe must belong to one and only one module, then by having declared any of the above in a module, when you import that module you essentially achieve the same thing... assuming you also exported them from the module.Salian
Doesn't this, however, impose a performance drop, due to referencing modules that one doesn't necessarily need? Will this properly tree-shake?Makalu
@Makalu I'm quite sure this works with tree-shaking, but using barrels was removed from suggested practices a long time ago, I think when modules where introduced just before 1.0.Selfrestraint
I am not even coming from the Angular context so it was the first time to see this term, but I did have seen this practice in current javascript, so I was wondering if there are any drawbacks.Makalu
@GünterZöchbauer Your latest comment mentions barrels have fallen out of style, and barrels are no longer in the the current versions of the Angular glossary. Can I talk you into updating this answer with the current state of style & barrels, including links to discussion about barrel use (example)? It looks like we're now meant to use "real" NgModules to get what barrels used to buy us, but also that barrels are still [largely?] supported, even if no longer encouraged. Is that accurate? etc etc.Substituent
Barrels are a TypeScript thing and not specific to Angular and they often caused hard to locate errors about circular dependencies. I don't know if this is the only reason the Angular team stopped promoting them. NgModule is an entirely different beast.Selfrestraint
E
53

index.ts is similar index.js in nodejs or index.html is web site hosting.

So when you say import {} from 'directory_name' it will look for index.ts inside the specified directory and import whatever is exported there.

For example if you have calculator/index.ts as

export function add() {...}
export function multiply() {...}

You can do

import { add, multiply } from './calculator';
Earl answered 1/6, 2016 at 9:46 Comment(2)
@FlowerScape Exporting via the index is particularly useful when creating libraries or module-level code, so that end users have less verbose imports. It also hides any unnecessary/confusing implementation details of the imported code.Graceless
Refactoring. You can change code, ex. rename files, as long as you keep the exports in index.ts the same.Motile
M
9

index.ts help us to keep all related thing together and we don't need to worry about the source file name.

We can import all thing by using source folder name.

import { getName, getAnyThing } from './util';

Here util is folder name not file name which has index.ts which re-export all four files.

export * from './util1';
export * from './util2';
export * from './util3';
export * from './util4';
Megasporophyll answered 7/8, 2019 at 4:27 Comment(0)
S
3

index.ts is usually located outside the internal folder. E.g.:

my-app/
├─ src/
│  ├─ internal/
│  │  ├─ app.ts
│  ├─ index.ts

Assume that in /src/internal/app.ts, we want to import any function, e.g function A.

If we don't have the index.ts where we put export * from ./internal/app.ts, when importing function A from external, our path will go straight inside the internal folder

import {A} from ./src/internal/app

This should be avoided as much as possible.

If we use index.ts, our path is just simple

import {A} from ./src

Shivery answered 29/11, 2022 at 15:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.