# Commencer un projet

# TL;DR

  • Créer un dossier où vous mettrez tous vos projets de développement (perso j'utilise ~/dev/projects/) ;
  • Créer dans ce dossier un sous-dossier avec le nom du projet (sans majuscule ni espace) ;
  • Créer dans ce sous-dossier un répertoire client et un autre server
  • Créer un fichier package.json avec la commande npm init ou npm init -y dans le dossier client ;
  • Créer un dépôt git avec la commande git init ;
  • Ajouter le fichier package.json dans l'index avec la commande git add package.json ;
  • Valider les modifications de l'index avec la commande git commit -m ":tada: Création du package.json" ;
  • Ajouter parcel dans les dépendances avec la commande npm i parcel-bundler ;
  • Ajouter le fichier package-lock.json dans l'index avec la commande git add package-lock.json ;
  • Ajouter les modifications de package.json dans l'index avec la commande git add package.json ;
  • Ajouter un fichier .gitignore (cf. gitignore.io (opens new window)) ;
  • Ajouter un fichier .editorconfig (cf. editorconfig.org (opens new window)) ;
  • Valider les modifications de l'index avec la commande git commit -m ":heavy_plus_sign: Ajouter parcel-bundler au projet" ;
  • Ajouter les scripts npm "start" parcel src/index.html et "build" parcel build src/*.html ;

# Les premières recommandations

Pour commencer un projet js, le mieux est de commencer par créer un fichier package.json. Il s'agit d'un fichier qui contiendra beaucoup d'informations utiles de notre projet.

Je conseille les choses suivantes pour vos projets de développement :

  • Dans votre répertoire personnel, créer un dossier dev pour tout ce qui concernera vos développements ;
  • Dans ce répertoire dev, créer un dossier projects dans lesquels il y aura tous vos projets ;
  • Dans ce répertoire projet, créer un répertoire par projet (pour l'exemple, le dossier s'appellera esilv-scratch) ;
  • Pour tous les noms de répertoire, je déconseille : les majuscules, les espaces, les caractères diacrités (comme les suivants : éàïôçł...) et les caractères spéciaux (@!) à part bien sûr les tirets - ("hyphen" ou "dash", ne dites pas "tiret du 6", s'il vous plaît) et les soulignés _ ("underscore" ou "underline", ne dites pas "tiret du 8" ou "tiret du bas", s'il vous plaît).

# Séparer la partie front-end et la partie back-end

Créer un dossier pour le projet.

Créer 2 sous-dossiers dans ce dossier :

  • client
  • server

Le dossier client contiendra la partie front-end ou client, et la partie back-end sera dans le dossier server.

# Créer un package.json

La commande npm init permet de créer un squelette de fichier de projet package.json. On peut taper sur la touche Entrée (Enter) à chaque prompt (attention à ne pas mettre d'espace dans le package-name : il prend par défaut le nom du répertoire courant).

~/dev/projects/esilv-scratch/client $ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (esilv-scratch)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /Users/stan/dev/projects/esilv-scratch/package.json:

{
  "name": "esilv-scratch",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}


Is this OK? (yes)

On peut aussi utiliser directement l'argument -y pour qu'il ne demande rien et utilise tous les paramètres par défaut :

$ npm init -y
Wrote to /Users/stan/dev/projects/esilv-scratch/client/package.json:

{
  "name": "esilv-scratch",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Pour plus de détails, cf le chapitre dédié à npm s

Pour plus de détails sur ce qu'est un fichier JSON, cf. le site officiel (opens new window).

# Créer un dépôt git

La création d'un dépôt git dans le répertoire courant se fait avec la commande git init :

~/dev/projects/esilv-scratch/ $ git init
Initialized empty Git repository in /Users/stan/dev/projects/temp/.git/

Cette commande crée un répertoire .git dans le répertoire courant qui contiendra toutes les sources et tout l'historique du projet. Il s'agit d'un fichier caché.

~/dev/projects/esilv-scratch $ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        package.json

nothing added to commit but untracked files present (use "git add" to track)

# Ajouter le fichier package.json

On peut maintenant ajouter le fichier package.json au dépôt, d'abord en l'ajoutant à l'index :

~/dev/projects/esilv-scratch/ $ cd client
~/dev/projects/esilv-scratch/client $ git add package.json

~/dev/projects/esilv-scratch/client $ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   package.json

Puis en validant la modification :

~/dev/projects/esilv-scratch/client $ git commit -m ":tada: Init JS project"
[master 8b9b3e2] :tada: Init JS project
 1 file changed, 15 insertions(+)
 create mode 100644 package.json

Note: j'aime bien mettre un gitmoji (opens new window) (emoji dédié aux commits git) au début de chaque message de commit, voir pourquoi ici (opens new window), c'est la raison des :<ici_in_gimoji>: en début de message de commit. Ce n'est pas du tout obligatoire, mais je conseille.

On peut voir le commit avec la commande git log

~/dev/projects/esilv-scratch/client $ git log
commit 8b9b3e2bfeb0ba7c954038ba23c46e0f91fe49d6 (HEAD -> master)
Author: Stanislas Ormières <stan@stormier.ninja>
Date:   Wed Mar 18 02:16:24 2020 +0100

    :tada: Init JS project

# Ajouter une dépendance

Nous aurons besoin de parcel-bundler pour la partie client.

La commande npm i parcel-bundler permet de l'installer (lancer la commande dans le répertoire client !)

npm i est un raccourci de npm install qui fonctionne aussi.

Voici ce que ça donne dans le terminal :

~/dev/projects/esilv-scratch $ cd client
~/dev/projects/esilv-scratch/client $ npm i parcel-bundler
npm WARN deprecated core-js@2.6.11: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
npm WARN deprecated mkdirp@0.5.3: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142

> fsevents@1.2.11 install /Users/stan/dev/projects/esilv-scratch/node_modules/fsevents
> node-gyp rebuild

  SOLINK_MODULE(target) Release/.node
  CXX(target) Release/obj.target/fse/fsevents.o
  SOLINK_MODULE(target) Release/fse.node

> deasync@0.1.19 install /Users/stan/dev/projects/esilv-scratch/node_modules/deasync
> node ./build.js

`darwin-x64-node-12` exists; testing
Binary is fine; exiting

> core-js@2.6.11 postinstall /Users/stan/dev/projects/esilv-scratch/node_modules/core-js
> node -e "try{require('./postinstall')}catch(e){}"

Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!

The project needs your help! Please consider supporting of core-js on Open Collective or Patreon:
> https://opencollective.com/core-js
> https://www.patreon.com/zloirock

Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)


> parcel-bundler@1.12.4 postinstall /Users/stan/dev/projects/esilv-scratch/node_modules/parcel-bundler
> node -e "console.log('\u001b[35m\u001b[1mLove Parcel? You can now donate to our open collective:\u001b[22m\u001b[39m\n > \u001b[34mhttps://opencollective.com/parcel/donate\u001b[0m')"

Love Parcel? You can now donate to our open collective:
 > https://opencollective.com/parcel/donate
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN esilv-scratch@1.0.0 No description
npm WARN esilv-scratch@1.0.0 No repository field.

+ parcel-bundler@1.12.4
added 806 packages from 478 contributors and audited 9015 packages in 28.321s

22 packages are looking for funding
  run `npm fund` for details

found 3 moderate severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

Cette commande a fait 3 choses très importantes.

  1. Elle a créé le répertoire node_modules/ dans notre dossier de projet. C'est dans ce répertoire que se trouve parcel-bundler ainsi que toutes ses dépendances, et les dépendances de ses dépendances, etc.

  2. Elle a aussi modifié le package.json : la propriété "dependencies" a été ajoutée, avec dedans "parcel-bundler": "^1.12.4", le contenu de ce fichier est désormais :

{
 "name": "esilv-scratch",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "scripts": {
   "test": "echo \"Error: no test specified\" && exit 1"
 },
 "keywords": [],
 "author": "",
 "license": "ISC",
 "dependencies": {
   "parcel-bundler": "^1.12.4"
 }
}
  1. Enfin, cette commande a généré un fichier package-lock.json. Ce fichier vérouille les versions de toutes les dépendances, directes (celles que nous avons ajoutées explicitement nous-mêmes) et indirectes (celles que nous n'avons pas ajoutées nous-mêmes mais qui sont des dépendances de celles-ci).

Il est très important de versionner (c'est-à-dire d'ajouter dans le dépôt git) ce fichier package-lock.json pour s'assurer que tous ceux qui cloneront le dépôt auront les mêmes versions de dépendances.

Le dossier node_modules quant à lui n'est pas à versionner (ne pas l'ajouter dans le dépôt git).

# Ajouter un .gitignore

Ainsi, le dossier node_modules n'est pas à versionner. Mais la commande git status liste tous les fichiers de tous les sous-dossiers de ce dossiers. Il faut donc dire à git qu'on veut ignorer node_modules... et un certain nombre d'autres fichiers et dossiers.

Le plus simple est d'utiliser le service https://www.gitignore.io/ en entrant au moins ces labels :

  • Node
  • Windows
  • macOS
  • Linux
  • VisualStudio Code

Puis cliquer sur le bouton Create, récupérer le contenu du fichier et le placer dans un fichier qui s'appelle .gitignore (oui, qui commence par un point .) à la racine du projet.

Ajouter le fichier .gitignore à l'index puis au dépôt :

~/dev/projects/esilv-scratch $ git add .gitignore

~/dev/projects/esilv-scratch $ git commit -m ":wrench: Add .gitignore file"
[master f5acb6c] :wrench: Add .gitignore file
 1 file changed, 180 insertions(+)
 create mode 100644 .gitignore

Désormais, la commande git status nous donne une sortie plus lisible :

~/dev/projects/esilv-scratch $ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   package.json

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        package-lock.json

no changes added to commit (use "git add" and/or "git commit -a")

# Ajouter package.json et package-lock.json au dépôt

On peut maintenant ajouter les fichiers package.json et package-lock.json au dépôt :

~/dev/projects/esilv-scratch $ cd client
~/dev/projects/esilv-scratch/client $ git add package*

~/dev/projects/esilv-scratch/client $ git commit -m ":heavy_plus_sign: Add parcel-bundler"
[master a0803a5] :heavy_plus_sign: Add parcel-bundler
 2 files changed, 6508 insertions(+), 1 deletion(-)
 create mode 100644 client/package-lock.json

Si je consulte les logs de git avec l'option --stat, j'obtiens la sortie suivante :

~/dev/projects/esilv-scratch/client $ git log --stat
commit a0803a5c809757d3a68368b699719edd46d06c7e (HEAD -> master)
Author: Stanislas Ormières <stan@stormier.ninja>
Date:   Wed Mar 18 13:04:50 2020 +0100

    :heavy_plus_sign: Add parcel-bundler

 client/package-lock.json | 6504 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 client/package.json      |    5 +-
 2 files changed, 6508 insertions(+), 1 deletion(-)
 (...)

package* est ce qu'on appelle un glob (opens new window) et permet de sélectionner tous les fichiers et dossier qui commencent par package, comme par exemple package.json et package-lock.json.

# Ajouter .editorconfig

Je conseille d'ajouter un fichier .editorconfig à la racine aussi avec ce contenu :

root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
quote_type = single

Pour que par défaut, VS code (et bcp d'autres éditeurs) indente de 2 espaces (sans tabulations), insère un saut de ligne à la fin du fichier, et que les sauts de lignes soient simples (version *nix et pas windows), avec le jeu de caractère UTF-8.

Ajouter le fichier .editorconfig au projet (à la racine, pas dans client).

# Écrire une page HTML simple

Emmet (opens new window) est un outil avec un ensemble de snippets (extraits de code) disponibles via des raccourcis très très utiles. Emmet est présent sous forme d'extension dans de nombreux éditeurs (atom, sublime,...) mais est déjà dans VS code et n'a pas besoin d'être installé via les extensions.

Ci-dessous un raccourci très utile pour créer facilement un squelette de page HTML5 : !, oui, tout simplement le point d'exclamation ! puis la touche Entrée. Voilà ce que ça donne dans VS code :

Raccourci emmet pour créer un squelette de page web :

Voici un lien vers la "Cheat sheet" Emmet officielle (opens new window) pour mieux voir en quoi ça peut être utile.

Voilà ce qu'on obtient :

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
  </body>
</html>

Après un minimum de modification (cf. html), on peut obtenir quelque chose comme ceci :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Titre de la page 1 - ESILV cours dev web</title>
</head>
<body>
    <header>
        <h1>Titre de la page 1</h1>
    </header>
    <main>
        Contenu principal de la page 1
    </main>
    <footer>
        &copy; Stanislas Ormières - depuis 2020
    </footer>
</body>
</html>

Pour l'ajouter au dépôt (je ne vais plus rappeler ces commandes) :

~/dev/projects/esilv-scratch/client $ git add index.html
~/dev/projects/esilv-scratch/client $ git commit -m ":sparkles: Ajouter une page index.html"

# parcel

# Qu'est-ce que parcel

Parcel (opens new window) est un empaqueteur ("bundler") "zero-config" (ne nécessite aucune configuration) qui

Pour utiliser parcel en mode dev : il faut pour cela :

  • soit 1. avoir installé parcel en global (npm install -g parcel-bundler) et taper la commande parcel index.html (je déconseille)
  • soit 2. modifier le package.json pour ajouter un script start qui lancera parcel
  1. Mauvaise solution :
~/dev/projects/esilv-scratch/client $ parcel index.html
Server running at http://localhost:1234
✨  Built in 96ms.

Pros : Pas besoin de modifier package.json et de rajouter des scripts (et on n'a pas besoin de savoir ce que sont les scripts).

Cons : Besoin d'installer parcel à part (et de savoir qu'il faut l'installer)... valable pour tous ceux qui voudront travailler sur le projet. Besoin de savoir comment on build avec parcel.

  1. Bonne solution :

Rajouter des scripts dans package.json :

 (...)
 "scripts": {
   "start": "parcel index.html",
   "build": "parcel build index.html"
 },
 (...)

On peut savoir quels sont les scripts disponibles avec la commande npm run :

~/dev/projects/esilv-scratch/client $ npm run
Lifecycle scripts included in esilv-scratch:
  start
    parcel index.html

available via `npm run-script`:
  build
    parcel build index.html

(Note : On peut aussi les connaître et les exécuter depuis VS code avec l'extension NPM-scripts (opens new window).)

La première partie est la partie des scripts standards (opens new window) qui ne nécessitent pas l'utilisation du premier argument run (comme npm start ou npm test). La deuxième partie est la liste des scripts "arbitraires" (comprendre "custom" ou "personnalisés") et qui nécessitent donc run-script ou plus simplement run :

# Lancer le mode dev

~/dev/projects/esilv-scratch/client $ npm start  

> esilv-scratch@1.0.0 start /Users/stan/dev/projects/esilv-scratch/client
> parcel index.html

Server running at http://localhost:56041 - configured port 1234 could not be used.
✨  Built in 304ms.

# Lancer le build du projet

~/dev/projects/esilv-scratch/client $ npm run build

> esilv-scratch@1.0.0 build /Users/stan/dev/projects/esilv-scratch/client
> parcel build index.html

✨  Built in 430ms.

dist/index.html     373 B     200ms

Cons : Besoin de modifier package.json et de rajouter des scripts.

Pros : Utilisation de scripts standards de npm ou standard de facto (build). Apprentissage des scripts npm pour les nouveaux. Visualisation facile de la liste des scripts npm disponibles. Sert de documentation du projet.

# Ajouter une deuxième page

Créer une deuxième page HTML page-2.html avec ce contenu :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Page 2 - ESILV Cours dev web</title>
</head>
<body>
    <header>
        <h1>
            Titre page 2
        </h1>
    </header>
    <main>
        <p>
            Contenu de la page 2
        </p>
        <p>
            Aller à l'<a href="./">index</a>
        </p>
    </main>
    <footer>
        &copy; Stanislas Ormières 2020
    </footer>
</body>
</html>

Et modifier la page index.html pour avoir ce contenu :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Page 1 </title>
</head>
<body>
    <header>
        <h1>
            Titre page 1
        </h1>
    </header>
    <main>
        <p>
            Contenu de la page 1
        </p>
        <p>
            Aller à la <a href="./page-2.html">page 2</a>
        </p>
    </main>
    <footer>
        &copy; Stanislas Ormières 2020
    </footer>
</body>
</html>

On peut vérifier si on veut bien ajouter tout ce qu'on veut avec la commande git add -p :

~/dev/projects/esilv-scratch/client $ git add -p
diff --git a/client/index.html b/client/index.html
index a48a7a8..414ba6f 100644
--- a/client/index.html
+++ b/client/index.html
@@ -12,7 +12,12 @@
         </h1>
     </header>
     <main>
-        Contenu de la page 1
+        <p>
+            Contenu de la page 1
+        </p>
+        <p>
+            Aller à la <a href="./page-2.html">page 2</a>
+        </p>
     </main>
     <footer>
         &copy; Stanislas Ormières 2020
Stage this hunk [y,n,q,a,d,e,?]?

On peut répondre y puis la touche entrée.

Et ajouter la page page-2.html avec git add page-2.html et ensuite valider les modifications avec git commit -m ":sparkles: Add second page"

# Ajouter du JavaScript

Créer un fichier main.js dans le répertoire client avec ce contenu :

console.log('Message de main.js')

Ajouter ensuite la ligne suivante juste avant la fin de la fermeture du </body> :

    <script src="./main.js"></script>

Il y aura donc à la fin du fichier :

(...)
    <footer>
        &copy; Stanislas Ormières 2020
    </footer>
    <script src="./main.js"></script>
</body>
</html>

Dans la console des dev tools du navigateur, il y aura "Message de main.js" qui s'affichera.

~/dev/projects/esilv-scratch/client $ git add index.html main.js

~/dev/projects/esilv-scratch/client $ git commit -m ":sparkles: Add simple JavaScript file"
[master 74aad21] :sparkles: Add simple JavaScript file
 2 files changed, 2 insertions(+)
 create mode 100644 client/main.js

Voilà, plus que le CSS et on sera bon pour commencer à fournir du travail à un client !!!

# Ajouter du CSS