From f4f15885d2b7382f095158445eb442a708a3dc50 Mon Sep 17 00:00:00 2001 From: oabdelnour <oabdelnour@takima.fr> Date: Tue, 27 Feb 2024 00:12:23 +0100 Subject: [PATCH] wip --- resources/docs/docs/chapters/tp/npm.md | 96 ++++++----- resources/docs/docs/chapters/tp/setup.md | 13 +- resources/docs/docs/chapters/tp/spa.md | 204 +++++++++++------------ resources/docs/mkdocs.yml | 13 +- 4 files changed, 163 insertions(+), 163 deletions(-) diff --git a/resources/docs/docs/chapters/tp/npm.md b/resources/docs/docs/chapters/tp/npm.md index 96bfcf5..1513b6a 100644 --- a/resources/docs/docs/chapters/tp/npm.md +++ b/resources/docs/docs/chapters/tp/npm.md @@ -16,9 +16,11 @@ Fortunately, we now have the [**NPM**](https://docs.npmjs.com/about-npm) (Node P _NPM_ comes with a [_CLI_](https://docs.npmjs.com/cli/v9/commands) to easily create a project, install some dependencies and so on. -## :fontawesome-solid-gear: The _NPM_ configuration file +## The _NPM_ configuration file +<hr> A project that uses _NPM_ comes with a configuration file at the root directory called [`package.json`](https://docs.npmjs.com/files/package.json). It contains some project metadata like: + - the package name - the version - a description @@ -30,11 +32,11 @@ A project that uses _NPM_ comes with a configuration file at the root directory These informations will be set in the `package.json` file by the `npm init` command. -### :fontawesome-solid-terminal: `npm init` <Diy/> <BadgeEasy /> +### `npm init` <span id="diy"> Do it yourself </span> At the root of the `front-end/` directory, initialize a new NPM package with the [`npm init` command](https://docs.npmjs.com/creating-a-package-json-file#running-a-cli-questionnaire). -??? tip "Show the commands" +??? note "Show the commands" ```bash linenums="1" cd front-end/ @@ -56,7 +58,7 @@ This command will ask you to fill in some informations. Set your own values here === "package.json" - ```json + ```json linenums="1" { "name": "username-meme-ory", "version": "1.0.0", @@ -74,12 +76,13 @@ This command will ask you to fill in some informations. Set your own values here ``` -> **info** The project name is prefixed with `username`. This is your namespace and it avoids collisions with existing packages in case you want to publish your package to the [NPM repository](https://www.npmjs.com/) +!!! info "Infos" + The project name is prefixed with `username`. This is your namespace and it avoids collisions with existing packages in case you want to publish your package to the [NPM repository](https://www.npmjs.com/) - Make your package private: package.json -```javascript +```javascript linenums="1" { // ... "private": true, @@ -88,8 +91,9 @@ package.json ``` -> **tip** _NPM_ is not only a tool, it is also connected to the [official NPM repository](https://www.npmjs.com/). There, you can search for and download libraries published by other npm users, but also publish your own package with the `npm publish command`. -> Set your package as private to avoid publishing it to the repository by accident. +!!! tip "Tip" + _NPM_ is not only a tool, it is also connected to the [official NPM repository](https://www.npmjs.com/). There, you can search for and download libraries published by other npm users, but also publish your own package with the `npm publish command`.<br> + Set your package as private to avoid publishing it to the repository by accident. #### <i class="fas fa-folder-tree"></i> Modified files @@ -110,7 +114,7 @@ All of our project [**dependencies**](https://docs.npmjs.com/specifying-dependen === "package.json" - ```json + ```json linenums="1" { "name": "server", "version": "1.0.0", @@ -140,18 +144,19 @@ All of our project [**dependencies**](https://docs.npmjs.com/specifying-dependen Go back in the `front-end/` folder and install the `http-server` library as a [**development dependency**](https://docs.npmjs.com/specifying-dependencies-and-devdependencies-in-a-package-json-file) for our project. -> **info** A `devDependency` is a dependency required for development and testing, but not needed for production. +!!! info "Infos" + A `devDependency` is a dependency required for development and testing, but not needed for production. To install a _devDependency_, we will use the `npm install` command along with the `--save-dev` or `-D` flag. === "alias" - ```bash + ```bash linenums="1" cd front-end npm install -D http-server ``` === "verbose" - ```bash + ```bash linenums="1" cd front-end npm install --save-dev http-server ``` @@ -160,7 +165,7 @@ To install a _devDependency_, we will use the `npm install` command along with t === "front-end/package.json" - ```json + ```json linenums="1" { "name": "username-meme-ory", "version": "1.0.0", @@ -181,23 +186,23 @@ To install a _devDependency_, we will use the `npm install` command along with t Notice how your `package.json` has been updated with a `devDependencies` key. !!! info "Infos" - > Did you see? The _http-server_ version is specified as `X.Y.Z`. This convention **enforced by NPM** is called **[Semantic Versioning (Semver)](https://docs.npmjs.com/about-semantic-versioning/)**. - >  - > **A package cannot be published if it does not follow this convention.** - > - > This allows you to specify a [**version range**](https://docs.npmjs.com/cli/v6/using-npm/semver#ranges) for a dependency. - > In our example, `^14.1.1` means compatible with all `14.1.*` versions. - > `14.1.0` <= _version_ < `14.2.0` (see: [cheatsheet](../10.cheatsheet/CHEATSHEET.md#semver)) - > Dependencies versions within the range are considered compatible and _NPM_ could update the package by itself when you run `npm install`. - > However, it could lead to inconsistencies if one does `npm install` after some time and a dependency got updated in the meantime within the range. - > That's why, _NPM_ also generated a [`package-lock.json`](https://docs.npmjs.com/cli/v8/configuring-npm/package-lock-json). In a nutshell, `package-lock.json` is like a verbose version of `package.json`. It lists transitive dependencies (ie: dependencies of our dependencies) and fixes each and every package version. + Did you see? The _http-server_ version is specified as `X.Y.Z`. This convention **enforced by NPM** is called **[Semantic Versioning (Semver)](https://docs.npmjs.com/about-semantic-versioning/)**. +  + **A package cannot be published if it does not follow this convention.** + + This allows you to specify a [**version range**](https://docs.npmjs.com/cli/v6/using-npm/semver#ranges) for a dependency. + In our example, `^14.1.1` means compatible with all `14.1.*` versions. + `14.1.0` <= _version_ < `14.2.0` (see: [cheatsheet](../10.cheatsheet/CHEATSHEET.md#semver)) + Dependencies versions within the range are considered compatible and _NPM_ could update the package by itself when you run `npm install`. <br> + However, it could lead to inconsistencies if one does `npm install` after some time and a dependency got updated in the meantime within the range.<br> + That's why, _NPM_ also generated a [`package-lock.json`](https://docs.npmjs.com/cli/v8/configuring-npm/package-lock-json). In a nutshell, `package-lock.json` is like a verbose version of `package.json`. It lists transitive dependencies (ie: dependencies of our dependencies) and fixes each and every package version. !!! danger "Danger" - > Avoid editing `package.json` by yourself. Prefer using the _NPM CLI_ (eg: `npm install`, `npm remove`, ...) instead. + Avoid editing `package.json` by yourself. Prefer using the _NPM CLI_ (eg: `npm install`, `npm remove`, ...) instead. If you check the `package-lock.json`file and search for `http-server`, you can see the following: -```json +```json linenums="1" { // ... "node_modules/http-server": { @@ -264,9 +269,10 @@ In addition to `package-lock.json`, _NPM_ also created a folder called `node_mod ``` !!! danger "Danger" - > The `node_modules/` folder contains all dependencies and is usually rather uge. Do not forget to ignore this directory in the `.gitignore` file to not commit it. - > !!! info "Show the node_modules folder size" - >  + The `node_modules/` folder contains all dependencies and is usually rather uge. Do not forget to ignore this directory in the `.gitignore` file to not commit it. + !!! info "Show the node_modules folder size" +  + #### <i class="fas fa-folder-tree"></i> Modified files @@ -286,14 +292,14 @@ front-end/ ## <i class="fas fa-terminal"></i> Write _NPM_ scripts - +<hr> Did you notice that the generated `package.json` has a `"scripts"` section? -??? info "Show the package.json file" +??? show "Show the package.json file" === "package.json" - ```json + ```json linenums="1" { "name": "username-meme-ory", "version": "1.0.0", @@ -312,14 +318,15 @@ Did you notice that the generated `package.json` has a `"scripts"` section? ``` -> **info** A _NPM_ package can have a complex lifecycle: from development to shipping, not to forget about the tests, the build and other stages that may require specific tools and commands... -> -> The `"scripts"` section allows developers to create aliases for all needed commands. -> Then, they can be executed running the command `npm run <script name>` +!!! info "Infos" + A _NPM_ package can have a complex lifecycle: from development to shipping, not to forget about the tests, the build and other stages that may require specific tools and commands... + + The `"scripts"` section allows developers to create aliases for all needed commands. + Then, they can be executed running the command `npm run <script name>` At the moment, only the `"test"` script is available. You can run it using the following command: -```bash +```bash linenums="1" npm run test ``` @@ -330,18 +337,19 @@ Because we have not written any tests yet, it defaults printing an error and exi In the previous section, we have installed the `http-server` package as a devDependency to our project. So now, to run the server, you can use the command `http-server -c-1` without `npx`. However, because it is rather hard to memorize, let's create a script as a shortcut instead of running it manually. -> **info** _NPM_ scripts act both as an help and a **documentation for developers**. As a new developer on a project, you do not need to know which tools are required to start your project, if you know `npm start` does the job. -> -> **Most of the projects have an `npm run (start|test)` command.** +!!! info "Infos" + _NPM_ scripts act both as an help and a **documentation for developers**. As a new developer on a project, you do not need to know which tools are required to start your project, if you know `npm start` does the job. + + **Most of the projects have an `npm run (start|test)` command.** - Add a new script called `start` in the scripts section. This script will run our `http-server` command. - ??? info "Show the package.json file" +??? show "Show the package.json file" - === "package.json" - ```json + === "package.json" + ```json linenums="1" { "scripts": { "start": "http-server -c-1", @@ -353,13 +361,13 @@ So now, to run the server, you can use the command `http-server -c-1` without `n - Kill the old `http-server` if it is still running. Now, you can start your application using the following command: === "alias" - ```bash + ```bash linenums="1" npm start ``` === "verbose" - ```bash + ```bash linenums="1" npm run start ``` diff --git a/resources/docs/docs/chapters/tp/setup.md b/resources/docs/docs/chapters/tp/setup.md index a45acb5..c2a5309 100644 --- a/resources/docs/docs/chapters/tp/setup.md +++ b/resources/docs/docs/chapters/tp/setup.md @@ -9,7 +9,7 @@ tag: > - This tutorial is best suited for linux <i class="fab fa-linux"></i>, but it also works with Windows <i class="fab fa-windows"></i> or MacOS <i class="fab fa-apple"></i>. -## :fontawesome-solid-flag-checkered: Prerequisites +## Prerequisites <hr> - Have a recent LTS version of [**nodejs**](https://nodejs.org/en/) @@ -18,7 +18,7 @@ tag: v16.13.0 ### at least ``` -!!! tips "**Pro tip**:" +!!! tips "**Pro tip**" Linux users can install and use [NVM](https://github.com/creationix/nvm). With this tool, it is easy to install multiple node versions and switch between all of them. @@ -41,19 +41,19 @@ tag: - [Prettier for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) - [Prettier for IntelliJ / Webstorm](https://plugins.jetbrains.com/plugin/10456-prettier) -## :fontawesome-solid-person-digging: Preparation +## Preparation <hr> In this tutorial, we provide you an existing codebase written in **good-old _ES5_** for an application called _MEME-Ory_. Your mission, should you choose to accept it, is to **rewrite this application using modern _ES6+_**. !!! info "Long story short, JavaScript is an implementation of the **Ecma Script (ES) specification**. Any browser can have its own implementation but must comply to the ES specification, which is the standard. **_ES6_**, released in 2015, was a **big jump forward** and marks the beginning of the **Modern _JavaScript_ era**. Since then, there is a new released each year." -### :fontawesome-brands-git-alt: Initialize the Git repository +### Initialize the Git repository -<span id="diy"> :fontawesome-solid-wrench: Do it yourself </span> +<span id="diy"> Do it yourself </span> <br> <br> -[:fontawesome-solid-file-arrow-down: Meme-ORY](../../downloads/init.zip){:download} +[Meme-ORY](../../downloads/init.zip){:download} - Create a new project under your namespace on your Gitlab. Call it **web-01**. - Clone that project in your workspace and checkout to a new branch called **develop** @@ -139,3 +139,4 @@ front-end/ - <input type="checkbox" /> I can play _MEME-Ory_ game on [http://localhost:8080/src](http://localhost:8080/src) [game-mockup]: ../../assets/mockup.png +[flag]: ../../icons/solid/flag-checkered.svg diff --git a/resources/docs/docs/chapters/tp/spa.md b/resources/docs/docs/chapters/tp/spa.md index badd02a..1f0a366 100644 --- a/resources/docs/docs/chapters/tp/spa.md +++ b/resources/docs/docs/chapters/tp/spa.md @@ -17,28 +17,30 @@ As you know, the _MEME-Ory_ application is made of three views: Each view comes with a _complete *HTML* document_. Going from one view to another one means **loading an entirely new document**, even if the new page have a lot in common with the previous one (eg: the _navbar_, the _footer_...). -> **danger** If the network is slow, it can cause **performance issues** and flickering until the page is fully loaded, which is not great in terms of **user experience**. ->  +!!! danger "Danger" + If the network is slow, it can cause **performance issues** and flickering until the page is fully loaded, which is not great in terms of **user experience**. +  ## <i class="fa fa-wrench"></i> The browser dev tools - +<hr> !!! tip "Did you know ?" - > Your web browser can give you a lot of information about what happens behind the scene (JavaScript execution, stack-traces, network, errors, ...). Press `ctrl+shift+I` (Firefox, Google Chrome, Chromium) to open the developer console. - > There, you can: - > - see the **application logs** in the "Console" tab - > - browse **source files** pressing `ctrl+P` or in the "Sources" tab - > - set **breakpoints** and **debug your code** - > - **inspect the document**: see HTML elements, edit CSS properties in the "Elements" tab - > - **monitor the Network** traffic in "Network" tab - > - and much more! - >  - -> !!! question "How many megabytes are transferred in total after going through the three views, with `size=2`?" + Your web browser can give you a lot of information about what happens behind the scene (JavaScript execution, stack-traces, network, errors, ...). Press `ctrl+shift+I` (Firefox, Google Chrome, Chromium) to open the developer console. + There, you can: + + - see the **application logs** in the "Console" tab + - browse **source files** pressing `ctrl+P` or in the "Sources" tab + - set **breakpoints** and **debug your code** + - **inspect the document**: see HTML elements, edit CSS properties in the "Elements" tab + - **monitor the Network** traffic in "Network" tab + - and much more! +  + +!!! question "How many megabytes are transferred in total after going through the three views, with `size=2`?" In this chapter, we will turn the _MEME-Ory_ application into a **_Single Page Application_** to fix this! ## The Single Page Application - +<hr> _**S**ingle **P**age **A**pplication_ (_SPA_) means the application lives in a single _HTML_ document (typically, `index.html`). Going from a view to another one is done by replacing part of the _HTML_ document by other _HTML_ templates rather than navigating to a new page. In a _SPA_, the application has only one page. Even if the content changes, we stay on the same `index.html`. As a result, we should neither use `window.location.href='...'` nor `<a href=‘…’>`, as it would load another document in place of `index.html`. Instead, we define a __Router__ to switch between views. @@ -50,78 +52,72 @@ It uses the [`DOM` API](https://developer.mozilla.org/en-US/docs/Web/API/Documen  -### Create the _Router_ <Diy/> - -- Download the _Router_ sources: <ResourcesButton path="router.zip" title="Router" /> +### Create the _Router_ <span id="diy"> Do it yourself </span> +<hr> +- Download the _Router_ sources as router.js: [Router](../../stylesheets/router){:download="router.js} This archive contains two source files you have to put in your `front-end/src/app/scripts/` folder: - **`router.js`**: a rudimentary _Router_ implementation. - **`main.js`**: the place where the _HTML templates_ and their corresponding JavaScript files are registered at the Router. The _Router_ will put the different views into the existing `document`, in the `<div id="content-outlet">`. -???+ info "Show the main.js file" +???+ note "Show the main.js file" === "main.js" - ```js + ```js linenums="1" const outlet = document.querySelector("#content-outlet"); const router = new Router(outlet); router - .register("", { - component: WelcomeComponent, - templateUrl: "/src/app/views/welcome.html", - }) - .register("welcome", { - component: WelcomeComponent, - templateUrl: "/src/app/views/welcome.html", - }) - .register("game", { - component: GameComponent, - templateUrl: "/src/app/views/game.html", - }) - .register("score", { - component: ScoreComponent, - templateUrl: "/src/app/views/score.html", - }); + .register("", { + component: WelcomeComponent, + templateUrl: "/src/app/views/welcome.html", + }) + .register("welcome", { + component: WelcomeComponent, + templateUrl: "/src/app/views/welcome.html", + }) + .register("game", { + component: GameComponent, + templateUrl: "/src/app/views/game.html", + }) + .register("score", { + component: ScoreComponent, + templateUrl: "/src/app/views/score.html", + }); ``` - Edit `router.js` and complete the implementation of `function renderTemplate() {}`. Follow the `TODO #spa` comments for instructions. - <details><summary> Show the resulting renderTemplate() function </summary> - - router.js - - ```js{8-12} - (function () { - /** - * Append an HTML template to the document, at the given outlet. - * @param HTMLElement outlet the location on the document to add the template - * @param HTMLElement template the template to append - */ - function renderTemplate(outlet, template) { - while (outlet.lastChild) { - outlet.removeChild(outlet.lastChild); - } - - outlet.appendChild(template); - } +??? note "Show the resulting renderTemplate() function" + === "router.js" + + ```js linenums="1" + (function () { + /** + * Append an HTML template to the document, at the given outlet. + * @param HTMLElement outlet the location on the document to add the template + * @param HTMLElement template the template to append + */ + function renderTemplate(outlet, template) { + while (outlet.lastChild) { + outlet.removeChild(outlet.lastChild); + } + outlet.appendChild(template); // ... - })(); - ``` - - </details> + })(); + ``` - Edit `welcome.js` and `game.js`. Look at the comments `TODO #spa` for instructions. - <details><summary> Tired of looking for TODOs manually? </summary> - - > **tip** The faster way to find all specific string occurrences in a project is the `ctrl+shift+F` shortcut. - > - > In our case: `ctrl+shift+F` -> `TODO #spa` will do the job (replace `ctrl` by `cmd` on mac) -</details> +??? note "Tired of looking for TODOs manually?" + !!! tip "Tips" + The faster way to find all specific string occurrences in a project is the `ctrl+shift+F` shortcut. + In our case: `ctrl+shift+F` -> `TODO #spa` will do the job (replace `ctrl` by `cmd` on mac) ## <i class="fa-solid fa-table-columns"></i> The application shell Each application view uses the same layout: + - a __navbar__ on top of the page - a _scrollable section_ with the __main content__ - a __footer__ at the bottom of the page @@ -131,20 +127,21 @@ It is called the **_Application Shell_** and is common to all application views.  ### Create the shell <Diy/> <BadgeMedium /> - +<hr> `welcome.html`, `game.html` and `score.html` are now _HTML_ templates/blocks instead of full-fledged _HTML_ documents. - Edit `index.html`. Follow the `TODO #shell` comments for instructions. - Add a new `<div>` as a child element of `<body>` to hold the content: - ```html + ```html linenums="1" <div id="content-outlet" class="h-100 w-100 d-flex flex-column"></div> ``` - Import all JS scripts located in `src/app/scripts` at the bottom of the `<body>` tag. Be careful to import `main.js` lastly. - > **warning** `main.js` has to be imported after the other scripts because it uses functions defined in the other scripts. This can quickly become a nightmare if more scripts have dependencies on each other. +!!! warning "Warning" + `main.js` has to be imported after the other scripts because it uses functions defined in the other scripts. This can quickly become a nightmare if more scripts have dependencies on each other. - Remove the `window.location` statement. @@ -152,47 +149,46 @@ It is called the **_Application Shell_** and is common to all application views.  -<details><summary> Show the index.html file </summary> - -index.html - -```html{19-24,12} -<!DOCTYPE html> -<html lang="en"> - <head> - <!-- ... --> - </head> - <body> - <nav class="navbar bg-primary mb-3 shadow"> - <!-- ... --> - </nav> - <section class="overflow-auto flex-grow-1 d-flex flex-column"> - <div class="container-fluid flex-grow-1"> - <div id="content-outlet" class="h-100 w-100 d-flex flex-column"></div> - </div> - - <footer class="p-3 bg-dark"> - <!-- ... --> - </footer> - - <script src="/src/app/scripts/welcome.js"></script> - <script src="/src/app/scripts/game.js"></script> - <script src="/src/app/scripts/score.js"></script> - <script src="/src/app/scripts/utils.js"></script> - <script src="/src/app/scripts/router.js"></script> - <script src="/src/app/scripts/main.js"></script> - </section> - </body> -</html> -``` +??? note "Show the index.html file" + + === "index.html" + + ```html linenums="1" + <!DOCTYPE html> + <html lang="en"> + <head> + <!-- ... --> + </head> + <body> + <nav class="navbar bg-primary mb-3 shadow"> + <!-- ... --> + </nav> + <section class="overflow-auto flex-grow-1 d-flex flex-column"> + <div class="container-fluid flex-grow-1"> + <div id="content-outlet" class="h-100 w-100 d-flex flex-column"></div> + </div> + + <footer class="p-3 bg-dark"> + <!-- ... --> + </footer> + + <script src="/src/app/scripts/welcome.js"></script> + <script src="/src/app/scripts/game.js"></script> + <script src="/src/app/scripts/score.js"></script> + <script src="/src/app/scripts/utils.js"></script> + <script src="/src/app/scripts/router.js"></script> + <script src="/src/app/scripts/main.js"></script> + </section> + </body> + </html> + ``` -</details> - Navigate to [http://localhost:8080/src/](http://localhost:8080/src/). You should be able to play the game as usual. Notice how the _hash_ (`#`) is used in the url. -> **question** -> - How many megabytes are transferred in total after going through the 3 views, with `size=2`? -> - How many files have been transferred? +!!! question "Question" + - How many megabytes are transferred in total after going through the 3 views, with `size=2`? + - How many files have been transferred? #### <i class="fas fa-folder-tree"></i> Modified files diff --git a/resources/docs/mkdocs.yml b/resources/docs/mkdocs.yml index 60347e8..436c5a4 100644 --- a/resources/docs/mkdocs.yml +++ b/resources/docs/mkdocs.yml @@ -31,9 +31,7 @@ theme: features: - navigation.tabs - navigation.instant - theme: - icon: - file: fontawesome/solid/file + custom_dir: overrides markdown_extensions: - admonition @@ -47,13 +45,10 @@ markdown_extensions: - pymdownx.tabbed: alternate_style: true - attr_list - - pymdownx.emoji: - emoji_index: !!python/name:materialx.emoji.twemoji - emoji_generator: !!python/name:materialx.emoji.to_svg +# - pymdownx.emoji: +# emoji_index: !!python/name:materialx.emoji.twemoji +# emoji_generator: !!python/name:materialx.emoji.to_svg - tables extra_css: - stylesheets/global.css - -extra_dirs: - - downloads \ No newline at end of file -- GitLab