Elisabeth
Elisabeth

Reputation: 21206

What is the task of the 'cliSystemConfigPackages' object in the angular 2 CLI configuration

I am using angular 2 and the CLI.

As there exist no information on https://github.com/angular/angular-cli

about the meaning of the barrels in combination with the angular 2 CLI tool I ask here...

My angular 2 app works ok so far that means I get no errors during runtime. But I fear sooner/later that will change, because I might not use the angular 2 CLI correctly. That means I do not always use the ng generate component my-new-component to create a component. And when I use it I delete the create index.ts for each component, because I think I do not need it.

So I have 3 questions here:

  1. What is a barrel? A file? folder? A batch of components?
  2. What means: the main property with the hardcode 'index' here? cliSystemConfigPackages[barrelName] = { main: 'index' };
  3. When the below configuration is managed by the CLI, what will happen when I do not use the CLI consequently?

That is a part of the system.config.ts

/***********************************************************************************************
     * Everything underneath this line is managed by the CLI.
     **********************************************************************************************/
    const barrels: string[] = [
      // Angular specific barrels.
      '@angular/core',
      '@angular/common',
      '@angular/compiler',
      '@angular/http',
      '@angular/router',
      '@angular/platform-browser',
      '@angular/platform-browser-dynamic',

      // Thirdparty barrels.
      'rxjs',

      // App specific barrels.
      'app',
      'app/shared',
      'app/test/create',
      'app/test/edit',
      'app/administration' 
      /** @cli-barrel */
    ];

    const cliSystemConfigPackages: any = {};
    barrels.forEach((barrelName: string) => {
      cliSystemConfigPackages[barrelName] = { main: 'index' };
    });

Upvotes: 3

Views: 158

Answers (1)

David Lizárraga
David Lizárraga

Reputation: 1192

  1. What is a barrel? A file? folder? A batch of components?

Definition taken from the Angular 2 Style Guide:

"Consider creating a file that imports, aggregates, and re-exports items. We call this technique a barrel."

Imagine you have an empty folder src/app/components and in that folder you run ng generate component MyComponent. This will create a folder with 5 files in it:

|-- my-component
|   |-- my-component.component.css
|   |-- my-component.component.html
|   |-- my-component.component.spec.ts
|   |-- my-component.component.ts
|   |-- index.ts

The index.ts is the barrel and its goal is to re-export the class in my-component.component.ts, so its contents will be:

export * from './my-component.component';

To make the example more clear now we generate a component MyComponent2 which will have its own folder and index.ts again.

Now we make use of these two components in another class by importing them in three different ways:

1.We don't use barrels at all:

import { MyComponent } from './components/my-component/my-component.component';
import { MyComponent2 } from './components/my-component2/my-component2.component';

2.We use barrels but we don't add them in system.config.ts:

import { MyComponent } from './components/my-component/index';
import { MyComponent2 } from './components/my-component2/index';

3.We use barrels and we add them in system.config.ts:

import { MyComponent } from './components/my-component';
import { MyComponent2 } from './components/my-component2';

In this last case we didn't even have to indicate the index file and we just had to write the path to the folder that holds it.

Barrels are basically to have less and shorter import statements. In this case we are just exporting one class per barrel but you can export as many as you wish in one barrel.

On top of that we can re-export barrels. For example we can have an index.ts in the components folder with these two exports in it:

export * from './my-component';
export * from './my-component2';

Now we could import them like so:

import { MyComponent, MyComponent2 } from './components';

or just:

import * from './components';

2.What means: the main property with the hardcoded 'index' here? cliSystemConfigPackages[barrelName] = { main: 'index' };

As you probably guessed already this is is telling that our barrels will be files the name index. So for every folder that we specified in the barrels array there has to be an index.ts file in it (an index.js when compiled).

It may be a little confusing that the array is named barrels but it's actually holding the folders that contain the barrel file, and maybe that's why you were asking in question 1 if a barrel is a file, a folder or a batch of components. In their style guide they define it as a file.

3.When the below configuration is managed by the CLI, what will happen when I do not use the CLI consequently?

This will depend on how we import the files but a common mistake would be if I import MyComponent like this:

import { MyComponent } from './components';

and I have all the barrels in place but I forgot to add app/components/my-component in the barrels array in the SystemJS system-config.ts file (when using ng generate they will be added automatically), the app would compile with no errors but whenever the it needs to load MyComponent it would fail and I'd see this error in the console:

Failed to load resource: the server responded with a status of 404 (Not Found) 
http://localhost:4200/app/components/my-component.js 

That's because in app/components/index.ts I put export * from './my-component' and since SystemJS didn't know this was a barrel and therefore didn't tell the module system that it should search for a file named index.js in a the my-component folder, it just went and tried to fetch a file named my-component.js.

For now I'd just stick with their best practices and have an index.ts file in absolutely every folder and make it export everything in it including other barrels in its subfolders, and add all the paths to folders that hold an index.ts in system-config.ts.

Upvotes: 2

Related Questions