An open API service indexing awesome lists of open source software.

https://github.com/Mimetis/ESM

Boilerplate to show how ESM are working today, both on browsers or from NodeJS. Use Rollup to bundle the modules in a compatible bundle for non ESM browser.
https://github.com/Mimetis/ESM

Last synced: 4 months ago
JSON representation

Boilerplate to show how ESM are working today, both on browsers or from NodeJS. Use Rollup to bundle the modules in a compatible bundle for non ESM browser.

Awesome Lists containing this project

README

          

# EcmaScript Modules session

Demos on ESM Session during DEVOXX 2018

* **Demo 01**: Using **TypeScript** to understand the **ESM** syntax, and show the fallback to **commonjs** or **amd**.
* **Demo 02**: Creating an **Express** application and show how to deal with browsers that does not support yet **ESM**. This demo focuses on modules on the client side.
* **Demo 03**: Creating a full application with ESM on the browser.
* **Demo 04**: Make the compatible version for non ESM browser. Using Rollup to bundle / transpile.
* **Demo 05**: Show the complete solution, and migrate to .mjs nodejs.
* **Demo 06**: Demo on the future dynamic `import()` statement.

## Demo 01: Undestanding ESM

This demo will focus on:

* Writing modules in **ESM** style.
* Transpiling for **CommonJS** / **AMD** with **TypeScript**.

Open **/Demo01/start** folder. The project is starter initiliazed with **NodeJS** / **TypeScript**, and the **node-fetch** module:

If you want to create from scratch, here are the command lines:
``` cmd
npm init -f
tsc --init
npm install node-fetch
npm install @types/node-fetch
```

Create 3 files:

* app.ts
* people.ts
* speakerService.ts

**Copy/Paste** the people.ts file, and explain the export pattern

``` typescript
export class speaker {
constructor(public firstName: string, public lastName: string, public company: string) {
}

getFullName() {
return `Full name : ${this.firstName} ${this.lastName} from ${this.company} `;
}
}

export class attendee {
constructor(public firstName: string, public lastName: string) { }
}

export class user {
constructor(public firstName: string, public lastName: string) { }
}

export class dog {
constructor(public name: string) { }
}

export class cat {
constructor(public name: string) { }
}
```

**Copy/Paste** this `speakerService.ts` file, and complete with the solution below :

``` typescript
let url = "http://cfp.devoxx.fr/api/conferences/DevoxxFR2018/speakers";

async function getAllSpeakers(): Promise> {

var response:any;
var speakersJson: Array;
var speakers = speakersJson.map(s => new speaker(s.firstName, s.lastName, s.company));

return speakers;

}

```

Solution:

``` typescript
import { speaker } from "./people";
import fetch from 'node-fetch';

let url = "http://cfp.devoxx.fr/api/conferences/DevoxxFR2018/speakers";

async function getAllSpeakers(): Promise> {

var response = await fetch(url);
var speakersList: Array = await response.json();
var speakers = speakersList.map(s => new speaker(s.firstName, s.lastName, s.company));

return speakers;

}

export default getAllSpeakers;
```

and explain default pattern

``` typescript
import { speaker } from "./people";
import fetch from "node-fetch";

let url = "http://cfp.devoxx.fr/api/conferences/DevoxxFR2018/speakers";

export default async () => {

var response = await fetch(url);
var speakersJson: Array = await response.json();
var speakers = speakersJson.map(s => new speaker(s.firstName, s.lastName, s.company));

return speakers;

};

// export default getAllSpeakers;
```

**Copy/Paste** this `app.ts` file, and complete with the solution below :

``` typescript
// (async () => {

// var speakers = await getAllSpeakers();

// speakers.forEach(speaker => {
// console.log(speaker.getFullName());
// });

// })();
```

Solution :

``` typescript
import { speaker } from "./people";
import getAllSpeakers from "./speakerServices";

(async () => {

var speakers = await getAllSpeakers();

speakers.forEach(speaker => {
console.log(speaker.getFullName());
});

})();
```

Move everything about speaker **people.ts** and **speakerService.ts** in a subfolder called `/people`.

Create a file `/people/index.ts` to export everything from `/people`

``` typescript
export * from './people';
export * from './speakerServices'
```

Explain why we can't `export default` in a `export *`

Workaround to export a default export in a export all pattern

``` typescript
export * from './people';
import getAllSpeakers from './speakerServices'
export { getAllSpeakers };
```

Go back to first version and replace in `speakerServices`:

``` typescript
export { getAllSpeakers };
```

Then change the `import` statement in `app.ts`:

``` typescript
import * as ppl from "./people/index";

(async () => {

var speakers = await ppl.getAllSpeakers()

speakers.forEach(speaker => {
console.log(speaker.getFullName());
});

})();
```

## Demos 02: Checking the browser capabilities for ESM

This demo will focus on:

* Showing how to see if a browser is **Modules** compliant.
* Showing how to load a script version for non compatible browsers with `nomodule` attribute
* Showing why `defer` is important when working with **Modules**

Open **Demo2/start** folder or create an express application, using **hbs** view engine.

``` cmd
express -v hbs
npm install
```

Adding **javascript files** in `layout.hbs`, just before `