Shimming: podstata, přístupy a princip fungování

Autor: IT Sectr Publikováno: 2026-05-19 Doba čtení: 8 min

Shimming — technika zajištění kompatibility modulů, které očekávají určité globální proměnné nebo API. V ekosystému Webpack se shimming realizuje prostřednictvím ProvidePlugin, imports-loader a exports-loader, což umožňuje připojit legacy knihovny bez změny jejich zdrojového kódu. Podle Webpack Documentation (2026) zůstává shimming klíčovým nástrojem pro integraci jQuery pluginů a dalších závislostí, které nepodporují modulární systém.

Hlavní body

  • Shimming — technika náhrady globálních proměnných a API pro zajištění kompatibility modulů v buildovém balíčku.
  • ProvidePlugin automaticky importuje modul při zjištění odkazu na globální proměnnou v kódu.
  • imports-loader a exports-loader spravují rozsah viditelnosti modulů, přidávají nebo mění jejich rozhraní.
  • Shim se liší od polyfill tím, že neimplementuje chybějící funkčnost, ale přesměrovává existující volání.
  • Webpack poskytuje vestavěné mechanismy shimmingu bez nutnosti instalovat další balíčky.

Co je Shimming?

Shimming je softwarová technika, která vkládá vrstvu kompatibility mezi kód a prostředí, aniž by měnila zdrojový kód modulu. V kontextu sestavování JavaScriptu shimming řeší problém, kdy modul odkazuje na globální proměnné (window.$, global.process), které v modulárním prostředí neexistují.

Shim a polyfill: hlavní rozdíly

Polyfill implementuje chybějící funkčnost od nuly a přidává do prostředí nové možnosti. Například core-js přidává Array.prototype.flatMap pro starší prohlížeče. Shim naopak přesměrovává existující volání na dostupné implementace nebo nahrazuje očekávané globální objekty. Ve Webpacku ProvidePlugin automaticky vkládá import $ from 'jquery' všude tam, kde se vyskytuje odkaz na globální proměnnou $, aniž by vyžadoval změny v kódu.

Hlavní rozdíl spočívá v cíli. Polyfill přidává to, co chybí, zatímco shim činí existující kód kompatibilním s prostředím, ve kterém se spouští. Volba mezi nimi závisí na tom, jaký problém se řeší: chybějící API nebo nekompatibilita rozhraní.

Jak funguje Shimming ve Webpacku

Webpack zpracovává každý modul jako izolovanou jednotku s vlastním rozsahem viditelnosti. Pokud knihovna odkazuje na globální proměnnou jQuery jako na window.$, sestavení skončí chybou, protože tato proměnná v modulárním kontextu neexistuje. ProvidePlugin řeší problém ve fázi kompilace: jakmile v kódu zjistí identifikátor $, plugin automaticky vloží import $ from 'jquery' na začátek souboru.

js
// Zdrojový kód (legacy modul přistupuje ke globálnímu jQuery)
$('.element').hide();

// Po zpracování pomocí ProvidePlugin (Webpack vloží import)
import $ from 'jquery';
$('.element').hide();

Navíc imports-loader umožňuje explicitně určit, které závislosti má modul získat. To je užitečné, když knihovna používá this na nejvyšší úrovni a očekává, že this odkazuje na window, nikoli na module.exports.

ProvidePlugin: globální proměnné pro moduly

ProvidePlugin — vestavěný plugin Webpacku, který automaticky načítá moduly při zjištění odkazu na zadané identifikátory. Konfigurace představuje objekt, kde klíč je název proměnné a hodnota je cesta k modulu a exportované pole.

Konfigurace pluginu

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

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

ProvidePlugin podporuje cílený import prostřednictvím syntaxe pole. Například [lodash, debounce] importuje pouze funkci debounce z lodash, což zmenšuje velikost výsledného balíčku. To je obzvláště důležité u mobilních projektů, kde každý kilobajt ovlivňuje dobu načítání.

imports-loader a exports-loader

imports-loader přidává potřebné importy na začátek modulu, zatímco exports-loader nastavuje exportované hodnoty pro moduly, které explicitně nepoužívají module.exports. Tyto loadery pracují na úrovni jednotlivých souborů, nikoli globálně jako ProvidePlugin.

Oprava závislostí pomocí imports-loader

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

exports-loader se používá, když knihovna přiřadí hodnotu globální proměnné, ale neexportuje ji přes modulární systém. Loader hodnotu vytáhne a přemění ji na modulární export, což ostatním modulům umožňuje importovat ji přes import.

Nastavení shimmingu v konfiguraci Webpacku

Shimming se konfiguruje v webpack.config.js kombinací pluginů a loaderů. Typický scénář zahrnuje ProvidePlugin pro globální proměnné a imports-loader pro konkrétní moduly, které vyžadují změnu rozsahu viditelnosti.

Základní konfigurace Webpacku pro 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',
    }),
  ],
};

Pole globalObject ve výstupu nastavuje kontext pro odkazy na this na nejvyšší úrovni. Pro prohlížečové prostředí se hodnota 'this' vztahuje na window a pro React Native nebo Node.js — na global. Výběr správné hodnoty zabraňuje chybám za běhu v cílovém prostředí.

Typické chyby při shimmingu

Shimming je mocný, ale nebezpečný nástroj. Nesprávné nastavení vede k duplikování kódu v balíčku, ke konfliktům názvů a k neočekávaným chybám za běhu. Vývojáři často zapomínají, že ProvidePlugin pracuje ve fázi kompilace a nedokáže zpracovat dynamické odkazy na proměnné.

Konflikty globálních proměnných

Pokud dva pluginy používají různé verze jQuery, ProvidePlugin vloží pouze jednu z nich, a to tu, která je v konfiguraci uvedena jako první. Druhá knihovna dostane nekompatibilní verzi, což způsobí chyby, které se těžko hledají. Řešením je použít exports-loader pro každou knihovnu s explicitním uvedením verze nebo použít webpack.IgnorePlugin pro vyloučení duplicitních modulů.

Další častou chybou je pokus o shimming modulů, které používají synchronní volání CommonJS require v dynamickém kontextu. ProvidePlugin zpracovává pouze statické identifikátory, proto je třeba dynamické odkazy nahradit ručně nebo použít NormalModuleReplacementPlugin.

Problémy s výkonem při nesprávném shimmingu

Nesprávné nastavení shimmingu může vést k výraznému zvětšení velikosti balíčku. Pokud je ProvidePlugin nastaven na desítky globálních proměnných, Webpack bude vkládat odpovídající importy do všech souborů projektu, bez ohledu na to, zda se tyto proměnné v daném souboru používají. To vytváří zbytečný kód, zejména ve velkých projektech s tisíci modulů.

Pro diagnostiku problémů se shimmingem použijte webpack-bundle-analyzer — nástroj pro vizualizaci složení balíčku. Pokud se jQuery nebo jiná knihovna objevuje v balíčku vícekrát, pravděpodobně kolidují různé verze nebo je ProvidePlugin nastaven na více identifikátorů vedoucích k různým verzím balíčku. Řešením je sjednotit verze závislostí přes resolve.alias a ověřit, že všechny shimmované identifikátory ukazují na stejný modul.

Alternativy shimmingu: refaktoring a aktualizace závislostí

Před použitím shimmingu zhodnoťte možnost aktualizace knihovny na verzi podporující modulární systém. Mnoho legacy balíčků má moderní alternativy, které shimming nevyžadují. Například jQuery pluginy lze nahradit nativními API prohlížeče: $.ajaxfetch, $.eachArray.forEach. Refaktoring přináší dlouhodobý přínos v údržbě, zatímco shimming je dočasné řešení, které komplikuje konfiguraci.

Pokud aktualizace není možná, zvažte NormalModuleReplacementPlugin, který umožňuje nahradit jeden modul jiným na úrovni rezoluce, bez změny zdrojového kódu. Tento plugin pracuje ve fázi sestavování grafu závislostí, před aplikací loaderů, a zpracovává všechny odkazy na modul bez ohledu na kontext. To je čistší řešení pro nahrazení celých knihoven než cílené loadery.

Shimming v moderním JavaScriptu: ESM a import maps

S rozvojem nativních modulů ES v prohlížečích a s příchodem import maps lze některé scénáře shimmingu vyřešit bez Webpacku. Import maps umožňují přejmenovávat názvy modulů za běhu, na úrovni prohlížeče, bez fáze sestavování. Tento přístup se však nepodporuje v React Native a dalších prostředích bez prohlížečového ESM, proto shimming přes Webpack zůstává aktuální pro produkční sestavení, kde je vyžadována plná kontrola nad závislostmi a jejich verzemi. Volba mezi import maps a Webpack shimy závisí na cílové platformě a požadavcích na kompatibilitu se staršími prohlížeči.

Často kladené otázky

Čím se liší shimming od tree shakingu?

Shimming přidává kód pro zajištění kompatibility, zatímco tree shaking odstraňuje nepoužitý kód. Tyto techniky mají opačný cíl: shimming zvětšuje velikost balíčku, tree shaking ji zmenšuje. V produkčním sestavení se obě aplikují postupně.

Lze použít shimming bez Webpacku?

Ano, shimming existuje jako technika nezávisle na Webpacku — například prostřednictvím globálních skriptů v HTML nebo modulů ES s re-exportem. Webpack však poskytuje nejpohodlnější nástroje automatizace: ProvidePlugin a loadery, které nevyžadují ruční úpravy kódu.

Jak shimming ovlivňuje výkon sestavování?

ProvidePlugin neovlivňuje rychlost sestavování, protože pracuje ve fázi kompilace AST. imports-loader a exports-loader přidávají malý čas zpracování pro každý soubor. Při použití na stovkách souborů může rozdíl činit 5–15 % času celkového sestavení.

Kdy se vyplatí od shimmingu upustit?

Pokud všechny závislosti podporují moduly ES a modulární systém, je shimming nadbytečný. Upuštění od shimmingu zjednodušuje konfiguraci, zmenšuje velikost balíčku a snižuje riziko konfliktů názvů. Doporučuje se zkontrolovat závislosti na caniuse.com.

Jak shimming funguje s TypeScriptem?

TypeScript vyžaduje další deklarace typů pro shimmované proměnné. Je třeba přidat declare const $: any nebo nainstalovat typy přes @types/jquery. ProvidePlugin vkládá importy na úrovni JavaScriptu po kompilaci TypeScriptu, proto se typy kontrolují samostatně.

Shrnutí

  • Shimming — technika zajištění kompatibility modulů s prostředím prostřednictvím náhrady globálních proměnných a API.
  • ProvidePlugin automaticky importuje moduly při zjištění odkazu na zadané identifikátory v kódu.
  • imports-loader přidává importy na začátek konkrétních souborů, zatímco exports-loader nastavuje exportované hodnoty.
  • Shim se liší od polyfill tím, že neimplementuje funkčnost, ale přesměrovává volání na existující implementace.
  • ProvidePlugin pracuje ve fázi kompilace a nezpracovává dynamické odkazy na proměnné.
  • Pole globalObject ve výstupu nastavuje správný kontext pro nejvyšší úroveň v cílovém prostředí.
  • Používejte shimming pouze pro moduly, které nepodporují moderní modulární systém, a upusťte od něj při plné podpoře modulů ES.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také