Malheureusement, je n'ai pas le temps/l'enthousiasme pour maintenir ce projet pour le moment. Je recommande de créer ce projet ou de lire sa source pour savoir comment il est construit.
Ce pack standard de webpack est destiné aux développeurs débutants, intermédiaires et avancés qui cherchent à créer rapidement des sites Web statiques tout en réalisant toutes les optimisations nécessaires pour obtenir un score parfait sur Google Page Speed Insights et Google Lighthouse Reports. Il s'agit d'une évolution de tris-gulp-boilerplate, désormais avec Webpack 4. Webpack est le nouveau standard de regroupement de JS dont Gulp n'était pas capable. Heureusement, Webpack peut à la fois exécuter des tâches et regrouper js ?
Le but de ce projet/passe-partout est de toucher les personnes suivantes :
Les débutants ? - qui, bien qu'ils utilisent Gulp/Webpack/Node/Npm, ont encore besoin d'explications plus approfondies que les développeurs plus familiers. Ils veulent que les choses fonctionnent, mais ils veulent aussi savoir comment et pourquoi .
Les arnaqueurs de projets parallèles ?♀️ — ceux qui ont toutes les bonnes idées mais qui ne veulent pas perdre de temps avec la configuration. Ils doivent diffuser leurs idées, leurs applications et leurs sites Web dans le navigateur... rapidement .
Les obsessionnels compulsifs ♂️ — des gens qui aiment obtenir des scores parfaits sur les rapports de performances et d'optimisation. Les personnes organisées numériquement et fières de savoir que tous leurs fichiers sont minimisés, compressés, compressés et prêts à être expédiés !
N'hésitez pas à créer ce dépôt et à créer votre propre flux de travail basé sur ce modèle ! Tout le monde est un peu différent, je comprends.
Vous avez besoin de git et node.js sur votre ordinateur avant de l'exécuter.
git clone https://github.com/tr1s/tris-webpack-boilerplate.git your-project-name
cd your-project-name && rm -rf .git
npm install
npm start
Vous êtes prêt, commencez à coder ?? !
Supprimez tout ce qui se trouve dans le dossier src/styles/
, src/index.html
et src/index.scss/
si vous souhaitez recommencer à 100 % et/ou créer votre propre flux de travail Sass. J'ai basé ma structure de dossiers sur le modèle 7-1.
npm run build
lorsque vous êtes prêt à télécharger votre site sur la plateforme FTP/d'hébergement de votre choix. Cela créera un dossier dist
avec tous les actifs de votre site Web optimisés et compressés.
Si vous souhaitez une explication détaillée du fonctionnement de tout cela, veuillez lire les fonctionnalités ci-dessous. Sinon, continuez à coder et amusez-vous :)
tris-webpack-passe-partout
Usage
Fonctionnalités / Contenu
Fonctionnalités expliquées
Division de configuration Webpack
Serveur de développement Webpack
Actifs HTML et minification
Page 404 introuvable
SCSS vers CSS + optimisations
Transpilation ES6
Liste des navigateurs
Éléments d'image + compression
Chargement de polices + préchargement
Compression des actifs
Nettoyer le plugin Webpack
Cartes sources
Génération de favicon
Hors ligne d'abord et mise en cache
Application Web progressive (PWA)
Je t'ai eu
Contribuer
Au lieu d'avoir un gros webpack.config.js
, nous diviserons nos versions de production et de développement en deux nouvelles configurations appelées webpack.dev.js
et webpack.prod.js
. Les configurations que nous souhaitons pour le développement et la production iront dans la configuration webpack.common.js
.
Lorsque nous exécutons npm start
, il exécutera la version de développement basée sur la configuration webpack.dev.js
qui contient également les configurations webpack.common.js
fusionnées. En savoir plus à ce sujet dans la documentation Webpack.
/* wenpack.dev.js */const merge = require("webpack-merge");const common = require("./webpack.common.js");/* fusionne le webpack.common.js puis vous ajoutez votre extra */module.exports = merge(common, { mode : "développement", /* le reste du code va ici */});
Lorsque nous exécutons npm run build
, il exécutera la version de production basée sur la configuration webpack.prod.js
qui contient également les configurations webpack.common.js
fusionnées.
/* webpack.prod.js */const merge = require("webpack-merge");const common = require("./webpack.common.js");/* fusionne le webpack.common.js puis vous ajoutez votre extra */module.exports = merge(common, { mode : "production",});
Nous voulons que nos versions de développement et de production produisent les mêmes résultats visuellement dans le navigateur. Vous ne voulez pas terminer le codage, exécuter la construction, puis créer un site Web totalement différent avec des images manquantes par exemple. C'est pourquoi nous avons webpack.common.js
pour gérer tous les chargeurs et la gestion des actifs. Le webpack.dev.js
sera légèrement différent avec une carte source plus légère. Enfin, webpack.prod.js
gérera toutes les étapes finales de mise en production de votre site Web. Il s'agit de la compression d'images, de la compression des actifs (gzip), de la minification des actifs, de la génération de favicon, de la mise en cache et de la création d'une première expérience hors ligne.
Je vais aborder chaque processus ci-dessous.
Le webpack-dev-server est configuré dans le package.json. npm start
exécutera le serveur et ouvrira votre projet dans le navigateur à l'aide de la configuration webpack.dev.js
. npm start
est le script par défaut de npm, vous n'avez donc pas besoin d'y ajouter run
. Mais pour le script de build, vous devez taper npm run build
.
"scripts": { "start": "webpack-dev-server --open --config webpack.dev.js", "build": "webpack --config webpack.prod.js"},
Nous utilisons le chargeur html pour exporter du HTML sous forme de chaîne et réduire la sortie. Cela vous permet d'importer votre src/index.html
dans votre src/index.js
. Nous pouvons simplement réduire le HTML avec une option de chargement minimize: true
, c'est pourquoi nous le laissons dans webpack.common.js
au lieu de le déplacer vers webpack.prod.js
.
/* webpack.common.js */{ tester : /.html$/, utiliser : [{loader : 'html-loader',options : {minimiser : true} }]},
/* src/index.js */import "./index.html";
Nous utilisons ensuite html-webpack-plugin pour créer un nouvel index.html
généré avec toutes les importations d'actifs correctes.
L'option template:
est l'endroit à partir duquel vous extrayez votre HTML source. Vous pouvez utiliser votre propre modèle HTML, votre modèle de guidon ou l'un de ces autres modèles.
L’option inject:
est l’endroit où iront vos actifs. Webpack placera votre script webpack-bundle.js
fourni au bas du corps par défaut, mais ici je l'ai changé en head
car nous utiliserons le script-ext-html-webpack-plugin pour ajouter un attribut defer
au script et placez-le dans l’en-tête du site Web. Cela contribue à la performance.
/* webpack.common.js */const HtmlWebpackPlugin = require('html-webpack-plugin');const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin");plugins : [ nouveau HtmlWebpackPlugin ({titre : 'tris-webpack-boilerplate', nom de fichier : 'index.html', modèle : './src/index.html', injection : 'head' }), nouveau HtmlWebpackPlugin ({titre : 'tris-404-page', nom de fichier : '404.html', modèle : './src/404.html', injection : 'head' }), nouveau ScriptExtHtmlWebpackPlugin({defaultAttribute : 'différer' }),],
Continuez à ajouter de new HtmlWebpackPlugin({})
si vous envisagez d'avoir un site Web multipage. Nommez la page de manière appropriée avec le title:
clé.
Netlify est un fantastique service gratuit qui vous permet de gérer et de déployer vos sites Web. Netlify recherche automatiquement un 404.html
et chargera cette page lorsque quelqu'un essaie d'ouvrir un lien rompu sur votre site Web. Vous n’avez donc rien à craindre.
Si vous utilisez un autre service, veuillez faire des recherches sur la façon dont vous pouvez lier votre page 404.html
afin qu'elle soit active. C'est un excellent moyen de renvoyer les gens vers votre page principale s'ils atterrissent sur un lien rompu.
Afin d'utiliser Sass/SCSS, nous devons utiliser quelques chargeurs pour obtenir les résultats souhaités. Le chargeur css, le chargeur postcss et le chargeur sass.
test:
utilise regex (expression régulière) pour rechercher des fichiers sass, scss ou css, puis les exécute via ces trois chargeurs, qui sont enveloppés autour d'un mini-css-extract-plugin, qui génère ensuite un seul fichier CSS pour vous à utiliser en production.
En savoir plus sur le concept des chargeurs.
/* webpack.common.js */{ test : /.(sa|sc|c)ss$/, utilisez : [MiniCssExtractPlugin.loader,{ chargeur : 'css-loader', options : {sourceMap : true }},{ chargeur : 'postcss-loader', options : {sourceMap : true }},{ chargeur : 'sass-loader ', options : {sourceMap : true }} ]},
La deuxième partie de la séquence de chargement, le postcss-loader
, c'est là que vous allez minifier et préfixer automatiquement votre CSS. Pour ce faire, nous créons un postcss.config.js
à la racine du projet et le configurons ainsi...
/* postcss.config.js */const purgecss = require("@fullhuman/postcss-purgecss");module.exports = { plugins : [require("autoprefixer"),require("cssnano")({ preset : "default",}),purgecss({ content: ["./**/*.html"], images clés : true,} ), ],};
Renseignez-vous sur le préfixe automatique et cssnano pour le configurer davantage à votre guise si besoin est. Renseignez-vous également sur postcss en général car c'est un outil très puissant à avoir dans votre arsenal.
Purgecss est un fantastique plugin postcss pour se débarrasser des CSS inutilisés dans votre code. Purgecss analyse votre contenu et vos fichiers CSS. Ensuite, il fait correspondre les sélecteurs utilisés dans vos fichiers avec ceux de vos fichiers de contenu. Il supprime les sélecteurs inutilisés de votre CSS, ce qui entraîne des fichiers CSS plus petits.
Il est prêt à l'emploi par défaut, mais si vous souhaitez le tester visuellement par vous-même, décommentez @import "../node_modules/bulma/bulma";
dans index.scss
, puis exécutez npm run build
et jetez un œil au webpack-bundle.css
résultant dans votre dossier dist. Vous remarquerez qu'il n'y a pas beaucoup de code. Supprimez ensuite le purgecss de votre postcss.config.js
et exécutez à nouveau npm run build
, vous remarquerez qu'il y a plus de 10 000 lignes de code dans votre CSS provenant du framework Bulma. Comme vous pouvez le voir, purgecss est parfait pour se débarrasser des CSS que vous n'utilisez pas lorsque vous utilisez de gros frameworks comme Bootstrap, Foundation, Bulma, etc !
Le mini-css-extract-plugin est la dernière étape car il extrait le CSS et lui donne un nom avant d'être affiché.
/* webpack.common.js */const MiniCssExtractPlugin = require("mini-css-extract-plugin");plugins : [ nouveau MiniCssExtractPlugin ({nom de fichier : 'webpack-bundle.css',chunkFilename : '[id].css' })],
Donc, fondamentalement... le css-loader
collectera les CSS de tous les fichiers CSS référencés dans votre application et les placera dans une chaîne. Ensuite, postcss-loader
préfixe et réduit automatiquement vos styles, puis sass-loader
le transforme en module JS, puis mini-css-extract-plugin
extrait le CSS du module JS dans un seul fichier CSS que le navigateur Web peut analyser.
Vous souhaiterez peut-être utiliser les dernières fonctionnalités et syntaxes JavaScript, mais tous les navigateurs ne les prennent pas encore en charge. Babel s'en chargera pour nous.
Ici, nous testons tous les fichiers js, mais en excluant le dossier node_modules
, puis nous l'exécutons via le babel-loader avec le préréglage babel-preset-env.
/* webpack.common.js */{ tester : /.js$/, exclure : /(node_modules)/, utilisez : {loader : 'babel-loader',options : { presets : ['@babel/preset-env']} }}
Cette fois, nous nous aventurons dans le fichier webpack.prod.js
. Lorsque nous npm run build
, notre sortie js sera réduite et aura des sourcesmaps complètes. En mode développement via npm start
nous aurons toujours des sourcesmaps plus légères mais les js ne seront pas minifiés.
/* webpack.prod.js */const TerserPlugin = require("terser-webpack-plugin");module.exports = merge(common, { mode : "production", outil de développement : "carte-source", optimisation : {minimizer : [ new TerserPlugin({test: /.js(?.*)?$/i,parallel: true,sourceMap: true, }),], },});
En savoir plus sur les options dans la documentation terser.
Ici, nous voulons avoir un endroit où nous pouvons indiquer à certains outils pour quels navigateurs nous aimerions ajouter la prise en charge. Nous y parvenons en utilisant browserslist et le fichier .browserslistrc
correspondant à la racine du projet. Autoprefixer et babel-present-env récupéreront ce fichier et appliqueront ce dont il a besoin en fonction de la configuration.
Renseignez-vous sur ce que vous pouvez transmettre d'autre dans .browserslistrc
et utilisez browserl.ist pour voir quels navigateurs seront spécifiquement ciblés avec votre configuration. D'accord, je pense que j'ai déjà dit assez de fois aux navigateurs ?.
/* .browserslistrc */> 0,25%pas mort
Nous testons d'abord les jpeg, jpg, png, gif et svg en utilisant regex (expression régulière), puis nous utilisons file-loader, qui résout les importations et nécessite un fichier dans une URL, puis émet le fichier dans le répertoire de sortie. Ainsi, si vous utilisez un élément <img>
qui récupère un fichier du dossier src/images
, il sera importé et émis vers le chemin de sortie spécifié images
. Ce qui finit par être src/images
si vous npm start
(dev en cours d'exécution) ou npm run build
(build en cours d'exécution).
/* webpack.common.js */{ test : /.(jpe?g|png|gif|svg)$/, utilisez : [{loader : 'file-loader',options : { name : '[name].[ext]', outputPath : 'images/', publicPath : 'images/'}, }]},
Maintenant, nous voulons uniquement optimiser nos images sur npm run build
, nous éditons donc notre webpack.prod.js
comme ci-dessous.
Encore une fois, nous testons les jpeg, jpg, png, gif et svg à l'aide de regex et appliquons les optimisations appropriées. gifsicle
est un compresseur gif sans perte, pngquant
est un compresseur png avec perte, et nous pouvons ajouter un plugin supplémentaire appelé imageminMozjpeg
pour effectuer une compression jpg/jpeg avec perte. Une valeur sûre consiste à régler la qualité entre 75 et 90 et vous devriez obtenir une compression décente sans perte de qualité visible.
Je suggère de s'en tenir à la compression sans perte et de recadrer vos images à leur bonne taille avant de les ajouter à votre projet. Supprimez simplement les sections clés imageminMozjpeg et pngquant pour ce faire.
Vous pouvez également utiliser tinypng pour la compression d'images.
/* webpack.prod.js */const ImageminPlugin = require("imagemin-webpack-plugin").default;const imageminMozjpeg = require("imagemin-mozjpeg");plugins : [ new ImageminPlugin({test : /.(jpe?g|png|gif|svg)$/i,gifsicle : { // niveau d'optimisation du compresseur gif sans perte : 9,}, pngquant : { // compresseur png avec perte, supprimer pour le compresseur sans perte par défaut qualité : "75",},plugins : [ imageminMozjpeg({// compresseur jpg avec perte, supprimer pour la qualité sans perte par défaut : "75", }),], }),];
Ici, nous testons toutes les extensions de polices courantes et utilisons à nouveau le chargeur de fichiers pour résoudre nos importations de polices et les afficher.
/* webpack.common.js */{ test : /.(woff|woff2|ttf|otf)$/, utilisez : [{loader : 'file-loader',options : { name : '[name].[ext]', outputPath : 'fonts/', publicPath : 'fonts/'}, }]},
Dans notre src/styles/base/_typography.scss
nous chargeons les polices via la règle @font-face
. Google Webfonts Helper est également un outil fantastique pour auto-héberger Google Fonts sans tracas. En savoir plus sur la règle @font-face
sur les astuces CSS. De plus, renseignez-vous également sur la propriété font-display.
Il est toujours préférable de précharger vos polices. Nous y parviendrons en utilisant le preload-webpack-plugin, et vous devrez le placer juste après le HtmlWebpackPlugin
pour qu'il fonctionne correctement.
/* webpack.common.js */new PreloadWebpackPlugin({ rel: 'précharger', as(entry) {if (/.(woff|woff2|ttf|otf)$/.test(entry)) return 'font'; }, fichierWhitelist : [/.(woff|woff2|ttf|otf)$/], inclure : 'allAssets'}),
Nous voilà de retour dans la configuration webpack.prod.js
utilisant le compression-webpack-plugin pour compresser uniquement les fichiers html, css et javascript. Cela permet d'éviter de compresser les fichiers sourcemap générés.
/* webpack.prod.js */module.exports = merge(common, { mode : 'production', plugins : [new CompressionPlugin({ test: /.(html|css|js)(?.*)?$/i // uniquement compressé html/css/js, ignore la compression des sourcesmaps, etc.}),});
Clean-webpack-plugin est juste un simple plugin webpack pour supprimer/nettoyer votre (vos) dossier(s) de construction avant d'en créer un nouveau. Surveillez l'examen de votre dossier pendant que vous exécutez npm run build
ou npm start
. Votre dossier dist
actuel (si vous en avez déjà créé un) sera supprimé et un nouveau apparaîtra immédiatement après.
/* webpack.common.js */const CleanWebpackPlugin = require("clean-webpack-plugin");plugins : [new CleanWebpackPlugin(["dist"])];
L'utilisation de sourcesmaps est essentielle pour déboguer votre code dans les outils de développement.
Comme vous pouvez le voir lorsque vous npm start
et ouvrez les outils de développement dans Chrome, puis cliquez sur la console, vous verrez qu'il y a deux console.logs provenant des lignes 1 et 2 script.js
Nous pouvons facilement le voir dans notre structure de dossiers à l'adresse src/scripts/script.js
. Si nous n'utilisions pas de sourcemaps, les outils de développement nous montreraient que ces console.logs proviennent de notre webpack-bundle.js
fourni, ce qui n'est pas très utile.
Cas similaire avec nos styles. Si vous jetez un œil à l'élément body
dans devtools, vous verrez certains styles appliqués à partir de notre fichier _global.scss
, et d'autres à partir de notre fichier _typography.scss
, qui se trouvent tous deux dans notre dossier src/styles/base/
. Nous ne pourrions pas le savoir si nous oubliions les sourcesmaps. Cela nous montrerait simplement les styles provenant de notre webpack-bundle.css
fourni.
/* webpack.dev.js */module.exports = merge(common, { mode : "développement", outil de développement : "inline-source-map",});
/* webpack.prod.js */module.exports = merge(common, { mode : "production", outil de développement : "source-map",});
Apprenez-en davantage sur les différents types de sourcesmaps pour trouver ce qui fonctionne le mieux pour votre projet. Lisez également l'option devtool dans la documentation du webpack.
Il s'agit d'un excellent plugin qui génère chaque icône dont vous aurez besoin en fonction d'une seule source d'image. Dans mon dossier src/images/
j'ai un tris-package.svg
que je saisis dans le plugin favicons-webpack-plugin.
Il générera des icônes pour Apple, Android, Chrome, Firefox, Twitter, Windows, etc. Il générera chaque icône dans toutes les tailles différentes et les importera directement dans la tête de votre site Web à laquelle elles appartiennent. Twitter et Windows sont définis sur false mais par défaut, je les ai donc modifiés en true juste pour couvrir toutes les bases, au cas où.
Remarque : cela augmente considérablement le temps de construction. Ce qui est compréhensible compte tenu de tout ce qu’il fait sous le capot et du temps qu’il vous fait gagner à long terme. Ne soyez pas surpris si votre npm run build
prend 20 secondes de plus que d'habitude.
/* webpack.prod.js */const FaviconsWebpackPlugin = require("favicons-webpack-plugin");module.exports = merge(common, { mode : "production", plugins : [nouveau FaviconsWebpackPlugin({ logo : "./src/images/favicon.svg", icônes : {twitter : true,windows : true, },}), ],});
Ici, nous utilisons le plugin plugin hors ligne pour mettre en cache tous nos actifs lors du chargement de la page.
Ce plugin est destiné à fournir une expérience hors ligne pour les projets Webpack . Il utilise ServiceWorker et AppCache comme solution de secours sous le capot. Nous incluons simplement ce plugin dans notre webpack.prod.js
et le runtime qui l'accompagne dans notre script client (src/index.js), et notre projet deviendra prêt hors ligne en mettant en cache tout (ou certains) des actifs de sortie du webpack.
Remarque : Si vous npm run build
et téléchargez vos modifications sur votre serveur (ou si vous maintenez votre site Web à jour), votre site Web devra avoir été fermé et rouvert avant de voir les modifications. Vous ne pouvez pas l'ouvrir et continuer à l'actualiser, vous devez fermer l'onglet et le rouvrir pour que le cache explose.
/* webpack.prod.js */const OfflinePlugin = require("offline-plugin");module.exports = merge(common, { mode : "production", plugins : [nouveau OfflinePlugin()],});
Les applications Web progressives (PWA) sont des applications Web qui se chargent comme des pages Web ou des sites Web classiques, mais peuvent offrir à l'utilisateur des fonctionnalités telles que le travail hors ligne, les notifications push et l'accès au matériel de l'appareil traditionnellement disponible uniquement pour les applications natives. Les PWA combinent la flexibilité du Web avec l’expérience d’une application native.
La dernière étape pour faire de ce passe-partout une PWA consiste à ajouter le manifeste d'application Web obligatoire à la racine de votre projet et à le configurer de manière appropriée !
Webpack rencontre des problèmes lorsqu'il tente de regrouper de grandes bibliothèques comme jQuery. Vous vous retrouverez avec des erreurs de console telles que $ is not defined
ou jQuery is not defined
. Pour résoudre ce problème, nous laissons Webpack le traiter comme un externe. Nous définissons ensuite les variables et incluons jQuery via un CDN. Quoi qu'il en soit, la plupart des gens ont jQuery mis en cache sur leur navigateur, ce ne sera donc pas un problème en termes de performances. J'ai ajouté la configuration externals:
par défaut, mais vous devrez ajouter le cdn jQuery par vous-même si vous envisagez de l'utiliser.
En savoir plus sur les externes dans la documentation Webpack.
/* webpack.common.js */plugins : [],externals : { $ : 'jquery', jquery : 'jQuery', 'fenêtre.$' : 'jquery',}
/* src/index.html */<head> <scriptdefersrc="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js" ></script></head>
Je fais de mon mieux pour expliquer les choses en détail, mais si quelque chose peut être expliqué plus clairement, n'hésitez pas à envoyer une pull request avec quelques suggestions de modifications. Merci!
J'espère que cela a aidé ! Suivez-moi sur Twitter si ça vous intéresse. ?