Shimming: esensi, pendekatan, dan prinsip kerja

Penulis: IT Sectr Diterbitkan: 2026-05-19 Waktu membaca: 8 mnt

Shimming — teknik untuk memastikan kompatibilitas modul yang mengharapkan variabel global atau API tertentu. Dalam ekosistem Webpack, shimming diimplementasikan melalui ProvidePlugin, imports-loader, dan exports-loader, sehingga memungkinkan menghubungkan pustaka legacy tanpa mengubah kode sumbernya. Menurut Webpack Documentation (2026), shimming tetap menjadi alat kunci untuk mengintegrasikan plugin jQuery dan dependensi lain yang tidak mendukung sistem modul.

Poin penting

  • Shimming — teknik mengganti variabel global dan API untuk memastikan kompatibilitas modul dalam bundle.
  • ProvidePlugin secara otomatis mengimpor modul saat menemukan referensi ke variabel global dalam kode.
  • imports-loader dan exports-loader mengelola cakupan visibilitas modul, menambahkan atau mengubah antarmukanya.
  • Shim berbeda dari polyfill karena tidak mengimplementasikan fungsionalitas yang hilang, melainkan mengarahkan panggilan yang ada.
  • Webpack menyediakan mekanisme shimming bawaan tanpa perlu menginstal paket tambahan.

Apa itu Shimming?

Shimming adalah teknik perangkat lunak yang memasukkan lapisan kompatibilitas antara kode dan lingkungan tanpa mengubah kode sumber modul. Dalam konteks bundling JavaScript, shimming menyelesaikan masalah ketika modul mengakses variabel global (window.$, global.process) yang tidak ada di lingkungan modular.

Shim dan polyfill: perbedaan utama

Polyfill mengimplementasikan fungsionalitas yang hilang dari awal, menambahkan kemampuan baru ke lingkungan. Misalnya, core-js menambahkan Array.prototype.flatMap untuk browser lama. Shim sebaliknya mengarahkan panggilan yang ada ke implementasi yang tersedia atau mengganti objek global yang diharapkan. Di Webpack, ProvidePlugin secara otomatis menyisipkan import $ from 'jquery' di mana pun ada referensi ke variabel global $, tanpa memerlukan perubahan kode.

Perbedaan utamanya terletak pada tujuannya. Polyfill menambahkan apa yang tidak ada, sedangkan shim membuat kode yang ada kompatibel dengan lingkungan tempat kode tersebut dijalankan. Pilihan di antara keduanya bergantung pada masalah yang diselesaikan: tidak adanya API atau ketidakcocokan antarmuka.

Bagaimana Shimming bekerja di Webpack

Webpack memperlakukan setiap modul sebagai unit terisolasi dengan cakupan visibilitasnya sendiri. Jika pustaka mengakses variabel global jQuery sebagai window.$, proses bundling akan berakhir dengan error, karena variabel tersebut tidak ada dalam konteks modular. ProvidePlugin menyelesaikan masalah ini pada tahap kompilasi: saat menemukan identifier $ dalam kode, plugin otomatis menyisipkan import $ from 'jquery' di awal file.

js
// Kode sumber (modul legacy mengakses jQuery global)
$('.element').hide();

// Setelah diproses oleh ProvidePlugin (Webpack menyisipkan import)
import $ from 'jquery';
$('.element').hide();

Selain itu, imports-loader memungkinkan Anda menentukan secara eksplisit dependensi apa yang harus diterima modul. Ini berguna ketika pustaka menggunakan this di level teratas, berharap bahwa this merujuk ke window, bukan ke module.exports.

ProvidePlugin: variabel global untuk modul

ProvidePlugin — plugin Webpack bawaan yang secara otomatis memuat modul saat mendeteksi referensi ke identifier tertentu. Konfigurasinya berupa objek tempat kunci adalah nama variabel, dan nilainya adalah jalur ke modul serta kolom yang diekspor.

Konfigurasi plugin

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

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

ProvidePlugin mendukung impor yang ditargetkan melalui sintaks array. Misalnya, [lodash, debounce] hanya mengimpor fungsi debounce dari lodash, sehingga mengurangi ukuran bundle akhir. Ini sangat penting untuk proyek seluler, tempat setiap kilobyte memengaruhi waktu muat.

imports-loader dan exports-loader

imports-loader menambahkan impor yang diperlukan ke awal modul, sedangkan exports-loader menetapkan nilai yang diekspor untuk modul yang tidak menggunakan module.exports secara eksplisit. Loader ini bekerja di tingkat file individual, bukan secara global seperti ProvidePlugin.

Memperbaiki dependensi dengan imports-loader

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

exports-loader digunakan ketika pustaka menetapkan nilai ke variabel global tetapi tidak mengekspornya melalui sistem modul. Loader mengekstrak nilai tersebut dan mengubahnya menjadi ekspor modular, sehingga modul lain dapat mengimpornya melalui import.

Mengonfigurasi shimming dalam konfigurasi Webpack

Shimming dikonfigurasi dalam webpack.config.js melalui kombinasi plugin dan loader. Skenario umum mencakup ProvidePlugin untuk variabel global dan imports-loader untuk modul spesifik yang memerlukan perubahan cakupan visibilitas.

Konfigurasi dasar Webpack untuk 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',
    }),
  ],
};

Kolom globalObject pada output menetapkan konteks untuk referensi this di level teratas. Untuk lingkungan browser, nilai 'this' merujuk ke window, dan untuk React Native atau Node.js — ke global. Memilih nilai yang tepat mencegah error saat runtime di lingkungan target.

Kesalahan umum saat shimming

Shimming adalah alat yang kuat, tetapi berbahaya. Konfigurasi yang salah menyebabkan duplikasi kode dalam bundle, konflik nama, dan error runtime yang tidak terduga. Pengembang sering lupa bahwa ProvidePlugin bekerja pada tahap kompilasi dan tidak dapat menangani referensi dinamis ke variabel.

Konflik variabel global

Jika dua plugin menggunakan versi jQuery yang berbeda, ProvidePlugin hanya akan menyisipkan salah satunya, yaitu versi yang disebutkan pertama dalam konfigurasi. Pustaka kedua akan menerima versi yang tidak kompatibel, yang menyebabkan error yang sulit dilacak. Solusinya adalah menggunakan exports-loader untuk setiap pustaka dengan menyebutkan versinya secara eksplisit atau menerapkan webpack.IgnorePlugin untuk mengecualikan modul yang duplikat.

Kesalahan umum lainnya adalah mencoba shimming pada modul yang menggunakan panggilan sinkron CommonJS require dalam konteks dinamis. ProvidePlugin hanya memproses identifier statis, sehingga referensi dinamis harus diganti secara manual atau gunakan NormalModuleReplacementPlugin.

Masalah performa saat shimming yang salah

Konfigurasi shimming yang salah dapat menyebabkan peningkatan ukuran bundle secara signifikan. Jika ProvidePlugin dikonfigurasi untuk puluhan variabel global, Webpack akan menyisipkan impor yang sesuai ke semua file proyek, terlepas dari apakah variabel tersebut digunakan di setiap file. Ini menciptakan kode berlebihan, terutama di proyek besar dengan ribuan modul.

Untuk mendiagnosis masalah shimming, gunakan webpack-bundle-analyzer — alat visualisasi komposisi bundle. Jika jQuery atau pustaka lain muncul beberapa kali dalam bundle, kemungkinan versi yang berbeda berkonflik atau ProvidePlugin dikonfigurasi untuk beberapa identifier yang mengarah ke versi paket yang berbeda. Solusinya adalah menyatukan versi dependensi melalui resolve.alias dan memastikan semua identifier yang di-shim menunjuk ke modul yang sama.

Alternatif shimming: refactoring dan pembaruan dependensi

Sebelum menerapkan shimming, pertimbangkan kemungkinan memperbarui pustaka ke versi yang mendukung sistem modul. Banyak paket legacy memiliki alternatif modern yang tidak memerlukan shimming. Misalnya, plugin jQuery dapat diganti dengan API asli browser: $.ajaxfetch, $.eachArray.forEach. Refactoring memberikan keuntungan jangka panjang dalam pemeliharaan, sedangkan shimming adalah solusi sementara yang memperumit konfigurasi.

Jika pembaruan tidak memungkinkan, pertimbangkan NormalModuleReplacementPlugin yang memungkinkan mengganti satu modul dengan modul lain di tingkat resolusi, tanpa mengubah kode sumber. Plugin ini bekerja pada tahap pembangunan grafik dependensi, sebelum loader diterapkan, dan memproses semua referensi ke modul terlepas dari konteksnya. Ini adalah solusi yang lebih bersih untuk mengganti seluruh pustaka daripada loader yang ditargetkan.

Shimming dalam JavaScript modern: ESM dan import maps

Dengan berkembangnya modul ES asli di browser dan munculnya import maps, beberapa skenario shimming dapat diselesaikan tanpa Webpack. Import maps memungkinkan menetapkan ulang nama modul secara langsung di tingkat browser, tanpa tahap bundling. Namun, pendekatan ini tidak didukung di React Native dan lingkungan lain tanpa ESM browser, sehingga shimming melalui Webpack tetap relevan untuk bundle produksi yang memerlukan kontrol penuh atas dependensi dan versinya. Pilihan antara import maps dan shim Webpack bergantung pada platform target dan persyaratan kompatibilitas dengan browser lama.

Pertanyaan yang sering diajukan

Apa perbedaan shimming dengan tree shaking?

Shimming menambahkan kode untuk memastikan kompatibilitas, sedangkan tree shaking menghapus kode yang tidak digunakan. Kedua teknik ini berlawanan tujuan: shimming memperbesar bundle, tree shaking memperkecilnya. Dalam bundle produksi, keduanya diterapkan secara berurutan.

Bisakah shimming digunakan tanpa Webpack?

Ya, shimming ada sebagai teknik yang independen dari Webpack — misalnya, melalui skrip global di HTML atau modul ES dengan re-export. Namun, Webpack menyediakan alat otomatisasi yang paling nyaman: ProvidePlugin dan loader yang tidak memerlukan perubahan kode manual.

Bagaimana shimming memengaruhi performa bundling?

ProvidePlugin tidak memengaruhi kecepatan bundling karena bekerja pada tahap kompilasi AST. imports-loader dan exports-loader menambahkan sedikit waktu pemrosesan untuk setiap file. Saat digunakan pada ratusan file, perbedaannya bisa mencapai 5–15% dari waktu bundling total.

Kapan sebaiknya menghindari shimming?

Jika semua dependensi mendukung modul ES dan sistem modul, shimming tidak diperlukan. Menghindari shimming menyederhanakan konfigurasi, mengurangi ukuran bundle, dan menurunkan risiko konflik nama. Disarankan untuk memeriksa dependensi di caniuse.com.

Bagaimana shimming bekerja dengan TypeScript?

TypeScript memerlukan deklarasi tipe tambahan untuk variabel yang di-shim. Anda perlu menambahkan declare const $: any atau menginstal tipe melalui @types/jquery. ProvidePlugin menyisipkan impor di tingkat JavaScript setelah kompilasi TypeScript, sehingga tipe diperiksa secara terpisah.

Kesimpulan

  • Shimming — teknik memastikan kompatibilitas modul dengan lingkungan melalui penggantian variabel global dan API.
  • ProvidePlugin secara otomatis mengimpor modul saat mendeteksi referensi ke identifier tertentu dalam kode.
  • imports-loader menambahkan impor ke awal file tertentu, dan exports-loader menetapkan nilai yang diekspor.
  • Shim berbeda dari polyfill karena tidak mengimplementasikan fungsionalitas, melainkan mengarahkan panggilan ke implementasi yang ada.
  • ProvidePlugin bekerja pada tahap kompilasi dan tidak memproses referensi dinamis ke variabel.
  • Kolom globalObject pada output menetapkan konteks yang tepat untuk level teratas di lingkungan target.
  • Gunakan shimming hanya untuk modul yang tidak mendukung sistem modul modern, dan hindari jika dukungan modul ES sudah penuh.

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga