Shimming: o que é, abordagens e princípio de funcionamento

Autor: IT Sectr Publicado: 2026-05-19 Tempo de leitura: 8 min

Shimming é uma técnica para garantir a compatibilidade de módulos que esperam determinadas variáveis globais ou APIs. No ecossistema do Webpack, o shimming é implementado por meio do ProvidePlugin, imports-loader e exports-loader, permitindo conectar bibliotecas legadas sem alterar o código-fonte delas. Segundo a Webpack Documentation (2026), o shimming continua sendo uma ferramenta essencial para integrar plugins de jQuery e outras dependências que não suportam sistema modular.

Principais pontos

  • Shimming é uma técnica de substituição de variáveis globais e APIs para garantir a compatibilidade de módulos no build.
  • ProvidePlugin importa automaticamente um módulo ao detectar uma referência a uma variável global no código.
  • imports-loader e exports-loader gerenciam o escopo dos módulos, adicionando ou alterando suas interfaces.
  • Shim difere do polyfill porque não implementa funcionalidade ausente, mas redireciona chamadas existentes.
  • Webpack fornece mecanismos integrados de shimming sem a necessidade de instalar pacotes adicionais.

O que é Shimming?

Shimming é uma técnica de software que insere uma camada de compatibilidade entre o código e o ambiente sem alterar o código-fonte do módulo. No contexto do build de JavaScript, o shimming resolve o problema quando um módulo acessa variáveis globais (window.$, global.process) que não existem no ambiente modular.

Shim e polyfill: principais diferenças

Polyfill implementa a funcionalidade ausente do zero, adicionando novos recursos ao ambiente. Por exemplo, o core-js adiciona Array.prototype.flatMap para navegadores antigos. O Shim, por sua vez, redireciona chamadas existentes para implementações disponíveis ou substitui os objetos globais esperados. No Webpack, o ProvidePlugin insere automaticamente import $ from 'jquery' em todos os lugares onde é encontrada uma referência à variável global $, sem exigir alterações no código.

A principal diferença está no objetivo. Polyfill adiciona o que não existe, enquanto shim torna o código existente compatível com o ambiente em que é executado. A escolha entre eles depende do problema que está sendo resolvido: ausência de API ou incompatibilidade de interfaces.

Como o Shimming funciona no Webpack

Webpack trata cada módulo como uma unidade isolada com escopo próprio. Se uma biblioteca acessa a variável global jQuery como window.$, o build falhará com erro, pois essa variável não existe no contexto modular. O ProvidePlugin resolve o problema na etapa de compilação: ao detectar o identificador $ no código, o plugin insere automaticamente import $ from 'jquery' no início do arquivo.

js
// Código-fonte (o módulo legado acessa o jQuery global)
$('.element').hide();

// Após o processamento do ProvidePlugin (o Webpack insere o import)
import $ from 'jquery';
$('.element').hide();

Além disso, o imports-loader permite especificar explicitamente quais dependências um módulo deve receber. Isso é útil quando uma biblioteca usa this no nível superior, esperando que this se refira a window e não a module.exports.

ProvidePlugin: variáveis globais para módulos

ProvidePlugin é um plugin integrado do Webpack que carrega automaticamente módulos ao detectar referências a identificadores especificados. A configuração é um objeto em que a chave é o nome da variável e o valor é o caminho para o módulo e o campo exportado.

Configuração do plugin

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

module.exports = {
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      _: 'lodash',
      'window.$': 'jquery',
    }),
  ],
};

ProvidePlugin suporta importação parcial por meio da sintaxe de array. Por exemplo, [lodash, debounce] importa apenas a função debounce do lodash, o que reduz o tamanho do bundle final. Isso é especialmente importante em projetos móveis, em que cada kilobyte afeta o tempo de carregamento.

imports-loader e exports-loader

imports-loader adiciona as importações necessárias ao início de um módulo, enquanto o exports-loader define os valores exportados para módulos que não usam module.exports explicitamente. Esses loaders trabalham no nível de arquivos individuais, não globalmente como o ProvidePlugin.

Correção de dependências com o imports-loader

js
// webpack.config.js — configuração do imports-loader
module.exports = {
  module: {
    rules: [
      {
        test: /legacy-module\.js$/,
        use: [
          {
            loader: 'imports-loader',
            options: {
              imports: [
                'jquery',
                '$',
              ],
            },
          },
        ],
      },
    ],
  },
};

exports-loader é usado quando uma biblioteca atribui um valor a uma variável global, mas não o exporta pelo sistema de módulos. O loader extrai o valor e o transforma em uma exportação de módulo, permitindo que outros módulos o importem por meio de import.

Configuração de shimming na configuração do Webpack

Shimming é configurado no webpack.config.js por meio de uma combinação de plugins e loaders. Um cenário típico inclui ProvidePlugin para variáveis globais e imports-loader para módulos específicos que exigem alteração de escopo.

Configuração básica do Webpack para shimming

js
const webpack = require('webpack');
const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    globalObject: 'this',
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules\/(?!legacy-lib)/,
        use: [
          {
            loader: 'imports-loader',
            options: {
              type: 'commonjs',
              imports: ['jquery', '$'],
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
    }),
  ],
};

O campo globalObject em output define o contexto para referências a this no nível superior. Para um ambiente de navegador, o valor 'this' se refere a window, enquanto para React Native ou Node.js se refere a global. Escolher o valor correto previne erros de execução no ambiente de destino.

Erros típicos ao fazer shimming

Shimming é uma ferramenta poderosa, porém perigosa. Uma configuração incorreta leva à duplicação de código no bundle, conflitos de nomes e erros de execução inesperados. Os desenvolvedores frequentemente esquecem que o ProvidePlugin funciona na etapa de compilação e não pode processar referências dinâmicas a variáveis.

Conflitos de variáveis globais

Se dois plugins usam versões diferentes de jQuery, o ProvidePlugin substituirá apenas uma delas, a especificada primeiro na configuração. A segunda biblioteca receberá uma versão incompatível, o que causará erros difíceis de depurar. A solução é usar exports-loader para cada biblioteca com versão explícita ou aplicar webpack.IgnorePlugin para excluir módulos duplicados.

Outro erro comum é tentar fazer shimming em módulos que usam chamadas require síncronas de CommonJS em contexto dinâmico. O ProvidePlugin processa apenas identificadores estáticos, portanto referências dinâmicas devem ser substituídas manualmente ou com NormalModuleReplacementPlugin.

Problemas de desempenho com shimming incorreto

Uma configuração incorreta de shimming pode levar a um aumento significativo do tamanho do bundle. Se o ProvidePlugin estiver configurado para dezenas de variáveis globais, o Webpack inserirá as importações correspondentes em todos os arquivos do projeto, independentemente de essas variáveis serem usadas em cada arquivo específico. Isso cria código redundante, especialmente em projetos grandes com milhares de módulos.

Para diagnosticar problemas com shimming, use o webpack-bundle-analyzer — uma ferramenta para visualizar a composição do bundle. Se o jQuery ou outra biblioteca aparecer no bundle várias vezes, provavelmente versões diferentes estão em conflito ou o ProvidePlugin está configurado para vários identificadores que apontam para versões diferentes do pacote. A solução é unificar as versões das dependências via resolve.alias e verificar se todos os identificadores com shim apontam para o mesmo módulo.

Alternativas ao shimming: refatoração e atualização de dependências

Antes de aplicar o shimming, avalie a possibilidade de atualizar a biblioteca para uma versão que suporte o sistema modular. Muitos pacotes legados têm alternativas modernas que não exigem shimming. Por exemplo, plugins de jQuery podem ser substituídos por APIs nativas do navegador: $.ajaxfetch, $.eachArray.forEach. A refatoração traz benefício de longo prazo na manutenção, enquanto o shimming é uma solução temporária que complica a configuração.

Se a atualização não for possível, considere o NormalModuleReplacementPlugin, que permite substituir um módulo por outro no nível de resolução sem alterar o código-fonte. Esse plugin funciona na etapa de construção do grafo de dependências, antes da aplicação dos loaders, e processa todas as referências ao módulo independentemente do contexto. É uma solução mais limpa para substituir bibliotecas inteiras do que loaders pontuais.

Shimming no JavaScript moderno: ESM e import maps

Com o desenvolvimento dos ES modules nativos nos navegadores e o surgimento dos import maps, alguns cenários de shimming podem ser resolvidos sem Webpack. Import maps permitem remapear nomes de módulos dinamicamente no nível do navegador, sem etapa de build. No entanto, essa abordagem não é suportada no React Native e em outros ambientes sem ESM de navegador, portanto o shimming via Webpack permanece relevante para builds de produção que exigem controle total sobre as dependências e suas versões. A escolha entre import maps e shims do Webpack depende da plataforma de destino e dos requisitos de compatibilidade com navegadores antigos.

Perguntas frequentes

Como o shimming difere do tree shaking?

Shimming adiciona código para garantir compatibilidade, enquanto o tree shaking remove código não utilizado. Essas técnicas são opostas em propósito: o shimming aumenta o tamanho do bundle, o tree shaking o reduz. Em um build de produção, ambas são aplicadas em sequência.

É possível usar shimming sem Webpack?

Sim, o shimming existe como técnica independente do Webpack — por exemplo, por meio de scripts globais no HTML ou por meio de ES modules com reexportação. No entanto, o Webpack fornece as ferramentas de automação mais convenientes: ProvidePlugin e loaders que não exigem alterações manuais no código.

Como o shimming afeta o desempenho do build?

ProvidePlugin não afeta a velocidade do build porque trabalha na etapa de compilação do AST. imports-loader e exports-loader adicionam um pequeno tempo de processamento para cada arquivo. Quando usados em centenas de arquivos, a diferença pode ser de 5–15% do tempo total do build.

Quando se deve abrir mão do shimming?

Se todas as dependências suportam ES modules e o sistema modular, o shimming é redundante. Abrir mão do shimming simplifica a configuração, reduz o tamanho do bundle e diminui o risco de conflitos de nomes. Recomenda-se verificar as dependências no caniuse.com.

Como o shimming funciona com TypeScript?

TypeScript exige declarações de tipos adicionais para variáveis com shim. É necessário adicionar declare const $: any ou instalar os tipos via @types/jquery. O ProvidePlugin insere as importações no nível de JavaScript após a compilação do TypeScript, portanto os tipos são verificados separadamente.

Resumo

  • Shimming é uma técnica para garantir a compatibilidade de módulos com o ambiente por meio da substituição de variáveis globais e APIs.
  • ProvidePlugin importa automaticamente módulos ao detectar referências a identificadores especificados no código.
  • imports-loader adiciona importações ao início de arquivos específicos, enquanto o exports-loader define os valores exportados.
  • Shim difere do polyfill porque não implementa funcionalidade, mas redireciona chamadas para implementações existentes.
  • ProvidePlugin funciona na etapa de compilação e não processa referências dinâmicas a variáveis.
  • O campo globalObject em output define o contexto correto para o nível superior no ambiente de destino.
  • Use shimming apenas para módulos que não suportam o sistema modular moderno e abra mão dele quando houver suporte completo a ES modules.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também