Bonne journée, mes amis!
Je vous présente une traduction de l'article "Webpack: Une introduction douce" de Tyler McGinnis.
Avant d'explorer une nouvelle technologie, posez-vous deux questions:
- Pourquoi cet outil est-il nécessaire?
- Quelles tâches effectue-t-il?
Si vous ne pouvez pas répondre à ces questions, vous n'aurez peut-être pas besoin de la technologie que vous étudiez. Essayons de répondre à ces questions par rapport à Webpack.
Pourquoi avez-vous besoin d'un pack Web?
Webpack est un constructeur de modules. Il analyse les modules de l'application, crée un graphe de dépendances, puis assemble les modules dans le bon ordre en un ou plusieurs bundles, qui peuvent être référencés par le fichier "index.html".
App.js -> |
Dashboard.js -> | Bundler | -> bundle.js
About.js -> |
Quels problèmes le Webpack résout-il?
Habituellement, lors de la création d'une application JavaScript, le code est divisé en plusieurs parties (modules). Ensuite, dans le fichier "index.html", vous devez spécifier un lien vers chaque script.
<body>
...
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="libs/react.min.js"></script>
<script src='src/admin.js'></script>
<script src='src/dashboard.js'></script>
<script src='src/api.js'></script>
<script src='src/auth.js'></script>
<script src='src/rickastley.js'></script>
</body>
Ce n'est pas seulement fastidieux, mais également sujet aux erreurs. Il est important non seulement de ne pas oublier les scripts, mais également de les organiser dans le bon ordre. Si vous chargez un script qui dépend de React avant de charger React lui-même, votre application s'arrêtera. Webpack résout ces problèmes. Pas besoin de s'inquiéter d'inclure tous les scripts dans l'ordre.
<body>
...
<script src='dist/bundle.js'></script>
</body>
Comme nous l'apprendrons bientôt, la collecte de modules n'est qu'un aspect du fonctionnement d'un pack Web. Si nécessaire, vous pouvez forcer le webpack à effectuer certaines transformations de module avant de les ajouter au bundle. Par exemple, la conversion de SASS / LESS en CSS standard ou de JavaScript moderne en ES5 pour les navigateurs plus anciens.
Installer un pack Web
Après avoir initialisé le projet avec npm, pour que le webpack fonctionne, vous devez installer deux packages -
webpack
et webpack-cli
.
npm i webpack webpack-cli -D
webpack.config.js
Après avoir installé ces packages, le webpack doit être configuré. Pour ce faire, un fichier est créé
webpack.config.js
qui exporte l'objet. Cet objet contient les paramètres du pack Web.
module.exports = {}
La tâche principale d'un webpack est d'analyser les modules, de les transformer éventuellement et de les combiner intelligemment en un ou plusieurs bundles, le webpack doit donc connaître trois choses:
- Point d'entrée de l'application
- Conversions à effectuer
- Où placer le bundle généré
Point d'entrée
Quel que soit le nombre de modules qu'une application contient, il y a toujours un point d'entrée unique. Ce module comprend le reste. En règle générale, ce fichier est index.js. Cela pourrait ressembler à ceci:
index.js
imports about.js
imports dashboard.js
imports graph.js
imports auth.js
imports api.js
Si nous indiquons au webpack le chemin d'accès à ce fichier, il l'utilise pour créer le graphe de dépendance de l'application. Pour ce faire, vous devez ajouter une propriété
entry
aux paramètres du pack Web avec la valeur du chemin d'accès au fichier principal:
module.exports = {
entry: './app/index.js'
}
Conversion avec des chargeurs
Après avoir ajouté le point d'entrée, vous devez informer le Webpack des transformations à effectuer avant de générer le bundle. Pour cela, des chargeurs sont utilisés.
Par défaut, lors de la génération de graphiques de dépendances basés sur l'opérateur, le
import / require()
webpack ne peut traiter que les fichiers JavaScript et JSON.
import auth from './api/auth' //
import config from './utils/config.json' //
import './styles.css' // ️
import logo from './assets/logo.svg' // ️
Il est peu probable que vous osiez vous limiter aux fichiers JS et JSON dans votre application, vous aurez probablement également besoin de styles, de SVG, d'images, etc. C'est là que les chargeurs entrent en jeu. La tâche principale des chargeurs, comme leur nom l'indique, est de permettre au Webpack de fonctionner avec plus que des fichiers JS et JSON.
La première étape consiste à installer le chargeur. Puisque nous voulons charger SVG, utilisez npm pour installer svg-loader.
npm i svg-inline-loader -D
Ensuite, ajoutez-le aux paramètres du pack Web. Tous les chargeurs sont inclus dans un tableau d'objets
module.rules
:
module.exports = {
entry: './app/index.js',
module: {
rules: []
}
}
Les informations sur le chargeur se composent de deux parties. Le premier est le type de fichiers en cours de traitement (
.svg
dans notre cas). Le second est le chargeur utilisé pour traiter ce type de fichier ( svg-inline-loader
dans notre cas).
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' }
]
}
}
Nous pouvons maintenant importer des fichiers SVG. Mais qu'en est-il de nos fichiers CSS? Pour les styles utilisés
css-loader
.
npm i css-loader -D
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: 'css-loader' }
]
}
}
Nous pouvons maintenant importer des fichiers SVG et CSS. Cependant, pour que nos styles fonctionnent correctement, nous devons ajouter un autre chargeur. Grâce à
css-loader
nous, nous pouvons importer des fichiers CSS. Mais cela ne veut pas dire qu'ils seront inclus dans le DOM. Nous souhaitons non seulement importer de tels fichiers, mais également les placer dans une balise <style>
afin qu'ils s'appliquent aux éléments DOM. Pour cela, vous avez besoin style-loader
.
npm i style-loader -D
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }
]
}
}
Notez que puisque deux chargeurs sont utilisés pour traiter les fichiers CSS, la valeur de la propriété
use
est un tableau. Faites également attention à l'ordre des chargeurs, d'abord style-loader
, ensuite css-loader
. C'est important. Le webpack les appliquera dans l'ordre inverse. Il est d'abord utilisé css-loader
pour les importations './styles.css'
, puis style-loader
pour l'injection de styles dans le DOM.
Les chargeurs peuvent être utilisés non seulement pour importer des fichiers, mais aussi pour les convertir. Le plus populaire est la conversion de JavaScript de nouvelle génération en JavaScript moderne à l'aide de Babel. Il est utilisé pour cela
babel-loader
.
npm i babel-loader -D
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
}
}
Il existe des chargeurs pour presque tous les types de fichiers.
Point de sortie
Maintenant, le webpack connaît le point d'entrée et les chargeurs. L'étape suivante consiste à spécifier le répertoire du bundle. Pour ce faire, ajoutez une propriété
output
aux paramètres du pack Web.
const path = require('path')
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
}
}
L'ensemble du processus ressemble à ceci:
- Le webpack reçoit un point d'entrée situé à
./app/index.js
- Il analyse les instructions
import / require
et crée un graphe de dépendances - Le webpack commence à créer le bundle en convertissant le code à l'aide des chargeurs appropriés
- Il récupère un paquet et le place dans
dist/index_bundle.js
Plugins
Nous avons vu comment utiliser des chargeurs pour traiter des fichiers individuels avant ou pendant la génération d'un bundle. Contrairement aux chargeurs, les plugins vous permettent d'effectuer des tâches après la création d'un bundle. Ces tâches peuvent concerner à la fois le bundle lui-même et d'autres codes. Vous pouvez considérer les plugins comme des chargeurs plus puissants et moins limités.
Prenons un exemple.
HtmlWebpackPlugin
La tâche principale d'un webpack est de générer un bundle qui peut être référencé dans
index.html
.
HtmlWebpackPlugin
crée index.html
dans le répertoire avec le bundle et ajoute automatiquement un lien vers le bundle qu'il contient.
Nous avons nommé le bundle
index_bundle.js
et l' avons placé dist
. HtmlWebpackPlugin
créera un nouveau fichier index.html
dans le répertoire dist
et ajoutera un lien vers le bundle qu'il contient - <script src='index_bundle.js'></script>
. Génial, non? Puisqu'il est index.html
généré HtmlWebpackPlugin
, même si nous changeons le point de sortie ou le nom du bundle, il HtmlWebpackPlugin
recevra ces informations et changera le contenu index.html
.
Comment utilisons-nous ce plugin? Comme d'habitude, vous devez d'abord l'installer.
npm i html-webpack-plugin -D
Ensuite, ajoutez la propriété aux paramètres du pack Web
plugins
.
const path = require('path')
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
},
plugins: []
}
Nous créons une instance
HtmlWebpackPlugin
dans un tableau plugins
.
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin()
]
}
EnvironnementPlugin
Si vous utilisez React, vous souhaiterez lui attribuer
process.env.NODE_ENV
une valeur production
avant de déployer l'application. Cela permettra à React de construire en production en supprimant les outils de développement tels que les avertissements. Le webpack vous permet de le faire via un plugin EnvironmentPlugin
. Il fait partie du pack Web, vous n'avez donc pas besoin de l'installer.
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin(),
new webpack.EnvironmentPlugin({
'NODE_ENV': 'production'
})
]
}
Désormais, n'importe où dans notre application, nous pouvons définir le mode de production avec
process.env.NODE_ENV
.
HtmlWebpackPlugin
et EnvironmentPlugin
n'est qu'une petite partie du système de plugins webpack.
Mode (mode)
Lors de la préparation d'une demande de production, plusieurs étapes doivent être suivies. Nous venons d'en couvrir un - la mise
process.env.NODE_ENV
en valeur production
. Une autre action consiste à réduire le code et à supprimer les commentaires pour réduire la taille de l'ensemble.
Il existe des plugins spéciaux pour résoudre ces tâches, mais il existe un moyen plus simple. Dans les paramètres du pack Web, il peut être défini
mode
sur development
ou en production
fonction de l'environnement de développement.
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'production'
}
Veuillez noter que nous avons supprimé
EnvironmentPlugin
. Le fait est qu'après avoir défini mode
la valeur, le production
webpack attribue automatiquement la process.env.NODE_ENV
valeur production
. Il réduit également le code et supprime les avertissements.
Lancement d'un webpack
Pour le moment, nous savons comment fonctionne le webpack et comment le configurer, il reste à l'exécuter.
Nous avons un fichier
package.json
que nous pouvons créer script
pour l'exécuter webpack
.
"scripts": {
"build": "webpack"
}
Désormais, lorsque vous exécutez la commande
npm run build
dans le terminal, un pack Web sera lancé, qui créera un bundle optimisé index_bundle.js
et le placera dans dist
.
Modes de développement et de production
Dans l'ensemble, nous en avons terminé avec le webpack. Enfin, voyons comment basculer entre les modes.
Lors de la construction pour la production, nous voulons tout optimiser autant que possible. Dans le cas du mode développement, le contraire est vrai.
Pour basculer entre les modes, vous devez créer deux scripts dans
package.json
.
npm run build
construira le bundle de production.
npm run start
démarrera le serveur de développement et surveillera les changements de fichiers.
Si vous vous en souvenez, nous définissons cette
mode
valeur sur une valeur production
dans les paramètres du pack Web. Cependant, nous n'en avons pas besoin maintenant. Nous voulons que la variable d'environnement ait une valeur appropriée en fonction de la commande exécutée. Changeons le script build
dans package.json
.
"scripts": {
"build": "NODE_ENV='production' webpack",
}
Si vous utilisez Windows, la commande serait:
"SET NODE_ENV='production' && webpack"
.
Maintenant, dans les paramètres du pack Web, nous pouvons modifier la valeur en
mode
fonction de process.env.NODE_ENV
.
...
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development'
}
Pour créer un bundle prêt à l'emploi pour notre application, nous l'exécutons simplement
npm run build
dans le terminal. Les dist
fichiers de répertoire sont créés index.html
et index_bunlde.js
.
Serveur de développement
Lorsqu'il s'agit de développer une application, la vitesse est primordiale. Nous ne voulons pas redémarrer le webpack et attendre une nouvelle version à chaque changement. C'est là que le package est utile
webpack-dev-server
.
Comme son nom l'indique, il s'agit d'un serveur Webpack pour le développement. Au lieu de créer un répertoire
dist
, il stocke les données en mémoire et les traite sur un serveur local. De plus, il prend en charge le redémarrage en direct. Cela signifie que toute modification webpack-dev-server
reconstruira les fichiers et redémarrera le navigateur.
Installez le package.
npm i webpack-dev-server -D
Tout ce qui reste à faire est d' ajouter le script
start
à package.json
.
"scripts": {
"build": "NODE_ENV='production' webpack",
"start": "webpack-dev-server"
}
Nous avons maintenant deux commandes: l'une pour démarrer le serveur de développement et l'autre pour créer le bundle fini.
J'espère que l'article vous a été utile. Merci de votre attention.