Até o momento vimos dois posts de introdução ao Webpack, nesse post iremos implementar linters em nosso código JavaScript, se você nunca ouviu falar em linting tools, elas são ferramentas de optimização de código, elas nos ajudam a escrever o código organizado e com boas práticas. Mas isso não significa que iremos prevenir bugs, mas a diferença que teremos um código fácil de debugar em em grandes times teremos uma estilo único de desenvolvimento.

Junto ao linters responsáveis pela validação básica podemos integra-los com guias de desenvolvimento, eles utilizam um conjunto padrões de desenvolvimento para realizar uma validação mais restrita, com isso tempos uma melhor manutenção do nosso código. No mercado front-end temos guias específicos para JavaScript e CSS, muitos guias de CSS estão atrelados a guias visuais, mas também podemos encontrar guias para automatização de validação CSS com Webpack e os principais Guias de estilo do mercado são:

Guias JavaScript

Guias CSS/LESS/SASS +HTML

  • Fractal – é uma biblioteca de components com style guide tempos alguns plugins de integração com webpack.
  • Airbnb CSS / SASS Style guide – contém regras de declaração, seletores, formatação, comentários, entre outras regras específicas para SASS
  • Indiomatic CSS Principles – contém regras gerais, whitespace, comentários, formatação e uma série de exemplos práticos.
  • Stylelint Config Standard – essa configuração extends da configuração recomendada e aplica um regra de uma série de guias

Por que utilizar Guia de padrão de desenvolvimento ?

Já abordarmos algumas vantagens mas vale a pena revisar:

  • Ajuda na prevenção de erros
  • Formatação automática em alguns casos
  • Padronização de desenvolvimento
  • Facilidade de manutenção de código
  • Fácil configuração, uma vez definido o estilo você poderá compartilhar a mesma configuração com o seu time
  • Incentivo a boas práticas de desenvolvimento

Ok, Já entendi agora como eu utilizo esses guias com Webpack?

Esse tutorial vamos continuar o trabalho dentro do repositório utilizado nos posts anteriores e implementar a validação do nosso código JavaScript, agora vamos criar uma nova branch chamada step-10 para realizarmos os primeiros passos. Inicialmente vamos instalar utilizando nosso terminal o eslint e eslint-loader em nosso projeto, eles serão os pacotes responsáveis pela validação do nosso código EcmaScript:

npm install eslint-loader eslint --save-dev

Após a instalação dos pacotes precisamos configurar o nosso eslint, podemos criar o nosso arquivo de configuração “.eslintrc” manualmente ou utilizar o terminal para instalação, para facilitar o nosso processo vamos utilizar o terminal, para isso executamos o seguinte comando em nosso terminal:

eslint --init

Quando executamos o comando anterior nosso terminal irá realizar uma série de perguntas que serão elas:

  • Como você gostaria de configurar ESLint?
    R. Usando um style guide popular
  • Qual style guide você gostaria de seguir
    R. Airbnb
  • Você usa React?
    R. No
  • Qual o formato que você quer o seu config file?
    R. JavaScript
  • Você gostaria de instalar as dependências necessárias?
    R. Y(sim)

Feito isso, o arquivo .eslintrc será criado com o seguinte código:

module.exports = {
    "extends": "google"
};

Agora que nos temos o eslint instalado e configurado vamos, inclui-lo em nosso webpack.config.js:

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env'],
            },
          },
          'eslint-loader',
        ],
      },
      {
        test: /\.(sa|sc|c)ss$/,
        exclude: /(node_modules|bower_components)/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader',
        ],
      },
      {
        test: /\.(svg|gif|png|jpe?g)$/,
        loader: 'url-loader',
        options: {
          limit: 100,
          fallback: 'file-loader',
          publicPath: '/img',
          outputPath: '/img',
        },
      },
    ],
  },
};

Este é o arquivo de configuração utilizado nos posts anteriores, incluímos o eslint-loader em nossas regras de leitura para arquivos JavaScript ele agora irá trabalhar em conjunto com o babel loader.

Rodando o webpack novamente se tudo ocorrer bem teremos o seguinte retorno:

Nosso lint irá começar a validar o nosso código

Lendo os nossos errors e warnings um ponto de atenção para o document. O eslint não reconhece document porque não especificamos qual ambiente estamos desenvolvendo, para isso vamos fazer uma alteração em nosso arquivo .eslintrc:

module.exports = {
    "extends": "airbnb-base",
    "env" : {
        "browser": true,
    }
};

Com essa nova propriedade “env” definimos browser como true, agora o eslint passará considerar que nosso será escrito para browsers. Podemos também especificar que nosso código irá rodar em servidores node.

Rodando nosso código novamente:

Ainda temos alguns erros e warnings podemos resolver de duas maneiras manualmente ou como um autofix, para realizar a correção automática você pode realizar via terminal ou através de configurações no webpack.config.js adicionando opções ao nosso eslint-loader da seguinte forma:

{
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env'],
            },
          },
          {
            loader: 'eslint-loader',
            options: {
              fix: true,
            },
          },
        ],
      },
Depois de rodar webpack com autofix temos os seguintes alertas relacionados ao nosso console.log

Podemos remover o console.log do nosso código essa é uma ação recomendada, imagina você enviar um código em produção cheio de console log, no Webpack podemos definir qual será o modo que iremos trabalhar “development” ou “production” partindo desse princípio podemos. Iremos criar uma condicional em nosso webpack.config quando executarmos o nosso código para produção iremos disparar alertas para remover os console.log de nosso código.

Para essa etapa iremos trabalhar na branch step-11, primeira mudança vamos incluir dois scripts em nosso package.json:

{
  "name": "webpack-tutorial",
  "version": "1.0.0",
  "description": "Webpack tutorial",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev" : "webpack --watch --mode=development",
    "build" : "webpack --mode=production"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/fellyph/webpack-tutorial.git"
  },
  "keywords": [
    "tutorial",
    "webpack"
  ],
  "author": "fellyph",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/fellyph/webpack-tutorial/issues"
  },
  "homepage": "https://github.com/fellyph/webpack-tutorial#readme",
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/preset-env": "^7.3.1",
    "babel-loader": "^8.0.5",
    "css-loader": "^2.1.0",
    "eslint": "^5.15.1",
    "eslint-config-airbnb-base": "^13.1.0",
    "eslint-config-google": "^0.12.0",
    "eslint-loader": "^2.1.2",
    "eslint-plugin-import": "^2.16.0",
    "file-loader": "^3.0.1",
    "node-sass": "^4.11.0",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.1",
    "url-loader": "^1.1.2",
    "webpack": "^4.29.0",
    "webpack-cli": "^3.2.1"
  }
}

Agora temos dois novos scripts dev e build, eles incluem o modo que iremos exportar modo de produção irá criar um código minificado sem source map já o código gerado para desenvolvimento terá recursos que irão facilitar o debug de nosso código.

Quando quisermos exportar a versão de desenvolvimento executamos em nosso terminal o comando:

npm run dev

Ele irá executar o comando “webpack –watch –mode=development” assim executaremos o webpack no modo desenvolvimento ainda inclui mais um parâmetro “–watch” para o webpack ficar assistindo todas as mudanças dentro do projeto assim só precisamos rodar o nosso código uma vez. Para exportar nosso script de produção rodamos o comando:

npm run build

Agora com esses dois novos recursos vamos fazer as seguinte alteração em nosso webpack.config:

const path = require('path');

module.exports = (env, options) => ({
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env'],
            },
          },
          {
            loader: 'eslint-loader',
            options: {
              fix: true,
              rules: {
                'no-console': (options.mode === 'development') ? 'off' : 'warn',
              },
            },
          },
        ],
      },
      {
        test: /\.(sa|sc|c)ss$/,
        exclude: /(node_modules|bower_components)/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader',
        ],
      },
      {
        test: /\.(svg|gif|png|jpe?g)$/,
        loader: 'url-loader',
        options: {
          limit: 100,
          fallback: 'file-loader',
          publicPath: '/img',
          outputPath: '/img',
        },
      },
    ],
  },
});

Temos várias maneiras de verificar se estamos criando código para produção ou desenvolvimento, no caso acima converti module.exports de um objeto para uma função para resgatar o mode dentro das opções definidas em nosso código executado no terminal.

Dentro das opções eslint-loader adicionamos uma condicional para saber se vamos desligar o alerta para o console.log, este é um exemplo para uma regra especifica mas podemos colocar qualquer regra dentro dessa condicional todas as regras você pode conferir nesse link

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *