Activité Programmation en JavaScript : plateformes d'exécution et introduction à la gestion d’événements

Situation

Vous êtes au début d’un projet de développement d’une application web. Vous envisagez d’utiliser JavaScript pour le développement de la partie client et de la partie serveur. Comme vous n’avez pas beaucoup d’expérience avec ce langage, vous décidez d’effectuer quelques tests technologiques.

Consigne

Réaliser les labs décrits ci-après et consigner le résultat de votre travail dans un document. Lisez attentivement tout le texte. Le but est d’apprendre JavaScript en exécutant du code, pas d’exécuter du code bêtement. Le travail est individuel, car il est important que tous les membres du groupe de projet soient capables de programmer la solution.

Un rapport qui ne contient que les réponses aux questions explicitement posées n’est pas suffisant. Le résultat de ce travail fait partie de la livraison du sprint 0.

Objectifs

À la fin de ce travail, vous devez :

  1. Connaître la notion d’entité de première class (first-class citizen) dans le contexte des langages de programmation.
  2. Connaître la notion de fonction anonyme ou expression lambda (lambda expression).
  3. Connaître la notion de fonction callback.
  4. Être capable d’utiliser une fonction anonyme en JavaScript.
  5. Être capable de lier un programme JavaScript à un document HTML à l’aide de la balise <script>
  6. Être capable d’utiliser les outils de développements (developer tools) d’un navigateur.

Résultat attendu

  • Un rapport de votre travail
  • Une archive zip contenant les répertoires lab1, lab2 et lab3.

Ressources

Logiciel :

  • Un éditeur de texte (VS Code).
  • Le gestionnaire de dépôt git.
  • La plateforme Node.js (node, npm, npx, etc.)
  • Un shell (bash, powershell, cmd).
  • Un navigateur web (Chrome, Firefox, IE).

Documents :

Mise en place de l’environnement

Pour ce travail, nous avons besoin d’un certain nombre de programmes :

  • le système de gestion de version Git qui permet également d’obtenir un code source depuis un dépôt GitHub ou GitLab.
  • la plateforme logicielle Node.js et l’interpréteur node qui permet la réalisation de programme en JavaScript.
  • le gestionnaire de dépendances npm qui fait partie de la plateforme Node.js et qui permet d’automatiser l’installation des bibliothèques dont nous aurons besoin.
  • l’éditeur Visual Studio Code (VSC).

Pour vérifier que ces programmes sont présents, ouvrez une fenêtre de terminal avec un shell (bash, powershell, cmd, etc.), lancez les commandes ci-après et vérifiez que chacune d’elle renvoie un numéro de version.

1
2
3
4
git --version
node --version
npm --version
code --version

Installez les programmes manquant à l’aide du gestionnaire de paquet de votre système d’exploitation (choco, brew, apt, etc.) manquantes puis rendez-vous ensuite dans votre répertoire de travail, par exemple %USERPROFILE%\work\m120\ ou ~/work/m120/ (au besoin, créez-en un). N’utilisez pas un disque réseau comme répertoire de travail.

Prenez l’habitude de travailler à l’aide de l’interface en ligne de commande (CLI) de votre système d’exploitation, même si cela peut sembler un peu fastidieux au début.

JavaScript : un langage, plusieurs plateformes

JavaScript ou ECMAScript est un langage de programmation utilisé traditionnellement pour ajouter des fonctionnalités à des documents HTML dans un navigateur web (Chrome, Firefox, etc.). Ce langage ne doit pas être confondu avec Java ni avec les Java Applets aujourd’hui disparues. En dehors de certaines similitudes dans leurs noms et leurs syntaxes voulues pour des raisons marketing, Java et JavaScript n’ont rien de commun. Longtemps cantonné au navigateur web, JavaScript est aujourd’hui également utilisé pour le développement de programmes utilitaires et de serveurs grâce à la plateforme Node.js.

Il est important de réaliser que JavaScript dispose d’au moins deux plateformes bien distinctes pour l’exécution de programmes : les navigateurs web (WebAPI) et la plateforme Node.js.

L’utilisation traditionnelle de JavaScript est la réalisation de scripts pour l’ajout de fonctionnalités aux documents HTML. Les scripts sont alors exécutés par le moteur JavaScript (JavaScript Engine) du navigateur.

Les scripts liés à un document à l’aide d’éléments HTML <script>. L’exécution d’un script a lieu lors du chargement du document par le navigateur, au moment où un élément <script> est traité. Le chargement et l’affichage du document HTML sont suspendus durant l’exécution du script. Les éléments HTML sont traités dans l’ordre où ils apparaissent dans le code HTML.

Dans ce contexte, l’objet Global de JavaScript est référencé par la variable globale window. Parmi les propriétés de cet objet, on trouve notamment :

  • window.document : Renvoie une référence un objet qui représente le document HTML (Document Object Model ou DOM).
  • window.console : Renvoie une référence à l’objet console qui fournit l’accès à la console de débogage du navigateur.

Les propriétés et les méthodes de l’objet Golbal peuvent être invoquées directement, sans avoir à spécifier la variable window. Écrire console.log("Hallo") est équivalent à écrire window.console.log("Hallo"). La première version est généralement préférée pour les propriétés et les méthodes définies par le standard ECMAScript (p. ex. console.log()). Pour les propriétés et les méthodes spécifique au navigateur, on préfère la seconde (p. ex. window.alert())

Plateforme Node.js

L’arrivée de la plateforme Node.js en 2009 a permis d’utiliser JavaScript en dehors du navigateur. Cette plateforme a été conçue pour la réalisation de serveurs et est donc particulièrement bien adaptée à cet usage.

L’interpréteur node de la plateforme permet d’exécuter un programme JavaScript de la même manière que l’interpréteur python permet d’exécuter un programme Python. La commande ci-après lance l’exécution du programme JavaScript contenu dans le fichier my-prog.js.

1
node my-prog.js

Dans ce contexte, l’objet Global de JavaScript n’est pas référencé par une variable comme dans le navigateur. Les méthodes et les propriétés de l’objet Global sont toujours invoquées directement. Parmi les propriétés et les méthodes de l’objet Global dans la plateforme Node.js on trouve notamment :

  • console : Renvoie un objet qui permet d’écrire dans la sortie standard (stdin) et dans la sortie d’erreur standard (stderr)
  • __dirname : Renvoie le chemin du fichier en cours d’exécution.
  • __filename : Renvoie le nom complet (chemin et nom) du fichier en cours d’exécution.
  • require() : Charge un objet depuis un module.

L’objet Global de Node.js n’a évidemment pas de propriété document.

Programmer en Javascript pour un navigateur (lab1)

Dans ce premier lab, vous allez exécuter du code JavaScript dans un navigateur web.

Dans votre répertoire de travail, créez un répertoire lab1, faites-en le répertoire courant et ouvrez le Visual Studio Code.

1
2
3
mkdir lab1
cd lab1
code .

Premiers pas

Pour exécuter un programme JavaScript dans un navigateur web, on a besoin d’un document HTML avec une balise <script>. Utilisez votre éditeur de texte pour créer un fichier lab1.html avec le code suivant : [subs=+quotes]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>M120 - Lab 1</title>
</head>

<body>
    <h1>M120 – Lab 1</h1>
    <p>
        Actualisez la page pour exécuter le script après un changement dans « hello-world.js.js ».
    </p>

    <!--
    En principe, les éléments script sont regroupés
    à la fin de l’élément body.
    -->
    <script src="./my-library.js"></script>
    <script src="./hello-world.js"></script>
</body>

</html>

Ouvrez le fichier dans votre navigateur et avec votre éditeur et organisez votre écran pour avoir votre éditeur de texte et votre navigateur l’un à côté de l’autre. Utilisez votre éditeur de texte pour créer un fichier hello-world.js et saisir le code suivant :

1
2
// Affiche une boîte de message.
window.alert('Hello world !')

Rafraîchissez la page pour exécuter le code.

Exécution des scripts

Vous pouvez observer qu’une boîte de message s’ouvre et que la page reste blanche tant que cette boîte n’est pas fermée. Ce comportement illustre la manière dont sont exécutés les scripts.

Le code JavaScrript est lié à un document HTML à l’aide d’éléments <script>. Le code d’un élément <script> est exécuté lorsque cet élément est traité par le navigateur lors du chargement du document. Tout comme les autres éléments, les éléments <script> sont traités dans l’ordre d’apparition dans le code HTML. C’est pourquoi on regroupe généralement les éléments <script> à la fin de l’élément <body>. En effet, de cette manière, on s’assure que tous les éléments du document ont été traités et chargés dans le DOM lorsque les scripts sont exécutés.

Le code JavaScript est exécuté dans le même thread que le chargement et l’affichage du document. La page ne peut donc pas s’afficher durant le chargement de la page ou durant l’exécution de code JavaScript. Comme la méthode alert() est bloquante, c’est-à-dire qu’elle ne retourne que lorsque la boîte de message est fermée, il ne peut rien se passer tant qu’elle est ouverte. On observerait le même phénomène si le script effectuait un long calcul.

Pour réaliser des documents HTML qui se charge rapidement, il est important de limiter au maximum le temps d’exécution des scripts au chargement.

Outils de développement

Les navigateurs modernes sont équipés d’outils de développement. Ces outils ne sont pas destinés à remplacer un environnement de développement pour la réalisation de programme en JavaScript pour le navigateur, mais à faciliter leur mise au point. Parmi ces outils, on trouve en particulier :

  • Une console (onglet console) qui permet de visualiser les messages écrits à l’aide de l’objet console et d’exécuter du code de manière interactive.
  • Un debugger (onglet source) qui permet notamment de placer des points d’arrêt dans les fichiers JavaScript lié au document HTML et d’exécuter le code pas à pas.

Ouvrez les outils de développement de votre navigateur et sélectionnez l’onglet Console.

Fig. 1 – Outils de développement Fig. 1 – Outils de développement
Fig. 1 – Outils de développement

Modifier le code de votre fichier hello-world.js pour afficher un message dans la console au lieu d’une boîte de messsage.

1
2
// Affiche une chaîne dans la console.
console.log('Hello world !')

Rafraîchissez la page pour exécuter le code et observez la console de votre navigateur.

Déclarer des variables

Par défaut, JavaScript n’exige pas la déclaration des variables. Si une variable n’est pas déclarée, elle est créée à la première utilisation. Modifiez votre programme comme ci-après et rafraîchissez la page.

1
2
3
4
5
// Affecte une chaîne à la variable myString qui n’a pas été déclarée.
myString = 'Hello world !'

// Affiche la valeur de myString dans la console.
console.log(myString)

Toutefois, il est préférable de déclarer les variables, car toutes les variables non déclarées sont globales. Il y a deux manières de déclarer une variable :

  • avec le mot clé const : la variable doit être initialisée et sa valeur ne peut pas être modifiée par une affectation.
  • avec le mot clé let : l’initialisation de la variable est optionnelle et sa valeur peut être modifiée par une affectation.

On préférera autant que possible const et on utilisera let que si la modification de la valeur de la variable est nécessaire (p. ex. variable de boucle).

1
2
3
4
5
6
7
8
9
// Déclare la variable myString et initialise sa valeur.
const myString = 'Hello world !'

// Déclare la variable de boucle avec let, car sa valeur
// doit pouvoir être modifiée.
for (let i = 0; i < 4; i += 1) {
  // Affiche la concaténation de plusieurs chaînes dans la console
  console.log(myString + ' (' + (i + 1) + 'x)')
}

Essayez de déclarer la variable de boucle avec const et constatez l’effet.

Définir le type d’une variable

JavaScript est un langage dynamiquement typé, c’est-à-dire que le type d’une variable est le type de la valeur qu’elle contient. Le mot clé typeof permet d’afficher le type d’une variable.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Déclare la variable myString et initialise sa valeur.
const myString = 'Hello world !'

// Déclare la variable de boucle avec let, car sa valeur
// doit pouvoir être modifiée.
for (let i = 0; i < 4; i += 1) {
  // Affiche la concaténation de plusieurs chaînes dans la console
  console.log(myString + ' (' + (i + 1) + 'x)')

  console.log('Le type de i est : ' + typeof (i) + ', le type de myString est : ' + typeof (myString))
}
console.log('\n\nExtérieur de la boucle')

// La variable i n’est pas définie en dehors de la boucle,
// son type est donc undefined.
console.log('Le type de i est : ' + typeof (i) + ', le type de myString est : ' + typeof (myString))

Observez l’expression passée à la méthode console.log de la ligne 8. Que se passe-t-il si l’on retire les parenthèses autour de i + 1 ? Décrivez chaque étape de l’évaluation avec et sans les parenthèse.

Déclarer des fonctions

Créez un nouveau fichier nommé my-library.js et copiez le code ci-après. Modifiez ensuite le fichier lab1.html de telle manière que ce nouveau fichier soit chargé et exécuté avant le fichier hello-world.js, et rafraîchissez la page pour exécuter le code. Assurez-vous que l’ordre d’exécution est bien my-library.js en premier et hello-world.js en second.

1
2
3
4
5
6
7
8
9
// Déclare une fonction nommée 'square' qui élève au carré
// une valeur passée en paramètre.
function square (value) {
  return value * value
}

// Applique la fonction square à la valeur 2 et affiche
// le résultat dans la console.
console.log('Le carré de 2 est : ' + square(2))

Le code précédent déclare une fonction square puis l’applique à la valeur 2. On recommande d’éviter l’utilisation de cette syntaxe pour au moins trois raisons :

  • Elle cache le fait que c’est une instruction dont l’effet est d’ajouter une méthode à l’objet Global.
  • Elle ne permet pas de se rendre compte qu’en JavaScript une fonction est un objet.
  • Cette syntaxe ne peut pas être utilisée pour la création de fonctions imbriquées (une fonction à l’intérieur d’une fonction).

La manière recommandée de déclarer une fonction en JavaScript est d’affecter une fonction anonyme à une variable. La partie droite d’une affectation étant toujours une expression, une fonction anonyme est donc une expression que l’on appelle expression lambda. Il s’agit d’une valeur littérale de fonction dont l’effet est de créer un objet de type function de la même manière qu’une valeur littérale de chaîne a pour effet de créer un objet de type string.

Modifier my-library.js avec le code ci-après et rafraîchissez la page.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// La partie droite de l’affectation (depuis le mot clé
// function à l’accolade fermée) est une expression lambda.
// Cette expression a pour effet de créer un objet de type 
// function. Après l’exécution de l’affection, la variable 
// square contient une référence à la fonction.
const square = function (value) {
  return value * value
}

// On peut vérifier que la variable square est bien de type
// function à l’aide du mot clé typeof.
console.log('Le type de la variable square est : ' + typeof (square))

// Applique la fonction square à la valeur 2 et affiche
// le résultat dans la console.
console.log('Le carré de 2 est : ' + square(2))

// L’appel d’une fonction avec la syntaxe classique square(2)
// est un raccourci pour appeler la méthode apply de l’objet
// de type function. Le premier argument est la valeur de
// this; une fonction globale est une méthode de l’objet
// Global référencé par la variable window. Le second argument
// est un tableau contenant les paramètres effectifs de la
// fonction.
console.log('Le carré de 2 est : ' + square.apply(window, [2]))

L’exécution des deux fichiers JavaScript devrait donner la trace suivante :

Fig. 2 – Trace de l’exécution de my-library.js et hello-world.js
Fig. 2 – Trace de l’exécution de my-library.js et hello-world.js

Comme la déclaration d’une fonction en JavaScript est en réalité l’affectation d’un objet de type function à une variable, il devient évident d’une part qu’une fonction est un objet, mais surtout que la variable qui dénote la fonction doit avoir été initialisée avant qu’on puisse l’utiliser.

Les différents fichiers JavaScript liés à un document HTML ne forment qu’un seul et même programme. Puisque le fichier my-library.js est exécuté avant , la fonction crée dans le fichier my-library.js et référencé par la variable globale square peut être utilisée dans le fichier hello-world.js.

Modifier le fichier hello-world.js avec le code ci-après et rafraîchissez la page.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Déclare la variable myString et initialise sa valeur.
const myString = 'Hello world !'

// Déclare la variable de boucle avec let, car sa valeur
// doit pouvoir être modifiée.
for (let i = 0; i < 4; i += 1) {
  // Affiche la concaténation de plusieurs chaînes dans la console
  console.log(myString + ' (' + (i + 1) + 'x)')

  console.log('Le type de i est : ' + typeof (i) + ', le type de myString est : ' + typeof (myString))
}
console.log('\n\nExtérieur de la boucle')

// La variable i n’est pas définie en dehors de la boucle,
// son type est donc undefined.
console.log('Le type de i est : ' + typeof (i) + ', le type de myString est : ' + typeof (myString))

// Appel la fonction référencée par la variable square.
const val = 4
const res = square(val)
console.log('Le carré de ' + val + ' est : ' + res)

Utiliser des expressions lambda (lab2)

Dans votre répertoire de travail, créez un répertoire lab2, faites-en votre répertoire courant et créez un fichier lab2.html avec le code suivant :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>M120 - Lab 2</title>
</head>

<body>
    <h1>M120 – Lab 2</h1>
    <p>
        Actualisez la page pour exécuter le script après un changement dans « my-lib-1.js ».
    </p>

    <!--
    En principe, les éléments script sont regroupés
    à la fin de l’élément body.
    -->
    <script src="./my-lib-1.js"></script>
</body>

</html>

Puisqu’une fonction est un objet, il s’en suit que :

  • une fonction peut être passée en paramètre à une autre fonction,
  • une fonction peut renvoyer une fonction.

On dit qu’une fonction est une entité de première classe (voir encadré).

Passer une fonction en paramètre

Créez un fichier my-lib-1.js et copiez le code suivant :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const points = [40, 100, 1, 5, 25, 10]

// Crée un objet de type fonction et
// affecte la référence à la variable
// compare.
const compare = function (a, b) {
  return a - b
}

console.log(points)

// Appelle la méthode sort en passant
// la variable compare qui référence
// la fonction de comparaison.
points.sort(compare)

console.log(points)

Dans le code précédent, nous avons affecté l’expression lambda à la variable compare avant de passer cette variable à la méthode sort. Il est également possible de passer directement l’expression lambda  :

1
2
3
4
5
6
7
8
9
10
11
12
const points = [40, 100, 1, 5, 25, 10]

console.log(points)

// Appelle la méthode sort en passant
// directement une expression lambda
// pour la fonction de comparaison.
points.sort(function (a, b) {
  return a - b
})

console.log(points)

La fonction de comparaison est passée en paramètre à la fonction de tri, mais elle n’est pas appelée à ce moment-là. La fonction de comparaison est appelée en retour (callback) par la fonction de tri pour comparer deux éléments. La fonction de comparaison doit renvoyer un nombre négatif si l’élément a est plus petit que l’élément b, zéro si l’élément a et l’élément b sont égaux, et un nombre positif si l’élément a est plus grand que l’élément b.

Allez dans l’onglet Sources des outils de développement et sélectionnez le fichier my-app.js. Placez un point d’arrêt (breakpoint) à la ligne 3, rafraîchissez la page et exécutez pas-à-pas en utilisant le bouton step into (pas le bouton step over).

Fig. 3 – Point d’arrêt dans l’onglet Sources
Fig. 3 – Point d’arrêt dans l’onglet Sources

Étudiez ce code et la documentation de la méthode sort son fonctionnement pour en comprendre le fonctionnement. Combien de fois la fonction de comparaison est-elle appelée ? Par quel sous‑programme ? Modifiez la fonction pour trier le tableau dans l’ordre décroissant.

Les onglets Sources et Console sont des outils précieux pour comprendre et déboguer du code JavaScript. Familiarisez-vous avec ces outils et assurez-vous d’avoir bien compris tout ce que vous avez fait jusque là. Comprendre qu’une fonction JavaScript est un objet et qu’une expression lambda est une entité de première classe est une étape essentielle pour programmer en JavaScript.

Fonctions imbriquées

Créez un fichier my-lib-2.js, liez-le à au document HTML et copiez le code suivant :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Affecte une procédure à une variable locale.
const mySuperFunction = function () {
  // Affecte la valeur d’une expression lambda (une fonction
  // anonyme) à une variable locale.
  const sqrt = function (value) {
    return Math.pow(value, 0.5)
  }

  // Calcule le carré de 2 et écrit le résultat dans la console.
  console.log('La racine de deux est : ', sqrt(2))
}

// Invoke l’exécution de la procédure. Les parenthèses sont vides, car
// la procédure n’a pas d’arguments, mais elle indique que la fonction
// doit être appelée.
mySuperFunction()

// N’a pas d’effet (n’importe quelle expression est une instruction).
mySuperFunction

// Génère une exception, la fonction sqrt n’est pas définie en dehors
// de la fonction mySuperFunction.
console.log('La racine de deux est : ', sqrt(2))

Programmer en JavaScript pour la plateforme Node.js (lab3)

La plateforme Node.js permet de réaliser des programmes en JavaScript indépendant d’un document HTML et d’un navigateur. Grâce à cette plateforme, JavaScript devient un langage de programmation à usage général, même si la plateforme est particulièrement adaptée à la réalisation de serveurs.

Pour ce troisième lab, en plus du navigateur, nous avons besoin d’une fenêtre de terminal. Orgnanisez l’écran de manière à avoir une fenêtre de terminal, votre navigateur et votre éditeur de texte. Si vous utilisez Visual Studio Code, vous pouvez également utiliser le terminal intégré.

Premier programme

Dans votre répertoire de travail, créez un répertoire lab3 et faites-en votre répertoire courant.

Pour exécuter un programme JavaScript avec la plateforme Node.js, il suffit d’écrire le programme dans un fichier et de passer ce fichier à l’interpréteur node. Avec votre éditeur de texte, créez un fichier my-server.js et ajoutez-y l’instruction suivante :

1
2
3
// Affiche la chaîne "Hello world !" dans la
// sortie standard (stdout)
console.log('Hello world !')

Dans la fenêtre de terminal, tapez la commande suivante :

1
# node my-server.js

Installer un package avec npm

La plateforme Node.js ne dispose d’une bibliothèque standard comme celle de Java, mais repose sur la disponibilité d’un grand nombre de petites bibliothèques. Pour faciliter la gestion des dépendances, la plateforme dispose de l’utilitaire npm.

Nous reviendrons plus avant sur l’utilisation de cet utilitaire pour la réalisation de package. Dans ce lab, nous ne l’utiliserons que comme gestionnaire de paquet pour installer le framework Express.js.

1
# npm install express

Le paquet que vous avez installé se trouve dans le répertoire node_modules. Ce répertoire peut devenir assez volumineux. Comme il peut être facilement reconstitué, il est recommandé de ne pas l’inclure dans vos sauvegardes. Il est cependant utile d’archiver toutes les dépendances utilisées pour la livraison du projet.

Réaliser un serveur HTTP avec Express.js

Le framework Express.js permet de réaliser un serveur HTTP en quelques lignes de code. Ouvrez le fichier my-server.js et tapez le code suivant :

1
2
3
4
5
6
7
8
9
10
11
const express = require('express')
const app = express()

app.get('/', function (req, res) {
  res.send('Hello World!')
})

app.listen(3000, function () {
  console.log('Server address: http://127.0.0.1:3000/')
  console.log('Server running... press ctrl-c to stop.')
})

Exécutez le programme à l’aide de l’interpréteur node puis utiliser le navigateur pour afficher l’url indiquée.

Servir des ressources statiques

Avec le serveur Express.js, il est également très facile de servir des ressources statiques. Arrêtez votre serveur et modifiez votre fichier my-server.js conformément au code ci-après.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Ce programme implémente un serveur HTTP et est exécuté
// par la plateforme Node.js

const express = require('express')
const app = express()

app.get('/', function (req, res) {
  res.send(
    '<h1>M120 – Lab 3</h1>' +
        '<p>Cette ressource dynamique est servie par le serveur HTTP <code>my-server.js</code></p>' +
        '<p>Aller à : <a href="/static/my-page.html">msy-page.html</a></p>')
})

app.use('/static', express.static(__dirname + '/public'))

app.listen(3000, function () {
  console.log('Server address: http://127.0.0.1:3000/')
  console.log('Server running... press ctrl-c to stop.')
})

Dans le répertoire lab3, créez la structure de répertoires suivante (depuis votre éditeur ou à l’aide du terminal) :

1
2
3
4
5
lab3
└──public
   ├── css
   ├── img
   └── libs

Dans le répertoire public créez un fichier my-page.html et copiez le code suivant :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>M120 - Lab 3</title>
    </head>
    <body>
        <h1>M120 – Lab 3</h1>
        <p>
            Cette ressource statique est servie par le serveur HTTP <code>my-server.js</code>
        </p>

        <!-- En principe les éléments script sont regroupés à la fin de l’élément body. -->
        <script src="/static/libs/my-script.js"></script>
    </body>
</html>

Dans le répertoire public/libs créez un fichier my-script.js et copiez le code suivant :

1
2
// Ce programme est un script exécuté par le navigateur.
console.log('Ce message s’affiche dans la console du navigateur.')

Exécutez le serveur à l’aide de l’interpréteur node et naviguez vers l’URL indiquée.

Fig. 1 – Outils de développement Fig. 1 – Outils de développement
Fig. 4 – Ressource dynamique et ressource statique.

Étudiez le code du serveur HTTP my-server.js et expliquez la différence entre la ressource statique et la ressource dynamique. Quelle est la plateforme qui exécute le fichier my-server.js ? Quelle plateforme exécute le fichier my-script.js ? À quel moment le fichier my-script.js est-il exécuté ?

Conclusion

Durant ce travail, vous avez pu expérimenter l’exécution de programme JavaScript sur deux plateformes d’exécution différentes : le navigateur et la plateforme Node.js. Vous avez également appris qu’en JavaScript, la déclaration d’une fonction se réalise par l’affectation d’une expression lambda (fonction anonyme) à une variable. Une expression lambda crée un objet de type function de la même manière qu’une valeur littérale de chaîne (p. ex. "Hello world!") crée un objet de type string. Enfin, étant une entité de première classe, une expression lambda peut être affectée à une variable, passée en paramètre et renvoyée par une fonction.