Cómo configurar nuestros proyectos para trabajar con Webpack, Babel 7, ESLint y Prettier

Webpack: Configuración Básica

Para configurar un proyecto preparado para trabajar con javascript “moderno”, tenemos que crear nuestro package.json, instalar una serie de dependencias y configurar webpack para poder importar módulos JS ES2015 y lanzar nuestro servidor local que se recargará automáticamente cuando grabemos.

Ideas Claras

  • Para crear nuestro package.json vacio hacemos npm init -y
  • Para instalar webpack y añadirlo como dependencia al package.json hacemos npm i -S webpack

package.json básico

Utilizaremos este package.json básico para empezar a trabajar

{
  "name": "starter-project",
  "version": "1.0.0",
  "description": "## Packages Webpack",
  "main": "index.js",
  "scripts": {
    "build": "rimraf dist && webpack --progress",
    "server": "webpack-dev-server --inline --progress"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "html-webpack-plugin": "^2.30.1",
    "rimraf": "^2.6.2",
    "webpack": "^3.8.1",
    "webpack-dev-server": "^2.9.4",
    "webpack-cli": "^3.2.1"
  }
}

Las dependencias instaladas son:

  • html-webpack-plugin → Nos permite añadir automáticamente el bundle creado con webpack a un .html (lo utilizamos en el webpack.config.js)
  • rimraf → Para eliminar archivos desde node (lo utilizamos en los scripts del package.json)
  • webpack → El bundler de módulos que utilizaremos. Nos permite manejar todas nuestras dependencias desde JS y se encarga de generar un bundle.js final con todo (lo utilizamos en los scripts del package.json)
  • webpack-dev-server → Sirve una app webpack y actualiza el navegador cuando detecta cambios en los archivos (lo utilizamos en los scripts del package.json)
  • webpack-cli → Proporciona el comando webpack para poder utilizarlo desde linea de comandos (o en los scripts del package.json)

webpack.config.js básico

Utilizaremos este webpack.config.js básico para empezar a trabajar

const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: "./src/app/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js"
  },
  new HtmlWebpackPlugin({ template: './src/index.html' }),
  devServer: {
    contentBase: "./src/public"
  }
};

Las propiedades configuradas son:

  • entry → El punto de entrada de nuestra app desde el cual se empezaran a “rastrear” los módulos
  • output → La carpeta y el nombre del archivo donde se generará nuestra app
  • plugins → Los plugins de webpack que aplicamos al generar nuestro bundle
  • devServer → La ruta desde la cual arrancará nuestro servidor local (y donde estatá nuestro index.html)

Añadimos también un index.html base en src

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title Page</title>
  </head>
  <body>

  </body>
</html>

webpack.config.js preparado para carga de módulos JS ES2015

Instalamos los módulos que necesitamos con

npm i -S  \
  @babel/core \
  babel-loader

Añadimos la propiedad module para definir las rules con las que configuraremos diferentes loaders para diferentes tipos de assets

De entrada sólo preparamos webpack para cargar JS ES2015 con babel-loader

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

Webpack: CSS con Webpack y StandardJS con prettier en Visual Code

Ahora vamos a añadir más loaders (css y html) y a configurar webpack para que genere un styles.css aparte para nuestros css cargados mediante webpack

Además configuraremos nuestro proyecto y el editor Visual Code (que te recomiendo) para que nos chequee y nos aplique automáticamente un standard de formato de código javascript muy popular llamando StandardJS

Añadiendo Loaders para cargar CSS/HTML desde JS

Instalamos los módulos que necesitamos con

npm i -S \
  css-loader \
  raw-loader \
  style-loader \
  extract-text-webpack-plugin

Añadimos las nuevas rules con su respectiva configuración de loaders y nuevos plugins.

webpack.config.js

const ExtractTextPlugin = require('extract-text-webpack-plugin')

...

module: {
  rules: [
    {
      test: /\.js$/,
      use: "babel-loader",
      exclude: /node_modules/
    },
    {
      test: /\.css$/,
      use: ExtractTextPlugin.extract({
        fallback: "style-loader",
        use: "css-loader"
      })
    },
    {
      test: /\.html$/,
      use: "raw-loader"
    }
  ]
},
plugins: [
  new HtmlWebpackPlugin({ template: "./src/index.html" }),
  new ExtractTextPlugin("styles.css")
],

Los loaders añadidos son:

  • style-loader y css-loader → Para poder cargar css desde javascript
  • raw-loader → Para cargar archivos de texto (por ejemplo para cargar el contenido de .html externos)

El plugin añadido es:

  • extract-text-webpack-plugin → Nos permite extraer parte del bundle en un archivo aparte (lo utilizaremos para separar los css en un styles.css aparte)

Activando ultimas características de Javascript con Babel

Babel es la herramienta que utilizamos para transpilar (traducir un código a otro código) código ES2015 a ES5. Cómo hay muchas features del lenguaje propuestas que aún no forman parte del standard, se utilizan los llamados presets y plugins para indicar a nuestro babel qué tipo de características de JS queremos utilizar en nuestro proyecto.

La última versión de Babel (la 7) ya trae un montón de novedades

Además, vamos a añadir el preset preset-env que permite optimizar el código genrado por babel en base a los browsers “target”.

Sin ninguna configuración, este preset se comporta igual que babel-preset-latest (o lo que es lo mismo, que babel-preset-es2015, babel-preset-es2016, and babel-preset-es2017 juntos)

Así que instalamos este módulo con npm i -S @babel/preset-env

Y creamos un archivos .babelrc con el que le indicamos a babel qué caracteristicas de Javascript queremos utilizar en nuestro proyecto

.babelrc

{
  "presets": ["@babel/preset-env"]
}

Configurando eslint & prettier con Visual Code para aplicación automática de javascript standard

ESLint es un “chequeador” de estilos que podemos aplicar a nuestro workflow de manera que podamos comprobar automáticamente si nuestro código sigue una determinada guía de estilos

Las normas (normalmente predefinidas ya en módulos NPM) que queremos que cumpla nuestro código las podemos definir en un .eslintrc que utilizará eslint para chequear nuestro código

En nuestro caso vamos a indicarle a eslint que tenga en cuenta las configuraciones de babel y que además chequee que nuestro código sigue el estilo standardJS

Para aplicar este check automáticamente instalamos un formateador de código llamado prettier a través del cual podremos aplicar automáticamente estos estilos desde nuestro editor

Asi que instalamos nuestras dependencias…

  npm i -S \
    babel-eslint \
    eslint-config-standard \
    eslint-plugin-import \
    eslint-plugin-node \
    eslint-plugin-promise \
    eslint-plugin-standard \
    prettier-eslint

Creamos y configuramos el .eslintrc

{
  "parser": "babel-eslint",
  "extends": [
    "standard"
  ]
}

Y añadimos la configuración correspondiente en Visual Code desde User Settings Visual Code

{
  ...
  "prettier.eslintIntegration": true
  ...
}

Extras

script-ext-html-webpack-plugin

Podemos instalar script-ext-html-webpack-plugin para mejora el plugin html-webpack-plugin y especificar atributos (como defer) al tag <script> de carga del bundle (lo utilizamos en el webpack.config.js)

Lo instalamos con npm i -D script-ext-html-webpack-plugin Y lo añadimos a plugins en nuestro webpack.config.js

 plugins: [
        ...,
        new ScriptExtHtmlWebpackPlugin({
            defaultAttribute: 'defer'
        })
    ],

Añadir source maps

También podemos configurar nuestro webpack.config.js para añadir source maps con devtool

Así cuando pongamos debugger veremos nuestro código original y no el transpilado por babel

module.exports = {
  entry: ...,
  output: ...,
  module: ...,
  plugins: ...,
  ...
  devtool: 'source-map'
}
Published 26 Jan 2019

Hola, soy JuanMa! En este blog iré compartiendo notas y descubrimientos relacionados con Javascript
Apuntes de JS on Twitter