Skip to content

undefinedschool/notes-webpack

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

5 Commits

Repository files navigation

Notas sobre Webpack

馃憠 Ver todas las notas

Intro

Webpack es un module bundler, su tarea es analizar el c贸digo de nuestra aplicaci贸n, detectar los diferentes m贸dulos que el mismo importa/exporta, aplicar (opcionalmente) las transformaciones necesarias y empaquetar todo el c贸digo en un 煤nico archivo .js y referenciarlo en el index.html, para que este pueda ser ejecutado en los browsers luego.

Bundling

Uno de los problemas que resuelve Webpack entonces, es la necesidad que ten铆amos previamente de linkear todos los scripts de librer铆as y m贸dulos que utiliz谩ramos en el index.html, en el orden correcto.

Los problemas que generaba esto eran:

  • dependencia de servidores de CDN (librer铆as)
  • problemas para el versionado: si queremos actualizar alguna librer铆a, tenemos que modificar manualmente los n煤meros de versiones en el src, lo que es poco pr谩ctico y propenso a errores
  • cargar los scrips en el orden incorrecto (si tienen dependencias entre si)
<!-- Linkeando scripts como antes -->
<body>
  ...
  <script src="libs/react.min.js"></script>
  <script src="src/admin.js"></script>
  <script src="src/api.js.js"></script>
  <script src="src/auth.js"></script>
</body>
<!-- Con Webpack -->
<body>
  ...
  <script src="dist/bundle.js"></script>
</body>

Transformaciones y optimizaciones

Aparte de resolver el problema del bundling, Webpack permite, a trav茅s de diferentes plugins y loaders, aplicar diferentes transformaciones (ej: transpilar TS, o c贸digo ES6+, agregar Babel, etc) y optimizaciones a nuestro c贸digo (ej: code splitting, image opt, etc).

Loaders

Por defecto, Webpack s贸lo puede analizar y procesar los archivos .js y .json de nuestro c贸digo. Probablemente necesitemos incluir estilos (CSS) e im谩genes. Es por este motivo que existen los loaders, que le permiten a Webpack procesar m谩s tipos de archivos, para realizar diferentes transformaciones, optimizaciones e incluirlos en el bundle final.

Para cada loader, tenemos que especificar sobre qu茅 archivos se va a aplicar (podemos usar regex).

Los loaders se instalan a trav茅s de npm, por ejemplo, para procesar SVGs y CSS

npm i -D svg-inline-loader css-loader

Si adem谩s queremos inyectar los estilos directamente en el DOM, podemos usar style-loader

npm i -D style-loader

Plugins

A diferencia de los loaders, que se utilizan para procesar y transformar archivos mientras generamos el bundle, los plugins le permiten a Webpack ejecutar ciertas tareas despu茅s de que el bundle fue creado. Por ejemplo, HtmlWebpackPlugin: genera un index.html, lo coloca en /dist (o en cualquier otro destino que definamos en output), agreg谩ndole un <script> tag que referencia al bundle creado. Otro plugin 煤til es EnvironmentPlugin, que nos permite configurar el entorno de producci贸n para el deployment.

Para agregar plugins, debemos instalarlos (al igual que los loaders) y setearlos en la propiedad plugins de la config

npm i -D html-webpack-plugin
// webpack.config.js
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  module: {
    rules: [ ... ]
  },
  output: { ... },
  plugins: [
    new HtmlWebpackPlugin(),
    new webpack.EnvironmentPlugin({
      'NODE_ENV': 'production'
    })
  ]
}

HMR

El Hot Module Replacement/Reloading permite agilizar el proceso de desarrollo, al dejarnos ver los cambios de forma instant谩nea en el browser, sin necesidad de refrescar el mismo. El mismo s贸lo estar谩 disponible en el entorno de desarrollo, no as铆 en producci贸n.

Setup

Instalar Webpack y su CLI como dependencias de desarrollo en el proyecto:

npm i -D webpack webpack-cli

Config

Crear el archivo webpack.config.js para guardar las opciones de configuraci贸n.

// webpack.config.js
module.exports = {
  entry: './src/index.js',
  module: {
    rules: [
      {
        test: /\.svg$/,          // aplicar esta transformaci贸n a todos los archivos .svg
        use: 'svg-inline-loader' // loader que vamos a usar
      },
      {
        test: /\.css$/,                       // aplicar esta transformaci贸n a todos los archivos .css
        use: [ 'style-loader', 'css-loader' ] //  en este caso usamos 2 loaders, por eso el array. El orden importa, webpack los procesa en orden inverso
      }
    ]
  }
}

En este archivo de config deberemos indicar cosas como:

  • entry point de nuestra app (definido en entry)
  • transformaciones que querramos aplicar (definidas en las rules dentro de module)
  • destino, con la ubicaci贸n del archivo empaquetado (definido en output)

Agregando el babel-loader para transpilar JS ES6+

npm i -D babel-loader
// webpack.config.js
module.exports = {
  entry: './src/index.js',
  module: {
    rules: [
      {
        test: /\.svg$/,          
        use: 'svg-inline-loader' 
      },
      {
        test: /\.css$/,                       
        use: [ 'style-loader', 'css-loader' ]
      {
        test: /\.(js)$/,         // aplicar esta transformaci贸n a todos los archivos .js
        use: 'babel-loader'
      }
    ]
  }
}

Finalmente, para agregar el destino, el output, que es un objeto con las siguientes propiedades

output: {
  path: ...     // ubicaci贸n de /dist, el directorio donde se va a ubicar el bundle
  filename: ... // nombre del bundle
}
// webpack.config.js
module.exports = {
  entry: './src/index.js',
  module: {
    rules: [
      {
        test: /\.svg$/,          
        use: 'svg-inline-loader' 
      },
      {
        test: /\.css$/,                       
        use: [ 'style-loader', 'css-loader' ]
      {
        test: /\.(js)$/,         // aplicar esta transformaci贸n a todos los archivos .js
        use: 'babel-loader'
      }
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index.bundle.js`
  }
}

tl;dr

  1. Webpack analiza el archivo definido como entry point
  2. Detecta y examina todos los imports/exports del mismo (o requires, si estamos usando CommonJS) y genera un dependency graph, para saber qu茅 m贸dulos dependen de cu谩les otros y en qu茅 orden debe insertarlos en el bundle final
  3. Comienza a crear el bundle y a medida que va agregando los scripts, aplica las transformaciones definidas en la config y agrega el output correspondiente
  4. Finalmente ubica el bundle final seg煤n output definido en la config

Dev & Production mode

Podemos realizar el proceso de preparar nuestro bundle para producci贸n (setear el NODE_ENV, minificar el c贸digo, etc) manualmente, en el caso de que querramos optimizar algo espec铆fico. Pero para simplificar y ahorrar tiempo, podemos usar el mode de la config y setearlo en production, que va a setear ciertos par谩metros por default (como los mencionados antes).

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

module.exports = {
  entry: './src/index.js',
  module: {
    rules: [ ... ]
  },
  output: { ... },
  plugins: [
    new HtmlWebpackPlugin()
  ],
  mode: process.env.NODE_ENV === 'production' ? 'production' : 'development'
}

El mode development de webpack deshabilita las optimizaciones mencionadas y activa el HMR para desarrollar localmente.

DevServer

El DevServer nos permite levantar un servidor local de desarrollo y carga los archivos en memoria, evit谩ndonos esperar a que se complete el build cada vez que guardamos cambios, para poder ver los mismos en el browser. Este m贸dulo adem谩s es el que incluye el HMR (live reloading). Para usarlo, lo instalamos con

npm i -D webpack-dev-server

Ejecutar Webpack desde los scripts

En nuestro package.json, agregamos los scripts de build (bundle optimizado para producci贸n) y dev (este 煤ltimo levanta un server local con HMR)

"scripts": {
  "build": "NODE_ENV='production' webpack",
  "dev": "webpack serve"
}

y luego lo corremos con npm run build.

M谩s info

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages