Configurar Webpack 5 desde cero





Aprenda a usar el paquete web para crear JavaScript, imágenes, fuentes y estilos, y cómo ejecutar el



servidor de desarrollo . Si ha usado el paquete web 4 antes, estas son algunas de las diferencias con la versión 5:



  • el comando "webpack-dev-server" ahora se parece a "webpack-serve"
  • ya no se requiere la instalación separada de file-loader, raw-loader y url-loader, puede usar los módulos de activos integrados
  • Node.js , , , stream, «stream-browserify» { stream: «stream-browserify» }


?



En su mayor parte, los sitios ya no se escriben en HTML puro con poco JavaScript; a menudo, solo se crean con JavaScript. Por lo tanto, es necesario compilar, minificar y transpilar el código. Aquí es donde el paquete web resulta útil.



Webpack es un constructor de módulos. Se utiliza para empaquetar el código para que lo utilice el navegador. Le permite aprovechar las últimas funciones de JavaScript con Babel, o usar TypeScript y compilarlo en código minificado entre navegadores. También le permite importar recursos estáticos a JavaScript.



Para los desarrolladores, el paquete web también proporciona un servidor de desarrollo que puede actualizar módulos y estilos sobre la marcha cuando se guarda el archivo. Las herramientas de línea de comandos como "vue create" y "react-create-app" utilizan el paquete web entre bastidores, pero puede crear fácilmente su propia configuración de paquete web para los marcos mencionados.



Webpack también puede hacer muchas otras cosas, pero este artículo cubrirá los conceptos básicos para configurarlo y usarlo.



Instalación



Cree un directorio de proyecto e inicialícelo:



mkdir webpack-tutorial
cd !$
// 
cd webpack-tutorial
yarn init -yp  //     "package.json"
// 
npm init -y


Instale webpack y webpack-cli como dependencias de desarrollo:



yarn add -D webpack webpack-cli
// 
npm i -D webpack webpack-cli




Cree un directorio "src" para almacenar los archivos de la aplicación. Comenzaré creando un archivo "index.js" simple:



console.log(" !")


Genial, tenemos un proyecto Node.js con los paquetes principales instalados y un archivo "index.js". Comencemos a configurar el paquete web.



Configuración básica



Comencemos a configurar el recopilador. Cree un archivo "webpack.config.js" en el directorio raíz del proyecto.



Punto de entrada


En primer lugar, debe definir el punto de entrada de la aplicación, es decir qué archivos compilará el paquete web. En el ejemplo anterior, definimos el punto de entrada como "src / index.js":



// webpack.config.js
const path = require('path')

module.exports = {
    entry: {
        main: path.resolve(__dirname, './src/index.js'),
    },
}


Punto de salida


El punto de salida es el directorio donde se colocan los archivos compilados por el paquete web. Establezcamos el punto de salida en "dist". El prefijo "[nombre]" coincide con el nombre del archivo en src:



// webpack.config.js
module.exports = {
    // ...

    output: {
        path: path.resolve(__dirname, './dist'),
        filename: '[name].bundle.js',
    },
}


La configuración mínima para construir el proyecto está lista. Agregue el script "build" al archivo "package.json" que ejecuta el comando "webpack":



// package.json
"scripts": {
    "build": "webpack"
}


Inicie el paquete web:



yarn build
// 
npm run build


asset main.bundle.js 19 bytes [emitted] [minimized] (name: main)
./src/index.js 18 bytes [built] [code generated]
webpack 5.1.0 compiled successfully in 152 mss


El archivo "index.bundle.js" se crea en el directorio "dist". El archivo no ha cambiado, pero hemos construido el proyecto con éxito.



Complementos



La interfaz del complemento hace que el paquete web sea muy flexible. Los complementos son utilizados tanto por el paquete web como por extensiones de terceros. Algunos complementos se utilizan en casi todos los proyectos.



Complemento basado en plantillas HTML


Tenemos un ensamblado listo para usar, pero es inútil sin marcado, que cargará el ensamblaje como un script. Como queremos que dicho archivo HTML se genere automáticamente, usamos el complemento html-webpack-plugin.





Instale el complemento:



yarn add -D html-webpack-plugin


Cree un archivo "template.html" en el directorio "src". Podemos agregar variables y otra información a la plantilla. Agregue la variable "título"; de lo contrario, la plantilla se verá como un archivo HTML normal con un contenedor con el identificador "raíz":



<!-- src/template.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>

  <body>
    <div id="root"></div>
  </body>
</html>


Agrega la propiedad "plugins" a la configuración del paquete web, donde definimos el plugin, el nombre del archivo de salida (index.html) y la plantilla:



// webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    // ...

    plugins: [
        new HtmlWebpackPlugin({
            title: 'webpack Boilerplate',
            template: path.resolve(__dirname, './src/template.html'), // 
            filename: 'index.html', //   
        }),
    ],
}


Iniciamos el montaje. El directorio "dist" ahora contiene el archivo "index.html" con el script incluido en él. ¡Frio! Si abre este archivo en un navegador, verá el mensaje "¡Qué interesante!" en la consola.



Agreguemos algo de contenido al DOM. Cambiemos el contenido del archivo "index.js" y reiniciemos el ensamblaje.



// index.js
//   
const heading = document.createElement('h1')
heading.textContent = ' !'

//    DOM
const root = document.querySelector('#root')
root.append(heading)


Vaya al directorio "dist" e inicie el servidor (para esto necesita instalar globalmente http-server : yarn global add http-server o npm i -g http-server).



http-server


En la pestaña del navegador que se abre, debería ver un título que dice "¡Qué interesante!" También tenga en cuenta la reducción del tamaño del archivo.



Limpieza


Instale el plugin clean-webpack-plugin, que limpia el directorio "dist" cada vez que se crea el proyecto. Esto le permite eliminar automáticamente los archivos antiguos que ya no son necesarios.





// webpack.config.js
const HtmlWebpackPlugin = require('html=webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')

module.exports = {
    // ...

    plugins: [
        // ...
        new CleanWebpackPlugin(),
    ],
}


Módulos y cargadores



El paquete web utiliza cargadores para analizar archivos cargados por módulos . Estos pueden ser archivos JavaScript, recursos estáticos como imágenes o estilos y compiladores como TypeScript y Babel. Webpack 5 tiene varios cargadores de recursos integrados.



Nuestro proyecto tiene un archivo HTML que carga algún script, pero no hace nada más. Pensemos en lo que queremos del coleccionista.



  • Compile las últimas funciones de JavaScript en un código que sea compatible con todos o la mayoría de los navegadores
  • Importación de estilos y conversión de SCSS a CSS
  • Importación de imágenes y fuentes
  • Configuración de React o Vue (opcional)


Primero, configuremos Babel para compilar JavaScript.



Babel (JavaScript)


Babel es una herramienta para habilitar JavaScript en el futuro hoy.



Vamos a definir una regla para que todos los archivos js de un proyecto (excepto los archivos contenidos en el directorio node_modules) se transpilen usando babel-loader. Babel requiere varias dependencias para funcionar:





yarn add -D babel-loader @babel/core @babel/preset-env @babel/babel-plugin-proposal-class-properties


// webpack.config.js
module.exports = {
    // ...

    module: {
        rules: [
            // JavaScript
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: ['babel-loader'],
            },
        ],
    }
}


Si está configurando un proyecto de TypeScript, debe usar mecanografiado-loader en lugar de babel-loader para todos los archivos JavaScript que necesitan transpilación. Está comprobando archivos con la extensión "ts" y utilizando ts-loader.



Así que Babel está configurado, pero el complemento aún no está disponible. Puede verificar esto agregando el siguiente código en la parte superior de index.js:



// index.js
//     
class Game {
    name = 'Violin Charades'
}
const myGame = new Game()

//  
const p = document.createElement('p')
p.textContent = `I like ${myGame.game}.`

//   
const heading = document.createElement('h1')
heading.textContent = ' !'

//      DOM
const root = document.querySelector('#root')
root.append(heading, p)


ERROR in ./src/index.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /Users/you/webpack-tutorial/src/index.js: Support for the experimental syntax 'classProperties' isn't currently enabled (3:8):

  1 | // Create a class property without a constructor
  2 | class Game {
> 3 |   name = 'Violin Charades'
    |        ^
  4 | }


Para solucionar este problema, cree un archivo ".babelrc" en la raíz del proyecto:



// .babelrc
{
  "presets": ["@babel/preset-env"],
  "plugins": ["@babel/plugin-proposal-class-properties"]
}


Comenzamos la construcción con la construcción de hilo. Todo funciona ahora.



Imagenes


Queremos importar imágenes a un archivo JavaScript, pero JavaScript no puede hacer esto. Para verificar esto, cree un directorio "src / images", ponga una imagen allí e intente importarla en el archivo "index.js":



// index.js
import example from './images/example.png'

// ...


Al iniciar la compilación, se lanzará una excepción:



ERROR in ./src/images/example.png 1:0
Module parse failed: Unexpected character ' ' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders


Como se señaló anteriormente, el paquete web tiene algunos descargadores integrados para manejar archivos estáticos. Para imágenes, use el tipo "activo / recurso". Tenga en cuenta que estamos hablando del tipo (tipo), y no del cargador (cargador):



// webpack.config.js
module.exports = {
    // ...

    module: {
        rules: [
            // 
            {
                test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
                type: 'asset/resource',
            },
        ],
    },
}


Aparece un nuevo archivo en el directorio "dist".



Fuentes y otros datos incrustados


El paquete web también tiene un módulo incorporado para manejar algunos datos incrustados, como fuentes y SVG. Para ello, basta con especificar el tipo "activo / en línea":



// index.js
import example from './images/example.svg'

// ...


// webpack.config.js
module.exports = {
    // ...

    module: {
        rules: [
            //   SVG
            {
                test: /\.(woff(2)?|eot|ttf|otf|svg|)$/,
                type: 'asset/inline',
            },
        ],
    },
}


Estilos


El uso de cargadores de estilo es un requisito previo para utilizar cadenas como "import 'file.css'" en su script.



Mucha gente usa CSS-in-JS , componentes con estilo y otras herramientas que permiten a JavaScript diseñar.



A veces podemos limitarnos a cargar un archivo CSS. Pero quizás desee utilizar PostCSS , que permite las últimas capacidades de CSS en el navegador. O desea utilizar el preprocesador Sass .



Quiero usar los tres: escribir código en Sass, procesarlo con PostCSS y compilarlo en CSS.





yarn add -D sass-loader postcss-loader css-loader style-loader postcss-preset-env node-sass


Al igual que con Babel, PostCSS requiere un archivo de configuración separado:



// postcss.config.js
module.exports = {
    plugins: {
        'post-css-preset-env': {
            browsers: 'last 2 versions',
        },
    },
}


Para probar la funcionalidad de las herramientas nombradas, creemos un archivo "src / styles / main.scss" que contenga variables Sass y un ejemplo de uso de PostCSS (lch):



// src/styles/main.css
$font-size: 1rem;
$font-color: lch(53 105 40);

html {
    font-size: $font-size;
    color: $font-color;
}


Importamos este archivo a index.js y agregamos 4 cargadores. El paquete web usa los cargadores de derecha a izquierda, por lo que el último debe ser sass-loader, luego PostCSS, luego CSS y finalmente style-loader, que aplica los estilos compilados a los elementos DOM:



// index.js
import './styles/main.css'

// ...


// webpack.config.js
module.exports = {
    // ...

    module: {
        rules: [
            // CSS, PostCSS, Sass
            {
                test: /\.(scss|css)$/,
                use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'],
            },
        ],
    },
}


Una vez construido, notará que Sass y PostCSS se han aplicado al DOM.



Tenga en cuenta que hemos establecido las preferencias para el modo de desarrollo. Para la producción, utilice MiniCssExtractPlugin en lugar de style-loader, que exporta CSS minificado.



Desarrollo de



Escribir yarn build (npm run build) cada vez para reconstruir el proyecto puede resultar tedioso. Cuanto más grande sea el proyecto, más tardará en construirse. Por lo tanto, debe tener dos archivos de configuración de paquete web:



  • Configuración de producción, incluida la minificación, optimización y eliminación de todos los mapas de recursos (mapas de origen)
  • Configuración de desarrollo, incluido el inicio del servidor, la actualización de cada cambio y los mapas de recursos


En lugar de crear un directorio "dist", el modo de desarrollo puede esperar almacenar la información que necesita en la memoria.



Para hacer esto, necesita instalar webpack-dev-server.





yarn add -D webpack-dev-server


Para demostrar cómo usar un servidor para el desarrollo, podemos definir la configuración apropiada en el archivo "webpack.config.js". En la práctica, es mejor tener dos archivos de configuración, uno con modo: producción y otro con modo: desarrollo. En el boilerplate webpack 5 especialmente preparado para usted, utilizo webpack-merge para obtener la configuración básica en un solo archivo, y los requisitos especiales están contenidos en los archivos "webpack.prod.js" y "webpack.dev.js".



// webpack.config.js
const webpack = require('webpack')

module.exports = {
    // ...
    mode: 'development',
    devServer: {
        historyApiFallback: true,
        contentBase: path.resolve(__dirname, './dist'),
        open: true,
        compress: true,
        hot: true,
        port: 8080,
    },
    plugins: [
        // ...
        //      
        new webpack.HotModuleReplacement(),
    ],
}


Hemos agregado el modo: desarrollo y una propiedad "devServer". Esta propiedad contiene varias configuraciones estándar: número de puerto (8080), apertura automática del navegador, uso de reemplazo de módulo en caliente , que requiere webpack.HotModuleReplacement (). Esto permitirá que los módulos se actualicen sin recargar la página completa, es decir, si los estilos individuales cambian, solo se actualizan, no es necesario volver a cargar JavaScript, lo que acelera enormemente el desarrollo.



Para iniciar el servidor, use el comando "webpack serve":



// package.json
"scripts": {
    "start": "webpack serve"
}


yarn start


Después de ejecutar este comando, el navegador se abrirá en localhost: 8080. Ahora puede modificar Sass y JavaScript y se actualizarán sobre la marcha.



Conclusión



Espero que este artículo te haya ayudado a comenzar con webpack. Para facilitarte la resolución de tus tareas diarias, desarrollé un boilerplate de webpack 5 con Babel, Sass, PostCss, optimización para producción y un servidor para desarrollo. Tomándolo como base, puede configurar fácilmente su paquete web para que funcione con React, Vue o TypeScript.



All Articles