Guide d'initiation à Webpack 4 et au regroupement de modules –
Le document Webpack 4 docs indique que:
Webpack est un regroupeur de modules. Son but principal est de regrouper les fichiers JavaScript pour les utiliser dans un navigateur, mais il est également capable de transformer, grouper ou empaqueter n'importe quelle ressource ou ressource.
Webpack est devenu l'un des outils les plus importants pour les utilisateurs modernes. développement web. Il s'agit principalement d'un bundler de module pour votre JavaScript, mais il peut être enseigné pour transformer tous vos éléments frontaux tels que HTML, CSS, voire des images. Il peut vous donner plus de contrôle sur le nombre de requêtes HTTP que votre application effectue et vous permet d'utiliser d'autres caractéristiques de ces ressources (Pug, Sass et ES8, par exemple). Webpack vous permet également de consommer facilement des paquets de npm.
Cet article s'adresse aux nouveaux utilisateurs de Webpack et couvre l'installation initiale, la configuration, les modules, les chargeurs, les plugins, le découpage de code et le remplacement de modules chauds. Si vous trouvez les didacticiels vidéo utiles, je peux vous recommander fortement le Webpack de Glen Maddern de First Principles comme point de départ pour comprendre ce qui rend Webpack spécial. C'est un peu vieux maintenant, mais les principes sont toujours les mêmes, et c'est une excellente introduction.
Pour suivre à la maison, vous devrez avoir installé Node.js . Vous pouvez également télécharger l'application de démo de notre repo GitHub .
Setup
Nous allons initialiser un nouveau projet avec npm et installer webpack
et webpack-cli
:
mkdir webpack-démo && cd webpack-demo
npm init -y
npm installer --save-dev webpack webpack-cli
Ensuite, nous allons créer la structure et le contenu du répertoire suivant:
webpack-demo
| - package.json
+ | - webpack.config.js
+ | - / src
+ | - index.js
+ | - / dist
+ | - index.html
dist / index.html
Bonjour Webpack
src / index.js
const racine = document.createElement ("div")
root.innerHTML = ` Bonjour Webpack.
`
document.body.appendChild (racine)
webpack.config.js
const path = require ('chemin')
module.exports = {
entrée: './src/index.js',
sortie: {
nom de fichier: "http://www.sitepoint.com/bundle.js",
chemin: path.resolve (__ dirname, 'dist')
}
}
Ceci demande à Webpack de compiler le code dans notre point d'entrée src / index.js
et de sortir un paquet dans /dist/bundle.js
. Ajoutons un script npm pour exécuter Webpack.
package.json
{
...
"scripts": {
- "test": "echo " Erreur: aucun test spécifié "&& exit 1"
+ "develop": "webpack --mode développement --watch",
+ "build": "webpack - production de mode"
},
...
}
En utilisant la commande npm run
nous pouvons créer notre premier paquet!
bundle.js 2.92 KiB principal [emitted] main
Vous devriez maintenant pouvoir charger dist / index.html
dans votre navigateur et être accueilli par "Hello Webpack".
Ouvrir dist / bundle.js
à voir ce que Webpack a fait. En haut se trouve le code d'amorçage du module de Webpack, et tout en bas se trouve notre module. Vous n'êtes peut-être pas encore impressionné par la couleur, mais si vous êtes arrivé si loin, vous pouvez commencer à utiliser ES Modules, et Webpack sera capable de produire un bundle pour la production qui fonctionnera dans tous les navigateurs.
Ctrl + C et exécutez npm run build
pour compiler notre bundle en mode de production .
Taille de bloc Morceaux
bundle.js 647 octets principal [emitted] main
Notez que la taille de l'ensemble est descendue de 2,92 KiB à 647 octets .
Jetez un autre regard sur dist / bundle.js
et vous verra un désordre de code laid. Notre bundle a été minifié avec UglifyJS: le code fonctionnera exactement de la même manière, mais avec la plus petite taille de fichier possible
- le développement en mode
optimise la vitesse de construction et le débogage - production en mode
optimise la vitesse d'exécution au moment de l'exécution et la taille du fichier de sortie.
Modules
En utilisant les modules ES, vous pouvez diviser vos grands programmes en plusieurs petits programmes autonomes
. comment consommer des modules ES en utilisant les instructions import
et export
. Par exemple, essayons cela maintenant en installant lodash-es et en ajoutant un second module:
npm install --save-dev lodash-es
src / index.js
import {groupBy} à partir de "lodash-es"
importer des personnes de "./people"
const managerGroups = groupBy (personnes, "manager")
const root = document.createElement ("div")
root.innerHTML = ` $ {JSON.stringify (managerGroups, null, 2)}
`
document.body.appendChild (racine)
src / people.js
const personnes = [
{
manager: "Jen",
name: "Bob"
},
{
manager: "Jen",
name: "Sue"
},
{
manager: "Bob",
name: "Shirley"
}
]
exporter les personnes par défaut
Exécutez npm run développez
pour démarrer Webpack et actualiser index.html
. Vous devriez voir un tableau de personnes groupées par directeur imprimé à l'écran.
Note: Les importations sans chemin relatif comme 'es-lodash'
sont des modules de npm installés à / node_modules
. Vos propres modules auront toujours besoin d'un chemin relatif comme './ people'
car c'est ainsi que vous pouvez les différencier.
Notez dans la console que la taille de notre bundle a augmenté à 1,41 Mio ! Cela vaut la peine d'être surveillé, même si dans ce cas il n'y a pas lieu de s'inquiéter. En utilisant npm run build
pour compiler en mode production tous les modules de lodash inutilisés de lodash-es sont retirés du bundle. Ce processus de suppression des importations inutilisées s'appelle tree-shaking et c'est quelque chose que vous obtenez gratuitement avec Webpack.
> npm run develop
Nombres de morceaux de morceaux de taille d'actif
bundle.js 1.41 MiB principal [emitted] [big] main
> npm run build
Nombres de morceaux de morceaux de taille d'actif
bundle.js 16,7 KiB 0 [emitted] main
Chargeurs
Les chargeurs vous permettent d'exécuter des préprocesseurs sur les fichiers lors de leur importation. Cela vous permet de regrouper des ressources statiques au delà de JavaScript mais regardons ce qui peut être fait en chargeant les modules .js
en premier
Gardons notre code moderne en exécutant tout ] .js
via le transtypeur JavaScript de prochaine génération Babel :
npm install --save-dev "babel-loader@x8.0.0-beta" @ babel / core @babel / preset-env
webpack.config.js
const path = require ('chemin')
module.exports = {
entrée: './src/index.js',
sortie: {
nom de fichier: "http://www.sitepoint.com/bundle.js",
chemin: path.resolve (__ dirname, 'dist')
},
+ module: {
+ règles: [
+ {
+ test: /.js$/,
+ exclude: /(node_modules|bower_components)/,
+ use: {
+ loader: 'babel-loader',
+ }
+ }
+ ]
+}
}
.babelrc
{
"préréglages": [
["@babel/env", {
"modules": false
}]
],
"plugins": ["syntax-dynamic-import"]
}
Cette configuration empêche Babel de transférer des déclarations import
et export
dans ES5, et autorise les importations dynamiques – que nous verrons plus loin dans la section sur la division des codes.
Nous sommes maintenant libres d'utiliser les fonctionnalités de langage moderne, et ils seront compilés à ES5 qui fonctionne dans tous les navigateurs.
Sass
Les chargeurs peuvent être enchaînés en une série de transformations. Un bon moyen de démontrer comment cela fonctionne est d'importer Sass depuis notre JavaScript:
npm install --save-dev style-loader css-loader sass-loader noeud-sass
webpack.config.js
module.exports = {
...
module: {
règles: [
...
+ {
+ test: /.scss$/,
+ use: [{
+ loader: 'style-loader'
+ }, {
+ loader: 'css-loader'
+ }, {
+ loader: 'sass-loader'
+ }]
+}
]
}
}
Ces chargeurs sont traités dans l'ordre inverse:
sass-loader
transforme Sass en CSS css-loader
parse le CSS en JavaScript et résout les dépendances. style-loader
génère notre CSS dans une balise
dans le document.
Vous pouvez les considérer comme des appels de fonction. La sortie d'un chargeur se charge comme entrée dans le suivant:
styleLoader (cssLoader (sassLoader ("source")))
Ajoutons un fichier source Sass et importons un module.
src / style.scss
$ bluegrey: # 2b3a42;
pré {
rembourrage: 8px 16px;
arrière-plan: $ bluegrey;
couleur: # e1e6e9;
font-family: Menlo, Courrier, monospace;
taille de police: 13px;
hauteur de ligne: 1,5;
text-shadow: 0 1px 0 rgba (23, 31, 35, 0,5);
border-radius: 3px;
}
src / index.js
import {groupBy} à partir de 'lodash-es'
importer des personnes de './people'
+ importer './style.scss'
...
Redémarrez la construction avec Ctrl + C et npm run développez
. Actualiser index.html
dans le navigateur et vous devriez voir un peu de style
CSS dans JS
Nous venons d'importer un fichier Sass de notre JavaScript, comme un module.
Ouvrir ] dist / bundle.js
et recherchez "pre {". En effet, notre Sass a été compilé en une chaîne de CSS et enregistré en tant que module dans notre bundle. Lorsque nous importons ce module dans notre JavaScript, style loader
génère cette chaîne dans une balise
Commençons un serveur à partir du répertoire dist pour le voir en action:
cd dist
service npx
Ouvrez http: // localhost: 5000 dans le navigateur et voyez ce qui se passe. Seul bundle.js
est récupéré initialement. Lorsque le bouton est cliqué, le module de chat est importé et initialisé.
Avec très peu d'effort, nous avons ajouté le découpage dynamique à notre application.
Plugins
Bien que les loaders utilisent des transformations sur des fichiers uniques, les plugins fonctionnent sur de plus gros morceaux de code. 19659004] Maintenant que nous regroupons notre code, les modules externes et actifs statiques, notre paquet va croître - rapidement . Les plugins sont là pour nous aider à diviser notre code de manière intelligente et à optimiser les choses pour la production.
Sans le savoir, nous avons déjà utilisé beaucoup de plugins Webpack par défaut avec "mode"
développement
- Fournit
process.env.NODE_ENV
avec la valeur "développement" - NamedModulesPlugin
production
- Fournit
processus.env. NODE_ENV
avec la valeur "production" - UglifyJsPlugin
- ModuleConcatenationPlugin
- NoEmitOnErrorsPlugin
Production
Avant d'ajouter des plugins supplémentaires, nous allons d'abord scinder notre config afin que nous puissions appliquer des plugins spécifiques à chaque environnement.
Renommez webpack.config.js
en webpack.common.js
et ajoutez un fichier de configuration pour le développement et la production.
- | - webpack.config.js
+ | - webpack.common.js
+ | - webpack.dev.js
+ | - webpack.prod.js
Nous allons utiliser webpack-merge
pour combiner notre config commune avec la config spécifique à l'environnement:
npm install --save-dev webpack-merge
webpack.dev.js
const merge = require ('webpack-merge')
const common = require ('./ webpack.common.js')
module.exports = fusion (commun, {
mode: 'développement'
})
webpack.prod.js
const merge = require ('webpack-merge')
const common = require ('./ webpack.common.js')
module.exports = fusion (commun, {
mode: 'production'
})
package.json
"scripts": {
- "develop": "webpack --watch --mode développement",
- "build": "webpack - production de mode"
+ "develop": "webpack --watch --config webpack.dev.js",
+ "build": "webpack --config webpack.prod.js"
},
Maintenant, nous pouvons ajouter des plugins spécifiques au développement dans webpack.dev.js
et des plugins spécifiques à la production dans webpack.prod.js
.
Split CSS
C'est Considéré comme la meilleure pratique pour séparer votre CSS de votre JavaScript lors du regroupement pour la production en utilisant ExtractTextWebpackPlugin .
Les chargeurs .scss
actuels sont parfaits pour le développement, donc nous les déplacerons de webpack.common.js
dans webpack.dev.js
et ajoutez ExtractTextWebpackPlugin
à webpack.prod.js
uniquement.
npm install --save-dev extract-text-webpack-plugin@4.0.0-beta.0
webpack.common.js
...
module.exports = {
...
module: {
règles: [
...
- {
- test: /.scss$/,
- use: [
- {
- loader: 'style-loader'
- }, {
- loader: 'css-loader'
- }, {
- loader: 'sass-loader'
- }
- ]
-},
...
]
}
}
webpack.dev.js
const merge = require ('webpack-merge')
const common = require ('./ webpack.common.js')
module.exports = fusion (commun, {
mode: 'développement',
+ module: {
+ règles: [
+ {
+ test: /.scss$/,
+ use: [
+ {
+ loader: 'style-loader'
+ }, {
+ loader: 'css-loader'
+ }, {
+ loader: 'sass-loader'
+ }
+ ]
+}
+]
+}
})
webpack.prod.js
const merge = require ('webpack-merge')
+ const ExtractTextPlugin = require ('extrait-text-webpack-plugin')
const common = require ('./ webpack.common.js')
module.exports = fusion (commun, {
mode: 'production',
+ module: {
+ règles: [
+ {
+ test: /.scss$/,
+ use: ExtractTextPlugin.extract({
+ fallback: 'style-loader',
+ use: ['css-loader', 'sass-loader']
+})
+}
+]
+},
+ plugins: [
+ new ExtractTextPlugin('style.css')
+ ]
})
Comparons la sortie de nos deux scripts de construction:
> npm run develop
Nombres de morceaux de morceaux de taille d'actif
Application app.bundle.js 28.5 KiB [emitted]
chat.bundle.js 1.4 KiB chat [emitted] chat
> npm run build
Nombres de morceaux de morceaux de taille d'actif
chat.bundle.js 375 octets 0 [emitted] chat
app.bundle.js 1,82 KiB 1 [emitted] application
style.css 424 octets 1 [emitted] application
Maintenant que notre CSS est extrait de notre bundle JavaScript pour la production, nous devons le à partir de notre HTML.
dist / index.html
Séparation de code
+
Cela permet un téléchargement parallèle du CSS et du JavaScript dans le navigateur, ce qui accélérera le chargement d'un seul paquet. Il permet également aux styles d'être affichés avant que le JavaScript ne finisse de télécharger.
Générer du HTML
Chaque fois que nos sorties ont changé, nous avons dû mettre à jour index.html
pour référencer les nouveaux chemins de fichiers . C'est précisément ce que html-webpack-plugin
a été créé pour nous automatiquement
Nous pouvons aussi ajouter clean-webpack-plugin
en même temps pour effacer notre / dist
répertoire avant chaque build.
npm installer --save-dev html-webpack-plugin nettoyer-webpack-plugin
webpack.common.js
const path = require ('chemin')
+ const CleanWebpackPlugin = require ('clean-webpack-plugin');
+ const HtmlWebpackPlugin = require ('html-webpack-plugin');
module.exports = {
...
+ plugins: [
+ new CleanWebpackPlugin(['dist']),
+ nouveau HtmlWebpackPlugin ({
+ titre: 'Mon application de tueur'
+})
+]
}
Maintenant chaque fois que nous construisons, dist sera effacé. Nous allons maintenant voir la sortie index.html
avec les bons chemins vers nos bundles d'entrée
Running npm run develop
produit ceci:
My killer app ]
Et npm run build
produit ceci:
My killer app
Développement
Le webpack-dev-server vous fournit un simple serveur web et vous donne rechargement en direct vous n'avez donc pas besoin d'actualiser manuellement la page pour voir les modifications.
npm install --save-dev webpack-dev-server
package.json
{
...
"scripts": {
- "develop": "webpack --watch --config webpack.dev.js",
+ "develop": "webpack-dev-server --config webpack.dev.js",
}
...
}
> npm run développer
「「 wds 」: Le projet s'exécute à http: // localhost: 8080 /
「「 wds 」: la sortie webpack est desservie à partir de /
Ouvrez http: // localhost: 8080 / dans le navigateur et modifiez l'un des fichiers JavaScript ou CSS. Vous devriez le voir construire et actualiser automatiquement.
HotModuleReplacement
Le plugin HotModuleReplacement
va plus loin que Live Reloading et échange des modules à l'exécution sans l'actualiser . Une configuration correcte permet d'économiser beaucoup de temps lors du développement d'applications à une seule page. Lorsque vous avez beaucoup d'état dans la page, vous pouvez apporter des modifications incrémentielles aux composants, et seuls les modules modifiés sont remplacés et mis à jour.
webpack.dev.js
+ const webpack = require ('webpack')
const merge = require ('webpack-merge')
const common = require ('./ webpack.common.js')
module.exports = fusion (commun, {
mode: 'développement',
+ devServer: {
+ chaud: vrai
+},
+ plugins: [
+ new webpack.HotModuleReplacementPlugin()
+ ],
...
}
Maintenant, nous devons accepter changer les modules de notre code pour réinitialiser les choses.
src / app.js
+ if (module.hot) {
+ module.hot.accept ()
+}
...
Note: Lorsque le remplacement de module chaud est activé, module.hot
est réglé sur true
pour le développement et false
pour la production, donc ceux-ci sont
Redémarrez le build et voyez ce qui se passe quand nous faisons ce qui suit:
- Cliquez Ouvrir le chat
- Ajouter une nouvelle personne au
.js
module
- Cliquez Ouvrez à nouveau le chat .
Voici ce qui se passe:
- Quand Ouvrir chat est cliqué, le
Le module chat.js
est récupéré et initialisé
- HMR détecte quand
people.js
est modifié
module.hot.accept ()
dans index.js
provoque le remplacement de tous les modules chargés par ce bloc d'entrée
- Lorsque Clavardage ouvert est de nouveau cliqué,
chat.init ()
est exécuté avec le code de la mise à jour mo dule.
CSS Replacement
Changeons la couleur du bouton en rouge et voyons ce qui se passe:
src / app.scss
button {
...
- arrière-plan: # 24b47e;
+ arrière-plan: rouge;
...
}
Nous pouvons maintenant voir des mises à jour instantanées de nos styles sans perdre aucun état. C'est une expérience de développeur beaucoup améliorée!
HTTP / 2
L'un des principaux avantages de l'utilisation d'un bundler de modules tel que Webpack est qu'il peut vous aider à améliorer les performances en vous donnant le contrôle sur la façon dont les assets sont construits puis récupéré sur le client. Il a été considéré meilleure pratique pour les années à concaténer les fichiers afin de réduire le nombre de demandes qui doivent être faites sur le client. Ceci est toujours valide, mais HTTP / 2 permet maintenant de livrer plusieurs fichiers dans une seule requête donc la concaténation n'est plus une solution miracle. Votre application peut réellement bénéficier de la mise en cache individuelle de nombreux petits fichiers. Le client pourrait alors aller chercher un seul module modifié plutôt que d'avoir à récupérer un paquet entier avec principalement le même contenu.
Le créateur de Webpack, Tobias Koppers a écrit un poste informatif expliquant pourquoi le regroupement est toujours important, même dans l'ère HTTP / 2
En savoir plus à ce sujet à Webpack & HTTP / 2 .
Plus à vous
J'espère que vous J'ai trouvé cette introduction à Webpack utile et je peux commencer à l'utiliser avec beaucoup d'efficacité. Cela peut prendre un peu de temps pour se familiariser avec la configuration, les chargeurs et les plugins de Webpack, mais apprendre comment fonctionne cet outil sera payant.
La documentation de Webpack 4 est en cours de préparation, mais elle est très bien préparée. Je vous recommande fortement de lire les Guides Concepts et pour plus d'informations. Voici quelques autres sujets qui pourraient vous intéresser:
Webpack 4 est-il le bundler de votre choix? Faites-moi savoir dans les commentaires ci-dessous.
Source link