Iniciar un proyecto nuevo con npm
npm init -y
Instalar webpack
npm install webpack webpack-cli -D
Indicarle a npm que debe compilar usando webpack
En el archivo package.json en la propiedad scripts se debe indicar a npm que debe usar webpack cuando complie
"scripts": {
"build":"webpack",
"test": "echo \"Error: no test specified\" && exit 1"
}
Webpack y sus valores de compilación por defecto
Cuando ejecutamos
npm run build webpack trae preconfigurado que debe buscar en la carpeta src y compilar el archivo index.js como punto de entrada, asi mismo tambien trae preconfigurado que el resultado de la compilación debe dejarlo en la carpeta dist, si no existe el la crea, tambien trae preconfigurado el modo de compilación production, tiene dos production o development y tambien trae preconfigurado que el archivo resultado de la compilación se llamara main.js; todos estos valores se pueden cambiar
Conceptos clave de Webpack que se iran revisando en detalle mas adelante
Entrypoint:
Es el punto de entrada de la aplicación
Se le debe indicar a webpack cual es el punto de entrada de la aplicación, el por defecto tiene configurado index.js
Output
Por defecto Webpack crea una carpeta dist y dentro un archivo main.js que contiene el codigo fuente de todas las dependencias usadas armando un grafo desde index.js
Loaders
Son como tuneles o transformadores o transpiladores, que transforman sintaxis a otra sintaxis, i.e:
- El loader de babel para transformar jsx a javascript
- El loader de sass para transformar de sass a css
- Cada vez que hacemos un import pasa por un loader
Loaders y presets
Los presest son reglas preestablecidas para que se pueda hacer una configuración u otra, al final son plugins, ej: el loader de babel con el preset de react una de las transformaciones que trae es la del jsx
Plugins
Ejecuta código en diferentes puntos de ejecución de Webpack
Indicarle a Webpack que compile en modo desarrollo o producción
En el nodo scripts del archivo
package.json puedes definir varios modos de empaquetar la aplicación
"scripts": {
"build": "webpack --mode production",
"dev": "webpack --mode development",
"test": "echo \"Error: no test specified\" && exit 1"
},
Para compilar en modo desarrollo o producción se usa la siguiente sintaxis de npm
npm run dev
npm run build
Y lo anterior para que sirve, bueno para indicarle a Webpack si debe o no optimizar el paquete que va a generar, con optimizar me refiero a si lo minifica entre otras técnicas de optimización que seguro tiene y no conozco por ahora, con dev Webpack no optimiza el paquete generado con build si
Hacer que Webpack compile cuando detecta un cambio
En el archivo package.json, si le agregas --watch a build o dev puedes conseguir esto
"scripts": {
"build": "webpack --mode production --watch",
"dev": "webpack --mode development --watch",
"test": "echo \"Error: no test specified\" && exit 1"
},
Pero no es muy optimo
Antes de ver loaders y plugins crea este archivo
Para configurar los loader y plugins debes crear primero un archivo con el nombre
webpack.config.js al mismo nivel de package.json
Configurar un loader, por ejemplo el de babel para React
Debes instalar previamente el core de babel, el loader y el preset, la -D indica que son dependencias de desarrollo
npm install @babel/core babel-loader @babel/preset-react -D
En el archivo webpack.config.js configurarlo de la siguiente manera:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react']
}
}
}
]
}
}
En este objeto le estamos diciento a webpack lo siguiente:
- module: Carga este modulo
- rules: Este modulo que estas cargando tiene las siguientes reglas
- test: /\.js$/ Debes ejecutarlo en todos los archivos .js
- excludes: /node_modules/ Excluye la carpeta node_modules
- use: Lo que usaran para ejecutarlo
- loader: 'babel-loader' Usaras el loader de babel
- options: Con las siguientes opciones
- presets: ['@babel/preset-react'] Usaras la configuración preestablecida de react, esta configuración dentro de muchas cosas que tiene, tiene la configuración para el transpilador de JSX a Javascript
En otras palabras Webpack le enviara todos los archivos .js al transformador babel-loader, exluyendo todo lo que encuentre en la carpeta node_modules, lo que se espera es que babel-loader con el preset de react, identifique y transforme la sintaxis JSX de cada archivo en sintaxis javascript que el navegador pueda interpretar
Cambiando el nombre al archivo output y colocandole un hash al nombre
En ocasiones queremos cambiar el nombre main.js que genera por defecto webpack en el output y también a veces queremos que al nombre le agregue una especie de hash, esto con el fin de que cuando publiquemos, evitar la cache del navegador y que nuestros usuarios tengan la versión mas actualizada de nuestra aplicación
En el archivo webpack.config.js debemos agregar output y adicionando [contentHash], WebPack cuando compila allí le agrega un hash.
module.exports = {
output: {
filename: 'app[contentHash].js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react']
}
}
}
]
}
}
Al cambiar el nombre y adicionar un hash debemos ajustar la referencia en el archivo index.html, a continuación veremos como hacer para que webpack haga el ajuste automáticamente por medio del plugin HTMLWebpackPlugin
Utilizando el plugin HTML Webpack Plugin
Vamos a usar este plugin para que cuando cambiemos el nombre del archivo output, se ajusten las referencias en el archivo index.html automáticamente
Instalar el plugin
npm i --save-dev html-webpack-plugin
En el archivo
webpack.config.js se debe agregar una constante del HTML Webpack Plugin y luego adicionarlo a la propiedad plugins del modulo
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
output: {
filename: 'app[contentHash].js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react']
}
}
}
]
},
plugins:[
new HtmlWebpackPlugin()
]
}
Cuando corres npm run dev, notamos que en la carpeta dist, webpack genero el archivo index.html y tambien el app[hashContent], pero notamos que el archivo index.html no es el nuestro el que teniamos en desarrollo y esto es porque el plugin usa una plantilla por defecto si no se le indica alguna y como no la hemos indicado por eso genero la plantilla que tiene por defecto; a continuación vamos a configurar la nuestra.
Configurando la plantilla que usara HtmlWebpackPlugin
En el archivo
webpack.config.js en la sección plugins se indica en titulo y el template html que usara el plugin
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
output: {
filename: 'app[contentHash].js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react']
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin(
{
title: "Webpack paso a paso",
template: "src/index.html"
}
)
]
}
Ya con esto, cada vez que se compile, Webpack generara el archivo index.html de acuerdo a la plantilla, generara el archivo .js indicando el hash y inyectara la ruta correcta automáticamente
Referencia:
Todo esto lo aprendí de Midudev
https://www.youtube.com/watch?v=ansUGkcrhwY&t=3004s