Les modules JavaScript

ES Modules

C'est quoi ?

ES Modules

// Fichier a.js

export const age = 21;
export let name = 'Florent';
export default 'Berthelot';
// Fichier B.js

import lastname, {name as firstname, age} from './a.js';

console.log(firstname, lastname, age);
// Florent Berthelot 21

ES Modules

// Fichier a.js

export const age = 21;
export let name = 'Florent';
export default 'Berthelot';
// Fichier B.js

import * as User from './a.js';

console.log(User.name, User.default, User.age);
// Florent Berthelot 21

ES Modules

import('http://cdn/d3.js')
  .then(d3 => {
    d3.makeABeautifulChart();
  });

ES Modules

ES Modules

Comment on en est arrivé là ?

Les débuts

Tu as 10 jours pour mettre Java dans Netscape

Le client (netscape) de Brendan Eich (Sun / Java)

Les débuts

<!--
<script src="./monapp.js" type="text/javascript"></script>
<script src="./pub.js" type="text/javascript"></script>
-->
// monapp.js
var password = 'ceciEstUnSecret';
// pub.js

hackUserAccount(password);

Les débuts

<!--
<script src="./monapp.js" type="text/javascript"></script>
<script src="./pub.js" type="text/javascript"></script>
-->
// monapp.js
(function() {
  var password = 'ceciEstUnSecret';
})();
// pub.js

hackUserAccount(password); // password is undefined

Les débuts

V8  + API Système = <3

J'ai des problèmes asynchrones avec le langage C

Ryan Dahl, le créateur de node.js

Les débuts

// Fichier A
exports.password = 'ceciEstUnSecret';

 Créé en Janvier 2009 par Mozilla
 ServerJS puis renommé en CommonJS

// Fichier B
const lePasswordDeFlorent = require('./fichierA').password;

Mais ce n'est pas asynchrone ?!

Les débuts

define(['jquery'], function ($) {
  return {
    motDePasse: 'CeciEstLeMDPDeFlorent'
  };
});

Créé en 2009 par Dojo

RunJS puis renommé en RequireJS

define(['motDePasse'], function (mdp) {
  console.log(`rhoo comment j'ai hacké sont MDP : ${mdp}`);
});

Les débuts

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['exports', 'b'], factory);
    } else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
        factory(exports, require('b'));
    } else {
        factory((root.commonJsStrict = {}), root.b);
    }
}(typeof self !== 'undefined' ? self : this, function (exports, b) {
    exports.action = function () {};
}));

Universal Module Declaration (UMD)

ES Module

Pourquoi il y a un problème ?

ES Module

// fichier a.js
console.log('Execution de a.js')
import { afficherPassword } from './b.js'
afficherPassword();
// fichier b.js
console.log('Execution de b.js')
export function afficherPassword () {
  console.log('leMDPDeFlorent');
}

Dans quel ordre sont affiché les messages ?

ES Module

// fichier a.js
console.log('Execution de a.js')
import { afficherPassword } from './b.js'
afficherPassword();
// fichier b.js
console.log('Execution de b.js')
export function afficherPassword () {
  console.log('leMDPDeFlorent');
}
Execution de b.js
Execution de a.js
leMDPDeFlorent

ES Module

// fichier a.js
console.log('Execution de a.js')
const afficherPassword = require('./b.js');
afficherPassword();
// fichier b.js
console.log('Execution de b.js');
module.exports = function() {
  console.log('leMDPDeFlorent');
}

Dans quel ordre sont affiché les messages ?

ES Module

// fichier a.js
console.log('Execution de a.js')
const afficherPassword = require('./b.js');
afficherPassword();
// fichier b.js
console.log('Execution de b.js');
module.exports = function() {
  console.log('leMDPDeFlorent');
}
Execution de a.js
Execution de b.js
leMDPDeFlorent

ES Modules

Et maintenant ?

ES Modules

.mjs

ES Modules

// Package.json

{
    "type": "module",
    "exports": "./index.js",
    "engines": "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
// a.js

import fs from 'node:fs/promises';

Dynamic Import

import('http://cdn/d3.js')
  .then(d3 => {
    d3.makeABeautifulChart();
  });

Work in every node.js file !

ES Module

Attention, pas d'import de JSON ! (Bientôt)

__dirname, __filename ==> import.meta.url

 

 

import { readFile } from 'fs/promises';

const json = JSON.parse(await readFile(new URL('./dat.json', import.meta.url)));

Les modules JavaScript

By Florent Berthelot