Barrel - Best Way to Import Files in Modern JavaScript Apps
Tags: javascript, web, frontend, tutorial
Published: 2023-08-20 17:11:59

## Introduction
Lets face this, everyone of us must have seen imports like this `import { DataFormatter } from './components/utils/data-formatter/data-formatter';` and most likely did use import in similar style. However, I know for sure it was not intentional and not intended to make peers' life difficult. It was probably because we didn't know about barrel files. In this tutorial, I will talk about barrel files along with [demo](#demo) and how it can simplify our lives as simple as a simple file import. Just practical not theoretical!
Barrel is not just about making file import pretty, but it helps us to keep the code base clean and maintainable.

**Wild wild import**
![wild import](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/khbdjyd4va20hrbxj21b.png)

## Benefits
Using barrel files we can go from import like `import { DataFormatter } from './components/utils/data-formatter/data-formatter';` style, to import like `import { DataFormatter } from './components';`. We’ll be taking small steps and improving as we go through this tutorial.

### Level one export - export just from component module
Exporting only from respective file module
![little very wild import](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d8jowgonmp54dq93tgjl.png)

With exporting from same module, we reduced the lengthy export a bit i.e. from `import { DataFormatter } from './components/utils/data-formatter/data-formatter';` to `import { DataFormatter } from './components/utils/data-formatter';`. Notice last part data-formatter is not needed anymore.

### Level two export - export from parent module
Export from outer module as well

![ok ok import](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8uyuo5m94q4cgt0evctj.png)

Now exporting from parent module, we further reduced the lengthy export a little more i.e. from `import { DataFormatter } from './components/utils/data-formatter';` to `import { DataFormatter } from './components/utils';`. Notice second data-formatter is also not needed anymore.

But no need to stop now. Let’s go further and import file from a module instead of long painful import statement.


### Level three export - combine different exports
Combine multiple exports as single

Well! way to go `import { Accordion, Button, DataAnalytics, DataFormatter } from './components';`, how about this? doesn't it like simple when compared first import style `import { DataFormatter } from './components/utils/data-formatter/data-formatter';`. We travelled a long way just like humans trying to travel across the galaxy.
![way better import](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yhfp3lpzsewrrxig9reo.png)

Auto import suggestion simplified.
![auto import suggestion](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3zrf4uw6qgjjpkbgue80.png)

### Level three export with as keyword
No need to write multiple file name in the import directly use the file in the code.

We can even go one level removing file name from the import `import * as component from './components';`, though in my opinion is a good way to import when to many file imports are need but I guess I'll leave this to developer perspective. 
![best](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3nns1qz7dims122rwjwp.png)

If we import file as something, then this is how can be used.
![import as usage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ojt1caj5c6tqoxwbsnay.png)

## Demo
Alright! showtime, enough of bragging (Time to test the waters). Below is the project structure which I'll be using for this tutorials. `App.tsx` file is under `src` module, `src` module is under project module i.e. `barrel-example`. `third-party` module is parallel to src i.e. directly under root project `barrel-example` directory.

Project Structure:
![proj str](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3vmn2pq7zvip4d16qvuh.png)

If you just want to simplify the import as [level one export](#level-one-export-export-just-from-component-module), just use this.
Create `index.tsx` for typescript project (based upon your project type create `.jsx` or `.js`) for the component under path `./barrel-example/src/components/utils/data-analytics/index.tsx `
![data level](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yv5vn0azjiz6fvykrnmp.png)

If you're little more curious and committed then re-export from its parent directory [Level two export](#level-two-export-export-from-one-level-higher-module).
Again create another `index.tsx` for typescript project (based upon your project type create `.jsx` or `.js`) that will provide level two export `./barrel-example/src/components/utils/index.tsx`
![util level](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6dmvifht09jxrskyh9hw.png)

If you want the best, then obvisouly you won't stop and go for [Level three export](#level-three-export-combine-different-exports).
Create `index.tsx` for typescript project (based upon your project type create `.jsx` or `.js`) that will provide level three export `./barrel-example/src/components/index.tsx`
![comp level](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k6hvaomz44yf8td6qygb.png)

Other way to export in case file are not directly inside the `src` module.
Parallel to src module directly under root directory, as it was done previously create `index.tsx` for typescript project (based upon your project type create `.jsx` or `.js`) that will provide [Level one export](#level-one-export-export-just-from-component-module), `./barrel-example/third-party/agent/index.tsx`, re-export default exported file to name export file. 
>Note - No need to change default to name export in the actual file. Just use `default as Agent` or whatever is the file/component name.

![Agent level](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/69eoi4xqftt3i8te4fok.png)

Kind of both [level two](#level-two-export-export-from-one-level-higher-module) [and three export](#level-three-export-combine-different-exports).
Parallel module, level two/three export create `index.tsx` for typescript project (based upon your project type create `.jsx` or `.js`), `./barrel-example/third-party/index.tsx`

![tp level](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3kt8d2dm4z0b7vki879u.png)

### Caution
Barrel file have known issue when it comes for tree shaking with module bundlers like webpack, rollup etc. Below workaround would work for webpack. In my opinion, applications that are extended as external library may not be good use case for the barrel files, better use case will be single page apps where it'll be easier to eliminate dead code (ultimately making it less rely on tree shaking)

```
rules: [
      // some other rules..
      {
        test: [/src\/components\/index.ts/i],
        sideEffects: false,
      }
    ]
```

And that's it! Here is the link to my [GitHub project](https://github.com/an1meshk/tutorials/tree/main/barrel-example), explore yourself.

> If you have reached here, then I made a satisfactory effort to keep you reading. Please be kind enough to leave any comments or ask for any corrections.

## My Other Blogs:

- [Avoid Spring RestTemplate Default Implementation to Prevent Performance Impact](https://dev.to/akdevcraft/never-use-spring-resttemplate-default-implementation-2ghj)
- [My firsthand experience with web component - learnings and limitations](https://dev.to/akdevcraft/my-firsthand-experience-with-web-component-learnings-and-limitations-4dd8)
- [Streaming logs of all pods at once](https://dev.to/akdevcraft/streaming-logs-from-all-pods-at-once-1kh7)
- [Test SOAP Web Service using Postman Tool](https://dev.to/akdevcraft/test-soap-web-service-using-postman-tool-171k)