Webpack par-ci, Webpack par-là… que vous soyez un développeur chevronné ou non, vous avez forcément entendu parler de cet outil. Qualifié de “bundler”, il vous permettra de faire bien des choses : utiliser un serveur local, utiliser le Live Reload, mais aussi et surtout compiler tous vos fichiers pour les regrouper en un seul. Pratique pour bien des raisons, notamment pour la performance de votre app ! Alors faites chauffer votre café, installez-vous bien : vous êtes à quelques lignes de comprendre Webpack et de bien le configurer !
Initialisation du projet avec Node et NPM
Si vous n’avez pas déjà installé Node et NPM, je vous invite à faire depuis le site officiel. Sur Ensuite, créez un dossier dans lequel vous allez travailler. Nommez-le donc comme vous le souhaitez.
Afin de préparer votre projet à utiliser les dépendances NPM, ouvrez votre terminal, rendez-vous à la racine de votre projet et tapez la commande suivante :
npm init -y
Ensuite, vous allez devoir créez 2 dossiers (public contenant 2 fichiers : index.html
, bundle.js
et src contenant 1 fichier index.js
) et 1 fichier webpack.config.js
à la racine. Pour vous faciliter la tâche, voici les commandes à exécuter (sous Linux/macOS, ces opérations sont aussi réalisables sous Windows avec des commandes équivalentes ou "à la souris") :touch webpack.config.js && mkdir public src && cd public && touch index.html bundle.js && cd .. && cd src && touch index.js && cd ..
Le dossier src/ nous permettra de stocker la logique de notre application tandis que le dossier public nous permettra de stocker tous nos fichiers minifiés. Mais ça, on le verra plus tard.
Il ne manque plus qu’un dossier assets
qui comprendra lui même 4 dossiers dont les noms parlent d’eux-mêmes : fonts
, icons
, images
et stylesheets
. Tapez donc cette commande pour les créer rapidement :
mkdir assets && cd assets && mkdir fonts icons images stylesheets && cd ..
Même chose que pour le point précédent, ces opérations sont aussi réalisables sous Windows avec des commandes équivalentes ou "à la souris".
Installation de Webpack
Voici la partie que vous attendiez avec impatience : l’installation de Webpack. Pour cela, tapez simplement :
npm install --save-dev webpack@latest webpack-dev-server@latest
Les flags --save-dev
(ou raccourci avec -D) indiquent que Webpack correspond à une dépendance de développement, que l'on a besoin de ces fichiers durant cette phase. Vous pourrez le vérifier dans votre fichier package.json
où il sera affiché sous la section dev dependencies. Un dossier node_modules
va apparaître dans votre dossier : il s’agit des dépendances dont Webpack va avoir besoin pour fonctionner.
Si vous utilisez git pour versionner vos fichiers, il est recommandé de ne pas inclure le dossier node_modules, c'est-à-dire de l'ajouter aux instructions .gitignore
Configuration de Webpack
Maintenant que Webpack est installé, nous allons devoir le configurer ! Pour cela, ouvrez webpack.config.js
et ajoutez les lignes suivantes :
const webpack = require("webpack");
const path = require("path");
Nous créons ici une constante appelée webpack
, qui requiert le module webpack. C’est la base pour que tout fonctionne. Puis nous créons la variable path
qui va nous permettre d’indiquer les bons chemins vers nos fichiers.
Ensuite, il va falloir indiquer un point d’entrée (notre fichier index.js
), c’est-à-dire le fichier qui sera lu et un point de sortie, à savoir le fichier qui sera compilé (bundle.js
). Ensuite, nous allons exporter cette configuration :
let config = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "./public"),
filename: "./bundle.js"
}
}
module.exports = config;
Maintenant, n’oubliez pas de lier votre fichier bundle.js
à votre fichier index.html
en tapant la ligne de code qui suit, juste avant la fermeture de votre balise <body>
:
<script src="bundle.js"></script>
Avant de faire notre premier test, vous allez installer Webpack de manière globale sur votre ordinateur avec l'option -g
:
npm install -g webpack@latest
Rendez-vous désormais dans votre fichier index.js
et tapez le code JS de votre choix. J’ai opté pour un simple :
document.write("Je débute avec Webpack !");
Maintenant, tapez simplement webpack
dans votre terminal et laissez la magie opérer :) Profitez-en pour ouvrir votre index.html
avec le navigateur de votre choix pour voir le contenu de votre page !
Un peu d’automatisation
Tout ceci est bien beau, mais vous n’allez pas taper webpack
dans votre terminal à chaque fois que vous voulez voir vos derniers changements, ça serait trop lourd ! Un flag existe pour cela : --watch
ou -w
. Allez-y, tapez webpack --watch
et regardez ce qu’indique Webpack dans votre terminal :
Cela signifie que Webpack surveille les modifications que vous allez apporter à vos fichiers. Vous pourrez donc simplement rafraîchir votre page HTML à chaque fois que vous voudrez voir le rendu. D’ici quelques paragraphes, nous verrons comment mettre en place le Hot Module Reload ou HMR pour les intimes : vos pages seront automatiquement rafraîchies à chaque fois que vous sauvegarderez votre travail depuis votre éditeur de code.
Reprenez donc votre fichier index.js et éditez le texte que vous aviez écrit. Sauvegardez, rechargez la page : magie, ça fonctionne ! Mais nous pouvons encore améliorer ceci. Plutôt que de taper webpack --watch
, nous allons rendre ça un peu plus sexy : rendez-vous dans votre fichier package.json
et modifiez l’objet script comme suit :
"scripts": {
"watch": "webpack --watch"
}
Maintenant, lorsque vous voudrez lancer la commande watch
depuis votre terminal, tapez npm run watch
.
Écrire de l’ES6 ? Le convertir en ES5 ? C’est possible !
Vous avez sûrement déjà entendu parler de l’ES6 (ECMAScript 6), une version récente du langage Javascript (suivie par d'autres au fil des ans). Vous devez donc savoir qu’il n’est pas possible pour tous les navigateurs (les plus anciens) d'interpréter l’ES6.
Webpack va nous permettre, en collaboration avec Babel, de compiler l’ES6 en ES5, ce qui rendra votre syntaxe récente (par exemple let et autres fonctions fléchées) parfaitement utilisable.
Pour cela, nous allons installer les dépendances Babel Loader et Babel Core :
npm install --save-dev babel-loader babel-core
Ajoutez ensuite le code suivant à votre fichier de configuration Webpack, après l’objet output :
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
}]
}
Quelques explications :
- La première ligne va identifier tous les fichiers se terminant par
.js
- La seconde va exclure de ces fichiers tous ceux qui se situent dans
node_modules
- La troisième va charger le loader Babel Core
babel-loader
Votre fichier doit donc désormais ressembler à ça :
const webpack = require("webpack");
const path = require("path");
let config = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "./public"),
filename: "./public/bundle.js"
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
}]
}
}
module.exports = config;
Maintenant, nous allons devoir indiquer à Babel qu’il doit utiliser le preset (pré-réglage) ES2015. Pour ce faire, entrez la commande suivante :
npm install --save-dev babel-preset-env
Créez un fichier .babelrc
à la racine de votre projet et ajoutez-y le code suivant :
{
"presets": [
["env", {
"targets": {
"browsers": ["last 2 versions", "safari >= 7"]
}
}]
]
}
Il va rendre votre ES6 compatible avec les 2 dernières de tous les navigateurs et les versions de Safari supérieures ou égales à la 7. Babel utilisant Browserlist, je vous invite à vous rendre sur la page GitHub du projet si vous souhaitez en apprendre plus sur cette partie de la configuration.
Allez dans votre fichier index.js et tapez de l’ES6. Pour ma part, je suis resté simple avec :
let a = "J'apprends Webpack !";
Ensuite, lancez Webpack avec npm run watch
. Ouvrez votre fichier bundle.js
et rendez-vous tout en bas. Si tout à bien fonctionné, vous devriez avoir var a = "J'apprends Webpack";
à la place de let, signe que Webpack a bien compilé l’ES6 en ES5 !
Compiler du SCSS en CSS ? C’est possible aussi !
Pour cela, vous allez avoir besoin d’installer de nouvelles dépendances :
npm i --save-dev sass-loader node-sass css-loader style-loader autoprefixer postcss-loader
De la même manière que vous l’aviez fait pour Babel Loader, tapez le code suivant dans webpack.config.js
après le loader babel-loader :
{
test: /\.scss$/,
loader: ['style-loader', 'css-loader', 'sass-loader', 'postcss-loader']
}
Votre fichier webpack.config.js doit désormais ressembler à ça :
const webpack = require("webpack");
const path = require("path");
let config = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "./public"),
filename: "./bundle.js"
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.scss$/,
loader: ['style-loader', 'css-loader', 'sass-loader', 'postcss-loader']
}]
}
}
module.exports = config;
Il va maintenant falloir créer un fichier .scss
dans votre dossier assets/stylesheets
pour tester tout ça :) Si vous n’êtes pas du tout familier avec SASS, je vous conseille de vous y intéresser. Il s’agit de CSS évolué, vous permettant notamment d’utiliser des variables. Nommez-le styles.scss
. Voici le code que j’ai tapé, toujours pour rester simple :
$midnight-blue : #2c3e50;
body {
background-color: $midnight-blue;
}
En gros, j’attribue le nom de Midnight-blue à la couleur dont le code hexadecimal est #2c3e50
. Puis je l’utilise pour changer la couleur de mon body en indiquant le nom de la variable (retenir les codes couleur est plus difficile :)).
Dans index.js
, nous allons maintenant require ce fichier. Pour cela, écrivez la ligne suivante au-dessus de tout le code :
require("../assets/stylesheets/styles.scss");
Avant de vérifier que tout fonctionne, j’attire votre attention sur PostCSS et autoprefixer : ce sont 2 outils qui vont vous permettre de préfixer automatiquement votre code CSS pour tous les navigateurs. Il ne vous sera donc plus nécessaire de penser écrire des propriétés CSS spécifiques pour -webkit-
(WebKit, Safari, Opera), -moz-
(Firefox), -o-
(anciennes versions d'Opera) et -ms-
(Microsoft). Tout sera fait automatiquement !
Pour en profiter, créez un fichier postcss.config.js
à la racine de votre projet et ajoutez-y le code suivant :
module.exports = {
plugins: [
require("autoprefixer")
]
}
Maintenant, relancez Webpack puis rechargez votre page. Elle devrait arborer un très beau Midnight Blue !
C'est très bien mais cela ne fonctionnera que dans votre environnement de développement. Tant que le tout n’est pas extrait dans un fichier CSS, vos utilisateurs ne pourront pas profiter de vos belles interfaces. Nous allons donc faire en sorte que tout code écrit dans un fichier SCSS soit compilé en CSS dans un fichier adéquat.
Pour cela, nous allons ajouter de nouvelles dépendances, vous commencez à en avoir l’habitude :
npm install --save-dev extract-text-webpack-plugin
Ajoutez la ligne suivante sous la ligne const path
de votre fichier de configuration Webpack pour require le plugin Extract Text :
const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin");
Ensuite, remplacez :
{
test: /\.scss$/,
loader: ['style-loader', 'css-loader', 'sass-loader', 'postcss-loader']
}
Par ceci, pour spécifier quels loaders utiliser et appeler le plugin :
{
test: /\.scss$/,
use: ExtractTextWebpackPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader', 'postcss-loader'],
})
}
Enfin, initialisez le plugin avec le code suivant, après votre objet module :
plugins: [
new ExtractTextWebpackPlugin("styles.css")
]
Votre fichier de configuration Webpack doit donc désormais ressembler à ceci :
const webpack = require("webpack");
const path = require("path");
const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin");
let config = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "./public"),
filename: "./bundle.js"
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.scss$/,
use: ExtractTextWebpackPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader', 'postcss-loader'],
})
}]
},
plugins: [
new ExtractTextWebpackPlugin("styles.css")
]
}
module.exports = config;
C’est l’heure du test ! Lancez npm run watch
: si vous n’avez aucune erreur de compilation dans votre terminal et qu’un fichier styles.css
a bien été généré dans votre dossier public avec du pur CSS, c’est que tout est bon ! N’oubliez pas de linker votre fichier CSS à votre HTML.
Installer un serveur de développement avec Hot Module Reload
Chose promise, chose due ! Nous allons maintenant un serveur de développement avec Hot Module Reload, qui rechargera automatiquement vos pages en fonction des modifications que vous apporterez à vos fichiers et qui en plus fera office de serveur local.
On commence donc par l’habituelle installation de dépendances :
npm install webpack-dev-server --save-dev
Après l’array de votre objet plugins dans votre fichier de configuration Webpack, ajoutez le code suivant :
devServer: {
contentBase: path.resolve(__dirname, "./public"),
historyApiFallback: true,
inline: true,
open: true,
hot: true
},
devtool: "eval-source-map"
Quelques explications :
contentBase
: indique le dossier depuis lequel le contenu sera servihistoryApiFallback
: activation d’un fallback versindex.html
pour les Single Page Applicationsinline
: active la diffusion de messages dans la console DevToolsopen
: ouvre votre navigateur par défaut lorsque le serveur est lancéhot
: active le Hot Module Reload, soit le rechargement automatique de vos modules à chaque modification/sauvegarde de vos fichiers
Votre fichier de configuration Webpack doit ressembler à ce qui suit après cette nouvelle mise à jour :
const webpack = require("webpack");
const path = require("path");
const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin");
let config = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "./public"),
filename: "./bundle.js"
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.scss$/,
use: ExtractTextWebpackPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader', 'postcss-loader'],
})
}]
},
plugins: [
new ExtractTextWebpackPlugin("styles.css")
],
devServer: {
contentBase: path.resolve(__dirname, "./public"),
historyApiFallback: true,
inline: true,
open: true,
hot: true
},
devtool: "eval-source-map"
}
module.exports = config;
Maintenant, il va falloir lancer votre serveur ! Pour ce faire, remplacez l’objet scripts de votre package.json
par :
"scripts": {
"start": "webpack-dev-server -d --hot --config webpack.config.js --watch"
}
Comme vous pouvez le voir, il vous suffit de taper npm run start
pour lancer votre serveur et non plus npm run watch
comme nous le faisions jusqu’alors. Si tout se passe bien, votre navigateur va alors s’ouvrir avec un onglet contenant votre site.Et là, vous allez sûrement remarquer que votre page ne s’actualise pas automatiquement au gré de vos changements. Du coup, nous allons installer la dépendance css hot loader :
npm install css-hot-loader --save-dev
Puis nous allons remplacer :
{
test: /\.scss$/,
use: ExtractTextWebpackPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader', 'postcss-loader'],
})
}
par :
{
test: /\.scss$/,
use: ['css-hot-loader'].concat(ExtractTextWebpackPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader', 'postcss-loader'],
}))
}
Vous pouvez désormais relancer Webpack avec npm run start
et faire quelques changements dans votre fichier SCSS pour les voir opérer en live !
Minifier les fichiers Javascript
La minification, vous connaissez ? En gros, il s’agit de réduire la taille de vos fichiers de manière à accélérer leur chargement en retirant les caractères et espaces superflus. Le plugin UglifyJS va nous permettre d’atteindre ce but.
Allez, on s’installe des dépendances :) ?
npm install uglifyjs-webpack-plugin --save-dev
Comme on l’a fait jusque là, créez une constante pour ce plugin dans votre fichier de configuration Webpack, sous le plugin Extract Text :
const UglifyJSPlugin = require("uglifyjs-webpack-plugin");
N’oublions pas d’initialiser le plugin dans l’array d’objet plugins :
new UglifyJSPlugin()
Qui doit donc désormais ressembler à ça :
plugins: [
new ExtractTextWebpackPlugin("styles.css"),
new UglifyJSPlugin()
]
Lancez Webpack avec la commande webpack
. Si tout a bien fonctionné, rendez-vous dans votre fichier bundle.js
: vous verrez que le fichier a été minifié et ne tient plus que sur une seule ligne.
Mettre en place des environnements de production et de développement
C’est bien beau tout ça, mais comment est-ce que vous allez vous y retrouver dans tout ce code minifié ? Pas facile de débugger.
Nous allons donc mettre en place un environnement de développement dans lequel rien ne sera minifié. Parce que pendant cette phase, on s’en fiche pas mal que votre code soit léger et vous devrez être capable de vous y retrouver facilement. En revanche, en production, c’est-à-dire le produit servi aux utilisateurs, on aura tout intérêt à minifier notre code.
Rendez-vous donc dans votre fichier package.json
et ajoutez les lignes suivantes à votre objet script (si vous etes sous Windows, ne tapez pas ce code, passez à l'étape suivante) :
"dev": "webpack", "prod": "NODE_ENV=production webpack --progress"
Attention, si vous développez sous Windows, la manipulation est légèrement différente. Commencez par installer la dépendance cross-env avec la commande suivante :
npm install --save-dev cross-env
Ensuite, modifiez votre fichier package.json
de la manière suivante :
"scripts": {
"dev": "webpack",
"prod": "cross-env NODE_ENV=production webpack --progress"
}
Lancez Webpack en faisant npm run prod
. Si vous avez bien fait, vous devriez voir NODE_ENV=production webpack --progress
dans votre terminal, comme sur la capture suivante :
C’est très bien, mais ça ne fait actuellement rien de plus que notre commande npm run start
en terme de différenciation d’environnement. Nous allons donc y remédier en tapant cette condition sous notre module.exports
de notre fichier de configuration Webpack :
if (process.env.NODE_ENV === 'production') {
module.exports.plugins.push(
new webpack.optimize.UglifyJsPlugin()
);
}
En gros, on dit dans cette condition que si on dans notre environnement de production, alors minifie nos fichiers en utilisant le plugin UglifyJS. Du coup, n’oubliez pas de supprimer new UglifyJSPlugin()
de votre array plugins sinon vos fichiers seront minifiés dans tous les cas.
Maintenant, si vous lancez npm run dev
, vous serez dans votre environnement de développement, vos fichiers ne seront pas minifiés. Faites un test et regardez votre fichier bundle.js
qui tient normalement sur plusieurs lignes. Faites un npm run prod et vous verrez qu’il est minifié et donc plus léger.
Minifier les fichiers CSS
Minifier les fichiers CSS repose sur le même principe que les fichiers JS, nous allons donc, comme d’habitude, installer une nouvelle dépendance :
npm install optimize-css-assets-webpack-plugin --save-dev
Ensuite, il va falloir créer une constante dans votre fichier de configuration Webpack :
const OptimizeCSSAssets = require("optimize-css-assets-webpack-plugin");
Enfin, on appelle le plugin dans notre condition (je vous rappelle qu’on ne veut la minification qu’en prod !) :
new OptimizeCSSAssets()
Voici à quoi doit ressembler cette condition :
if (process.env.NODE_ENV === 'production') {
module.exports.plugins.push(
new webpack.optimize.UglifyJsPlugin(),
new OptimizeCSSAssets()
);
}
Vous pouvez faire comme nous avons fait plus haut pour la minification JS : faites un test avec npm run dev
où vos fichiers CSS ne doivent pas être minifiés et un autre avec npm run prod
où ils doivent l’être.
Vous avez désormais 3 moyens de lancer Webpack :
npm run start
: qui démarre votre serveur, le HMR et qui ne minifie aucun fichiernpm run dev
: qui lance votre environnement de développement sans HMR ni serveur et minificationnpm run prod
: qui lance votre environnement de production sans HMR ni serveur et avec minification
Bonus
Votre terminal affiche désormais tous les détails dont vous avez besoin :
Mais il faut avouer que ce n’est pas très clair, non ? Que diriez-vous de pimper Webpack pour qu’il ressemble à ça :
Si tel est le cas, ajouter la dépendance Webpack Dashboard avec la commande suivante :
npm install webpack-dashboard --save-dev
Ajoutez ensuite l’habituelle constante à votre fichier de configuration Webpack :
const DashboardPlugin = require("webpack-dashboard/plugin");
Puis appelez le plugin depuis votre array plugins
toujours dans le même fichier :
new DashboardPlugin()
Enfin, modifiez l’objet scripts de package.json
en ajoutant webpack-dashboard pour que le dashboard se lance lorsque vous lancez votre serveur avec npm run start
:
"scripts": {
"dev": "webpack",
"start": "webpack-dashboard webpack-dev-server -d --hot --config webpack.config.js --watch",
"prod": "NODE_ENV=production webpack --progress"
}
Vous en savez désormais plus sur Webpack et vous avez surtout réussi à configurer votre starter que vous pourrez utiliser pour votre prochain projet ! N’hésitez pas à laisser un commentaire si toutefois vous aviez une remarque à faire et clapez autant que vous pouvez :) !
Commentaires
très très bon tutoriel que je vais lire plusieurs fois ....merci beaucoups .
Pour le débutant certains mots devraient faire l'objet d'une introduction : un projet ? , comment npm sait il ou il va installer le package ? docker possible ?.
const webpack = require("webpack"); pour être terre à terre charge t il le module( package) qui se situe dans projet/node_module/webpack/ mais quelle fichier javascript en premier ?
Quelles sont les diférences entre la version 1 et 2 ?
Pour résumer ( me corriger si je me trompe) , wepack permet en utilisant une seule ligne de code ( lien vers un script) dans le fichier html de charger plusieurs types de ressources ( librairie , code pour css, js, raster , svg .... ) .
Comment se comporte le code généré par webpack coté client si on utilise webpack dans un CMS ? déja cela a t il un sens ? Je pense surtout au fait que ce genre d outils devrait coté client ne charger ( appeler au fur à mesure ) que les ressources utiles en cas de besoin ( lazy loader ?) et ne pas charger toutes les ressources et de ne pas se recharger lors de changement de page ( même template) !! .
Salut,
Dans la partie : Écrire de l’ES6 ? Le convertir en ES5 ? C’est possible !
au niveau de : Votre fichier doit donc désormais ressembler à ça :
il y a une erreur a la ligne : filename: "./public/bundle.js"
le "public" est de trop, cela créer un répertoire public dans le répertoire public
J'ai aussi une erreur avec le .babelrc :
Module build failed: Error: Couldn't find preset "env" relative to directory "/Lab/test/debuter-avec-webpack"
L'erreur avec le .babelrc : Module build failed: Error: Couldn't find preset "env" relative to directory "/Lab/test/debuter-avec-webpack"
Je l'ai résolu avec : npm install --save-dev babel-preset-env
@bastienrc : Effectivement Bastien, merci pour ta vigilance ! C'est corrigé !
Très bon tuto @ZeFifi , clair et bien détaillé. Je viens de l'installer pour mon nouveau projet :)
Super tuto, je découvre Webpack et trouve ça génial !
Par contre, je suis sur Windows et j'ai un problème avec le script prod :
"prod": "set NODE_ENV=production && webpack --progress"
J'ai dû rajouté "set" et && après lecture sur le web mais ça plante au niveau du fichier config webpack avec la condition :
if (NODE_ENV === 'production') {
module.exports.plugins.push(
new webpack.optimize.UglifyJsPlugin()
);
}
Erreur affiché dans la console :
ReferenceError: NODE_ENV is not defined
Une idée pour remettre ça en route ?
@mediapole : Réponse solution à moi même et peut-être utile @ZeFifi et autres utilisateurs Windows :
1- En utilisant les dépendences "cross-env", variables d'environnement cross platform
https://www.npmjs.com/package/cross-env
npm install --save-dev cross-env
2- on modifie le fichier package.json, balise script.prod :
"scripts": {
"start": "webpack-dev-server -d --hot --config webpack.config.js --watch",
"dev": "webpack",
"prod": "cross-env NODE_ENV=production webpack --progress"
}
Le soucis sur Windows est réglé... mais peut-être y a-t-il plus simple sans passer par "cross-env" ?
Intéressant comme intro mais un peu frustrant. On peut déjà trouver ce genre de tuto sur le net si on s'y intéresse un peu.
Ce qui est intéressant en webpack est notamment la modularité du bundle. parce que là on a l'impression que 220k minifié gzip c'est admissible pour la prod, mais on est déjà au limite (2s) pour le "mobile first" et c'est juste pour le JS, reste le html & les assets.
Reste tellement d'autres sujets à aborder. Un lien pour aller plus loin aurait été intéressant. Et parler de webpack-merge pour avoir un fichier webpack maintenable aurait été bien.
Et non je ne suis pas un hater.
Article intéressant mais je suis un peu du même avis que Wadouk.
Je pense que Webpack est bien plus qu'un simple bundler mais on ne trouve que des tutos basiques qui ne font pas plus qu'une configuration Gulp ou Grunt.
Un second article sur les avantages de Webpack, la modularité, le lazy loading... serait sympa.
@wadouk @korigan Merci pour vos retours constructifs et vous avez tout à fait raison. Le but ici était, comme tu le dis si bien Wadouk, une intro au sujet, je voulais m'intéresser à la propriété de bundler dans un premier temps. Des updates sont prévues, mais encore va-t-il falloir les écrire :)
@mediapole merci, je vais mettre l'article à jour en conséquence dès que je peux. Après quelques recherches, il s'avère que ta solution est la bonne ;)
@angelique : Trop cool Angélique, merci pour ton retour !
@tout le monde : pour ma part, débutant sur Webpack, j'ai trouvé le format du tuto BON, ça m'a pris 1/2 journée a bien tout faire dans le cadre de mon nouveau projet (j'étais bloqué avec mon Chrome et ES6 avec les import de classes). Le tuto aurait été plus complet, ça m'aurait peut-être fait un peu plus peur pour l'aborder. J'ai trouvé ici ce que je cherchais et je trouve que juste les fonctionnalités abordés sont géniales ! ... donc big hugh à ZeFifi pour ce chouette tuto pour ma part je suis comblé :)
Merci @mediapole ton retour me fait vraiment super plaisir !
@tout le monde : pour ma part, débutant sur Webpack, j'ai trouvé le format du tuto BON, ça m'a pris 1/2 journée a bien tout faire dans le cadre de mon nouveau projet (j'étais bloqué avec mon Chrome et ES6 avec les import de classes). Le tuto aurait été plus complet, ça m'aurait peut-être fait un peu plus peur pour l'aborder. J'ai trouvé ici ce que je cherchais et je trouve que juste les fonctionnalités abordés sont géniales ! ... donc big hugh à ZeFifi pour ce chouette tuto pour ma part je suis comblé :)
Hello,
webpack-dashboard a l'air sympa mais ca capote chez moi
par contre ca se passe comment pour les images? j'ai cru comprendre qu'il faut url ou file-loader, c'est un peu la jungle pour comprendre et faire fonctionner tout ca
@lei : Tu peux te créer un répertoire images dans assets et tout mettre dedans :) Pour le chemin, tu indiques "images/nom-du-fichier.jpg" et ça devrait aller ;)
Excellent tutoriel, merci pour tout !
Petite question de débutant webpack, si je développe sous Webpack, je dois livre au client le dossier assets et public ?
Merci pour le tuto. Chez moi le css hot loader ne fonctionne pas. Dès que je sauve le fichier .scss, rien ne se passe. Aucune compilation... Webpack 3.10.0 est installé. Voici ma config webpack:
let config = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "./public"),
filename: "./bundle.js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.scss$/,
use: ['css-hot-loader'].concat(ExtractTextWebpackPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader', 'postcss-loader'],
}))
}
]
},
plugins: [
new ExtractTextWebpackPlugin("styles.css")
],
devServer: {
contentBase: path.resolve(__dirname, "./public"),
historyApiFallback: true,
inline: true,
open: true,
hot: true
},
devtool: "eval-source-map"
}
@deenice : J'ai suivi le tuto aussi, as tu bien pensé à importer ton fichier styles.scss dans ton index.js ? :
import '../assets/stylesheets/styles.scss;
Après une autre méthode consiste à mettre un autre point d'entrée dans ta config webpack:
entry: ["./src/index.js", "./assets/stylesheets/styles.scss"],
plutôt que d'importer ton fichier scss dans index.js.
Pour moi ça a marché, après je ne suis pas une spécialiste, je débute avec webpack, et je ne sais pas quelle est la meilleure pratique !
@Haestan : Le dossier public contient effectivement ton site compilé et le dossier assets tous les assets dont les images ;) C'est donc bien ces 2 répertoires que tu dois livrer !
Ouaou !! Ultra puissant !! Un grand merci à votre équipe, vous êtes géniaux ;)
Bonjour, merci pour ce tutoriel très bien expliqué et complet pour bien démarrer avec Webpack.
Tout a parfaitement fonctionné jusqu'à l'étape bonus Webpack Dashboard. Une fois cette fonctionnalité installé, j'ai rencontré des problèmes au niveau de l'actualisation en live lorsque je modifiais mon scss alors que cela marchait avant. Après quelques recherches sur internet, j'ai constaté qu'en mettant:
"start": "webpack-dashboard -- webpack-dev-server -d --hot --config webpack.config.js --watch"
dans le script du fichier package.json, tout se remettait à fonctionner correctement.
@Wollsale : J'ai le problème que toi. As tu trouvé une solution?
Sinon très bon tuto mais je suis bloqué tout comme @Wollsale.
Bonjour,
merci pour ce tutoriel très précis qui permet une bonne première approche de webpack.
J'ai une interrogation concernant le fichier bundle.js qui est dans le dossier public. Une fois toutes les manipulations faites il est composé d'un grand nombre de lignes liées à webpack. J'avoue que j'ai la sensation que ces lignes "polluent" le fichier. En effet s'agissant du fichier de prod, pourquoi autant de lignes liées à Webpack dedans ? Ai-je fait une mauvaise manip, où est-ce une particularité explicable de webpack.
Merci !
Un grand merci, j'avais fait du webpack 1 il y a un petit moment et du coup j'ai pu configurer notre nouveau projet très facilement grâce à ton tuto.
Le seul truc qui me manque, et que j'avais fait dans mon ancien projet c'est le serveur qui doit être liée à mon framework PHP. Si c'est comme avec webpack 1 faut utiliser l'option proxy mais je vais chercher.
Bonjour,
Tout d'abord merci pour ce tuto :) Bien des choses se sont éclaircies depuis cette lecture :)
Tout fonctionnait parfaitement en suivant ce tuto sauf que lorsque je changeais mon fichier scss la page n'était pas automatiquement rafraîchie. J'ai vu dans les commentaires que plusieurs personnes avaient ce problème avec Hot Reload. J'ai résolu le problème en ajoutant une lignes aux plugins du webpack.config.js
plugins: [
new ExtractTextWebpackPlugin("styles.css"),
new webpack.HotModuleReplacementPlugin()
],
Du coup maintenant le premier script "start" présenté dans ce tuto fonctionne parfaitement .
"scripts": {
"start": "webpack-dev-server -d --hot --config webpack.config.js --watch"
}
Bonjour,
J'ai eu un petit problème avec la version 4 de webpack, que j'ai résolu ;)
Pour le extract-text-webpack-plugin, il faut faire:
npm i -D extract-text-webpack-plugin@next
Si cela aide quelqu'un.
Aussi avec la 4, il faut faire:
"dev": "webpack --mode development",
"prod": "webpack --mode production"
Pour activer les différents modes.
Ils impliquent différents fonctionnements mais je laisse à l'auteur editer son poste.
Ex: le mode prod va directement minifier le js par défault.
Merci pour le super tuto, le meilleur à ce jour, et récent en plus!
Néanmoins, les choses évoluent vite, et vous avez peut-être, comme moi, eu affaire à une erreur de compilation au moment d'intégrer
"extract-text-webpack-plugin". Si vous avez une erreur de type "DEPRECIATION WARNING" au sujet d'un module nommé "tapable", remplacé simplement la version du module dans votre fichier package.json comme suit:
"extract-text-webpack-plugin": "^4.0.0-alpha.0"
Cela devrait normalement résoudre le problème. Je n'ai pas trouvé mieux pour l'instant.
PS: Je vois à l'instant que ce sujet est évoqué par @Esquiro, je poste malgré tout, ça peut servir.
Bonjour,
Même remarque que @korigan : j'avais compris que Webpack allait plus loin qu'un task runner js. Par exemple la gestion d'un fichier manquant, telle une image manquant à l'appel alors qu'elle est appelée par CSS. Mais il y a sans doute d'autres points encore plus importants, je ne les connais pas...
Très bon tuto,
Cependant j'ai été bloqué à partir de l'étape à laquelle on ajouter le css-hot-loader.
Impossible d'avoir le module qui se charge quand on lance le serveur, obligé de faire une modification dans l'index.js pour que le module se charge. En fouinant sur github j'ai finalement trouvé la solution à cette adresse: https://github.com/shepherdwind/css-hot-loader/issues/37
Il suffit de remplacer "extract-text-webpack-plugin" par "mini-css-extract-plugin"
Pour l'installer: npm install mini-css-extract-plugin --save-dev
Et la configuration :
Remplacer
{
test: /\.scss$/,
use: ['css-hot-loader'].concat(ExtractTextWebpackPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader', 'postcss-loader']
}))
}]
Par
{
test: /\.scss$/,
use: ['css-hot-loader', MiniCssExtractplugin.loader, 'css-loader']
}]
Et dans la partie plugins ajoutez cette ligne:
new MiniCssExtractplugin("styles.css")
Merci pour le tuto en tout cas :)
je suis bloqué à la saisi de la commande >webpack
ça me compile dans un dossier /dist/main.js, j'ai loupé qqch ?
voici mon webpack.config.js
const webpack = require("webpack");
const path = "/data/monchemin/jh";
const config = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: "/data/monchemin/jh/public"
}
};
module.exports = config;
On est sur quelles versions de webpack pour ce tuto ?
visiblement depuis, il y a eu du changement
On est sur quelles versions de webpack pour ce tuto ?
visiblement depuis, il y a eu du changement
@jhabai :
// package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack --watch --mode development ./src/index.js --output ./public/bundle.js",
"build": "webpack --mode production ./src/index.js --output ./public/bundle.js"
},
@jhabai : webpack.config.js n'était pas à la racine, dsl
Merci pour ce tuto canon ! Gros +1 pour le dashboard, c'est vraiment trop cool comme feature :)
Comme les commentaires précédents, j'ai eu deux-trois soucis, voici comment je les ai résolu si ça peut aider qqn :
Étape - Éditer le fichier .babelrc :
Au lieu de env j'ai du mettre : @babel/preset-env
Étape - Compilation CSS
Le plugin Extract Text Webpack n'était pas compatible avec la version de Webpack. Voici la commande que j'ai du exécuter pour l'installer :
npm i -D extract-text-webpack-plugin@next
Étape - Définitions des environnements
Au lieu de new webpack.optimize.UglifyJsPlugin(), j'ai remis UglifyJsPlugin en utilisant le même nom que dans le require.
Encore merci pour cet article, très complet pour partir une appli :)
Merci pour ce tutoriel, il est vraiment au top même si j'ai vus qu'il manquait quelques petits bout de morceaux, mais celà nous fait un peu chercher les informations !
Merci ^^
Bonjour,
Bon tuto pour comprendre un peu à quoi sert ce webpack (Au final, je trouve que le moindre projet web aujourd'hui est une vraie usine à gaz et qu'on à fait un bond de 20 ans en arrière... C'est d'une complexité hallucinante, mais bon, je suis hors sujet :) ).
J'ai un souci que je ne sais pas comment résoudre.
J'ai un serveur d'appli qui va servir une petit appli web MVC bien classique . Le site est en techno node/typescript/express/nunjucks
J'aimerais pouvoir créer des scripts client (en ts) et créer un bundle pour chaque page servies et non pour l'ensemble du site (et encore mois avec les ts du serveur).
Or webpack, choppe tout ce qu'il trouve et génère 1 seul bundle...
Et quand je n'utilise pas webpack, j'ai des modules qui ne se chargent pas (coté client).
Je ne sais plus comment faire... Une idée? Qu'est ce que j'ai loupé?
Bonjour,
Merci pour ce tuto !
Lorsque je tente d'installer Webpack de manière global avec la commande [npm install -g webpack@latest] j'ai de nombreuses erreurs que je ne parviens pas à résoudre :
npm ERR! path ../lib/node_modules/webpack/bin/webpack.js
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall symlink
npm ERR! Error: EACCES: permission denied, symlink '../lib/node_modules/webpack/bin/webpack.js' -> '/usr/local/bin/webpack'
npm ERR! [OperationalError: EACCES: permission denied, symlink '../lib/node_modules/webpack/bin/webpack.js' -> '/usr/local/bin/webpack'] {
npm ERR! cause: [Error: EACCES: permission denied, symlink '../lib/node_modules/webpack/bin/webpack.js' -> '/usr/local/bin/webpack'] {
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'symlink',
npm ERR! path: '../lib/node_modules/webpack/bin/webpack.js',
npm ERR! dest: '/usr/local/bin/webpack'
npm ERR! },
npm ERR! stack: 'Error: EACCES: permission denied, symlink ' +
npm ERR! "'../lib/node_modules/webpack/bin/webpack.js' -> " +
npm ERR! "'/usr/local/bin/webpack'",
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'symlink',
npm ERR! path: '../lib/node_modules/webpack/bin/webpack.js',
npm ERR! dest: '/usr/local/bin/webpack'
npm ERR! }
npm ERR!
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator (though this is not recommended).
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/Johan/.npm/_logs/2019-06-12T11_42_04_580Z-debug.log
Avez-vous une idée ??
petit astuce pour les user window
`npm i touch-cli-windows -g`
Pour ajouter la command touch de façon global a votre system.
Si vous avez node biensur.
@shenron76 : essaye [sudo npm install -g webpack@latest]
Bonjour,
Merci pour ce tuto ! J'ai juste un problème, je n'arrive pas à accéder aux images de mon dossier assets puisqu'il est en dehors du dossier public. Comment faire pour y accéder ? Dois-je mettre mes assets dans le dossier public ?
Mercii d'avance
Bonjour,
Merci pour ce tuto ! J'ai juste un problème, je n'arrive pas à accéder aux images de mon dossier assets puisqu'il est en dehors du dossier public. Comment faire pour y accéder ? Dois-je mettre mes assets dans le dossier public ?
Mercii d'avance
Bonjour à tous,
J'ai suivi le tutoriel mais très vite coincer au niveau du tout premier essai !
J'ai systématiquement le message du terminal
« -bash: webpack: command not found »
J'utilise un MBA avec Mac OS 10.14.6 Mojave
Vos réponse sont les bien venues