Modules & Modules & Modules, Oh My!
Tags: angular, javascript, typescript, esm
Published: 2023-06-03 14:05:14

---
title: Modules & Modules & Modules, Oh My!
published: true
date: 2023-05-25 19:46:31 UTC
tags: angular,javascript,typescript,esm
canonical_url: https://medium.com/@seanhaddock_60973/modules-modules-modules-oh-my-c170efde7292
---

![](https://cdn-images-1.medium.com/max/1024/0*tivEF6cOcZobm4O0)
_Photo by La-Rel Easter on Unsplash_

When I was first transitioning from C#/ASP.NET web development to modern frontend JavaScript development in Angular circa 2014, one of the things that kept tripping me up was  **modules**.

It wasn’t the _concept_ of modules that was confusing but rather the conflation of JavaScript, TypeScript and Angular modules. More than that, I think, it was the conflation of JavaScript, TypeScript and Angular in _general_.

Anxious to jump in and actually create something, I tended to gloss over these distinctions, and you can actually get pretty far without really understanding all of the differences. But I think starting with a solid understanding of these concepts would have helped me in my development journey.

In this post, I want to touch on the difference between JavaScript, TypeScript and Angular and then explain how **modules** differ between them.

### JavaScript => TypeScript => Angular

![](https://cdn-images-1.medium.com/max/1024/1*0RASABVnBRxX2mdiA9_jRg.png)

#### JavaScript

JavaScript, of course, is the language of browsers. The final state of an Angular application — what gets shipped to the browser — is JavaScript.

#### TypeScript

TypeScript describes itself as “JavaScript with syntax for types”. TypeScript is a superset of JavaScript and as such, you _could_ just write plain JavaScript in your .ts files. But of course, the point of using TypeScript is that you can do things in TypeScript that you cannot do (or do as easily) in JavaScript — typing your code being first among them.

It’s important to realize, however, that all TypeScript gets transpiled to plain old JavaScript before being run in a browser (or anywhere else). A great way to see this in action is to visit the [TypeScript Playground](https://www.typescriptlang.org/play).

#### Angular

Since I learned Angular and TypeScript _at the same time_, there were many things that I thought were part of Angular that I later realized were just part of TypeScript. This would sometimes cause confusion — for example, when I needed to add a non-Angular dependency to my application.

Although TypeScript is the recommended language for developing Angular applications now (and you’d be hard-pressed to find one that isn’t), when **AngularJS** first came out, you had to make a decision whether you wanted to write your application in TypeScript, JavaScript or DART! Angular is ultimately just JavaScript code that provides a framework for creating applications.

> The Angular framework itself is loaded as a set of JavaScript modules — [angular.io](https://angular.io/guide/ngmodule-vs-jsmodule)

### Modules

![](https://cdn-images-1.medium.com/max/1024/0*CqncSgfm4cte3nRP)
_Photo by Volodymyr Hryshchenko on Unsplash_

#### JavaScript Modules

JavaScript modules are really simple. A module is just code in one file that can be shared with code in other files. You _export_ code (variables, constants, functions, classes) from one file and _import_ it into another — that’s it.

What isn’t simple, are the various module _types _— ESM, CommonJS, AMD, UMD, etc. The good news is that ESM (ECMAScript Modules) are the most popular type for Angular development and are the only type natively supported by modern browsers. ESM is easy to recognize by the use of **import** and **export** statements:

```
//in dog.js file
export class Dog {
  bark() {
    console.log('woof');
  }
}

// exporting outside of Dog class just for illustration
export const dogTeethCount = 42;

//in script.js file
import { Dog, dogTeethCount } from './dog.js'

const d = new Dog();
d.bark();

console.log(dogTeethCount);
```

#### TypeScript Modules

TypeScript modules are more or less the same as JavaScript modules. However, in TypeScript you always use the ESM (import/export) syntax (again good news), but you can configure TypeScript to deliver the final JavaScript module in a _different_ type, such as CommonJS. Again, the ESM module type is becoming the de facto standard for web.

You specify the module type in tsconfig.json with the **module ** setting:

```
{
  "compilerOptions": {
    ...
    "module": "ES2022"
```

> In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module — [typescriptlang.org](https://www.typescriptlang.org/docs/handbook/modules.html).

#### Module Resolution in TypeScript

Another thing that initially confused me about modules was how TypeScript knew where to find the module referenced by the **import** statement. This is called _module resolution_. There is a tsconfig setting for that too:

```
{
  "compilerOptions": {
    ...
    "moduleResolution": "node"
```

Options are **classic** and **node** , but node is recommended.

There are two types of module imports —  **relative** and **non-relative**. Relative imports are pretty straightforward (aside from the fact that TypeScript hides the extension by default):

```
import { Dog } from './animal/animal';
```

Starting at the directory where this file resides, you can find the **animal** module code in animal/ **animal.ts** (there is one other possibility with **node** module resolution but I don’t want to complicate things here).

Non-relative imports are a little more mysterious:

```
import { Component } from '@angular/core';
```

In this case, TypeScript will walk the directory tree looking in all **node\_modules** directories for one of the following:

- **@angular/core.ts|tsx|d.ts** file
- @ **angular/core/index.ts|tsx|d.ts** file
- **@angular/core/package.json** file

So again, TypeScript is attempting to match the module **name** to a file or directory name.

#### Angular Modules

The _code_ that creates an Angular module (NgModule) is itself a TypeScript (and later JavaScript) module and also uses other TypeScript/JavaScript modules:

```
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

@NgModule({
  declarations: [],
  imports: [
    CommonModule
  ]
})
export class AnimalModule { }
```

But the NgModule’s role in Angular development, though conceptually similar to JavaScript modules, _is completely different_ and specific to Angular. With the associated metadata object, NgModules dictate how the application compiles and how various pieces fit together, as well as providing a way to organize your code.

Much more could be said about Angular modules of course, but the point to get across here is that they should not be confused with JavaScript modules. Angular modules are a way of instructing and structuring _Angular_ code, whereas JavaScript modules are a generic way to promote code re-use and organization in any JavaScript application.

Ok, thanks for reading, and hopefully you have a better understanding of how the three main pieces of an Angular application — (JavaScript, TypeScript and the Angular framework) interact and are distinct, if you didn’t already.

### Bibliography

- [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)
- [https://www.typescriptlang.org/tsconfig](https://www.typescriptlang.org/tsconfig)
- [https://www.typescriptlang.org/docs/handbook/modules.html](https://www.typescriptlang.org/docs/handbook/modules.html)
- [https://www.typescriptlang.org/docs/handbook/module-resolution.html](https://www.typescriptlang.org/docs/handbook/module-resolution.html)
- [https://angular.io/guide/ngmodule-vs-jsmodule](https://angular.io/guide/ngmodule-vs-jsmodule)