Shimming: essensen, metoderna och funktionsprincipen

Författare: IT Sectr Publicerad: 2026-05-19 Lästid: 8 min

Shimming — en teknik för att säkerställa kompatibilitet hos moduler som förväntar sig vissa globala variabler eller API:er. I Webpack-ekosystemet implementeras shimming genom ProvidePlugin, imports-loader och exports-loader, vilket gör det möjligt att koppla in legacy-bibliotek utan att ändra deras källkod. Enligt Webpack Documentation (2026) förblir shimming ett nyckelverktyg för integrering av jQuery-plugin-program och andra beroenden som inte stöder modulsystemet.

Viktigaste punkterna

  • Shimming — en teknik för att ersätta globala variabler och API:er för att säkerställa modulkompatibilitet i bygget.
  • ProvidePlugin importerar automatiskt modulen när det upptäcker en referens till en global variabel i koden.
  • imports-loader och exports-loader hanterar modulernas synlighetsomfång genom att lägga till eller ändra deras gränssnitt.
  • Shim skiljer sig från polyfill genom att det inte implementerar den saknade funktionaliteten, utan vidarebefordrar befintliga anrop.
  • Webpack tillhandahåller inbyggda shimming-mekanismer utan att det krävs installation av extra paket.

Vad är Shimming?

Shimming är en programvaruteknik som bygger in ett kompatibilitetslager mellan kod och miljö utan att ändra modulens källkod. I samband med JavaScript-bundling löser shimming problemet när en modul refererar till globala variabler (window.$, global.process) som saknas i den modulära miljön.

Shim och polyfill: de viktigaste skillnaderna

Polyfill implementerar den saknade funktionaliteten från grunden och lägger till nya möjligheter i miljön. Till exempel lägger core-js till Array.prototype.flatMap för äldre webbläsare. Shim vidarebefordrar däremot befintliga anrop till tillgängliga implementeringar eller ersätter förväntade globala objekt. I Webpack infogar ProvidePlugin automatiskt import $ from 'jquery' överallt där en referens till den globala variabeln $ förekommer, utan att det krävs ändringar i koden.

Den viktigaste skillnaden ligger i syftet. Polyfill lägger till det som saknas, medan shim gör befintlig kod kompatibel med den miljö där den körs. Valet mellan dem beror på vilket problem som löses: avsaknaden av ett API eller inkompatibilitet mellan gränssnitt.

Hur fungerar Shimming i Webpack

Webpack behandlar varje modul som en isolerad enhet med eget synlighetsomfång. Om ett bibliotek refererar till den globala variabeln jQuery som window.$ avslutas bygget med ett fel, eftersom denna variabel inte finns i den modulära kontexten. ProvidePlugin löser problemet i kompileringsfasen: när identifieraren $ upptäcks i koden infogar plugin-programmet automatiskt import $ from 'jquery' i början av filen.

js
// Källkod (legacy-modulen refererar till global jQuery)
$('.element').hide();

// Efter bearbetning av ProvidePlugin (Webpack infogar import)
import $ from 'jquery';
$('.element').hide();

Dessutom gör imports-loader det möjligt att explicit ange vilka beroenden modulen ska få. Detta är användbart när ett bibliotek använder this på den översta nivån och förväntar sig att this refererar till window i stället för module.exports.

ProvidePlugin: globala variabler för moduler

ProvidePlugin — en inbyggd Webpack-plugin som automatiskt laddar moduler när en referens till angivna identifierare upptäcks. Konfigurationen är ett objekt där nyckeln är variabelns namn och värdet är sökvägen till modulen och det exporterade fältet.

Plugin-programmets konfiguration

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

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

ProvidePlugin stöder riktad import genom arraysyntax. Till exempel importerar [lodash, debounce] endast funktionen debounce från lodash, vilket minskar storleken på det slutliga paketet. Detta är särskilt viktigt för mobilprojekt där varje kilobyte påverkar laddningstiden.

imports-loader och exports-loader

imports-loader lägger till nödvändiga importer i början av modulen, medan exports-loader anger exporterade värden för moduler som inte explicit använder module.exports. Dessa loaders arbetar på nivån för enskilda filer, inte globalt som ProvidePlugin.

Åtgärda beroenden med hjälp av imports-loader

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

exports-loader används när ett bibliotek tilldelar ett värde till en global variabel men inte exporterar det via modulsystemet. Loadern extraherar värdet och omvandlar det till en modulär export, vilket gör att andra moduler kan importera det via import.

Konfigurera shimming i Webpack-konfigurationen

Shimming konfigureras i webpack.config.js genom en kombination av plugin-program och loaders. Ett typiskt scenario omfattar ProvidePlugin för globala variabler och imports-loader för specifika moduler som kräver ändring av synlighetsomfånget.

Grundläggande Webpack-konfiguration för 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',
    }),
  ],
};

Fältet globalObject i output anger kontexten för referenser till this på den översta nivån. För webbläsarmiljön refererar värdet 'this' till window och för React Native eller Node.js — till global. Att välja rätt värde förhindrar körtidsfel i målmiljön.

Vanliga fel vid shimming

Shimming är ett kraftfullt men farligt verktyg. Felaktig konfiguration leder till duplicerad kod i paketet, namnkonflikter och oväntade körtidsfel. Utvecklare glömmer ofta att ProvidePlugin arbetar i kompileringsfasen och inte kan bearbeta dynamiska referenser till variabler.

Konflikter mellan globala variabler

Om två plugin-program använder olika versioner av jQuery infogar ProvidePlugin endast den som anges först i konfigurationen. Det andra biblioteket får en inkompatibel version, vilket orsakar fel som är svåra att felsöka. Lösningen är att använda exports-loader för varje bibliotek med explicit angivande av versionen eller att tillämpa webpack.IgnorePlugin för att utesluta duplicerade moduler.

Ett annat vanligt fel är att försöka shimma moduler som använder synkrona CommonJS-anrop require i en dynamisk kontext. ProvidePlugin bearbetar endast statiska identifierare, därför måste dynamiska referenser ersättas manuellt eller så kan NormalModuleReplacementPlugin användas.

Prestandaproblem vid felaktigt shimming

Felaktig konfiguration av shimming kan leda till en betydande ökning av paketstorleken. Om ProvidePlugin är konfigurerat för dussintals globala variabler infogar Webpack motsvarande importer i alla projektets filer, oavsett om dessa variabler används i varje specifik fil. Detta skapar onödig kod, särskilt i stora projekt med tusentals moduler.

För att diagnostisera problem med shimming, använd webpack-bundle-analyzer — ett verktyg för att visualisera paketets sammansättning. Om jQuery eller ett annat bibliotek förekommer flera gånger i paketet konflikterar troligen olika versioner, eller så är ProvidePlugin konfigurerat för flera identifierare som leder till olika versioner av paketet. Lösningen är att förena beroendenas versioner via resolve.alias och kontrollera att alla shimmade identifierare pekar på samma modul.

Alternativ till shimming: refaktorisering och uppdatering av beroenden

Innan du tillämpar shimming bör du utvärdera möjligheten att uppdatera biblioteket till en version som stöder modulsystemet. Många legacy-paket har moderna alternativ som inte kräver shimming. Till exempel kan jQuery-plugin-program ersättas med webbläsarens inbyggda API:er: $.ajaxfetch, $.eachArray.forEach. Refaktorisering ger en långsiktig fördel i underhållet, medan shimming är en tillfällig lösning som komplicerar konfigurationen.

Om uppdatering inte är möjlig, överväg NormalModuleReplacementPlugin, som gör det möjligt att ersätta en modul med en annan på upplösningsnivån utan att ändra källkoden. Detta plugin-program arbetar i fasen då beroendegrafen byggs, före att loaders tillämpas, och bearbetar alla referenser till modulen oavsett kontext. Det är en renare lösning för att ersätta hela bibliotek än riktade loaders.

Shimming i modern JavaScript: ESM och import maps

Med utvecklingen av inbyggda ES-moduler i webbläsare och framväxten av import maps kan vissa shimming-scenarier lösas utan Webpack. Import maps gör det möjligt att tilldela om modulnamn direkt på webbläsarnivå, utan byggfas. Detta tillvägagångssätt stöds dock inte i React Native och andra miljöer utan webbläsar-ESM, därför förblir shimming via Webpack relevant för produktionsbyggen där full kontroll över beroenden och deras versioner krävs. Valet mellan import maps och Webpack-shims beror på målplattformen och kraven på kompatibilitet med äldre webbläsare.

Vanliga frågor

Vad skiljer shimming från tree shaking?

Shimming lägger till kod för att säkerställa kompatibilitet, medan tree shaking tar bort oanvänd kod. Dessa tekniker är motsatta till syftet: shimming ökar paketstorleken, tree shaking minskar den. I produktionsbyggen tillämpas båda i följd.

Kan man använda shimming utan Webpack?

Ja, shimming finns som en teknik oberoende av Webpack — till exempel genom globala skript i HTML eller genom ES-moduler med re-export. Webpack erbjuder dock de mest bekväma automatiseringsverktygen: ProvidePlugin och loaders som inte kräver manuella kodändringar.

Hur påverkar shimming byggprestandan?

ProvidePlugin påverkar inte bygghastigheten eftersom det arbetar i AST-kompileringsfasen. imports-loader och exports-loader lägger till lite bearbetningstid för varje fil. När de används på hundratals filer kan skillnaden uppgå till 5–15 % av den totala byggtiden.

När bör man avstå från shimming?

Om alla beroenden stöder ES-moduler och modulsystemet är shimming överflödigt. Att avstå från shimming förenklar konfigurationen, minskar paketstorleken och sänker risken för namnkonflikter. Det rekommenderas att kontrollera beroenden på caniuse.com.

Hur fungerar shimming med TypeScript?

TypeScript kräver ytterligare typdeklarationer för shimmade variabler. Du måste lägga till declare const $: any eller installera typerna via @types/jquery. ProvidePlugin infogar importerna på JavaScript-nivå efter TypeScript-kompileringen, därför kontrolleras typerna separat.

Sammanfattning

  • Shimming — en teknik för att säkerställa modulers kompatibilitet med miljön genom att ersätta globala variabler och API:er.
  • ProvidePlugin importerar automatiskt moduler när en referens till angivna identifierare upptäcks i koden.
  • imports-loader lägger till importer i början av specifika filer, medan exports-loader anger exporterade värden.
  • Shim skiljer sig från polyfill genom att det inte implementerar funktionalitet, utan vidarebefordrar anrop till befintliga implementeringar.
  • ProvidePlugin arbetar i kompileringsfasen och bearbetar inte dynamiska referenser till variabler.
  • Fältet globalObject i output anger rätt kontext för den översta nivån i målmiljön.
  • Använd shimming endast för moduler som inte stöder det moderna modulsystemet och avstå från det när det finns fullt stöd för ES-moduler.

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också