Webpack 4'den 5'e Geçiş

Mucahit Gurbuz
7 min readApr 14, 2021

--

2020'nin Kasım aylarında Webpack ekibinin duyurusuyla Webpack 5 sürümü yayımlanmış oldu. Aşağıda bahsedeceğim bir çok değişikliğin yanında özellikle micro front-end yapısını hedefleyen uygulamalar için büyük kolaylık sağlayan Module Federation özelliğinin sunulması Webpack 5'e olan ilgiyi artırmış gözüküyor. Konfigürasyonların sadeleşmesi ve hissedilir performans artışı benim bu güncellemedeki en sevdiğim noktalar oldu. Şu anda bir parçası olduğum OPLOG’un front-end ekibi(Team Picasso) olarak projelerimizi güncel tutmak ve scalibility adına alt yapımızı micro front-end’e hazırlamak için bu güncellemeyi hayata geçirdik.

Bu makalede Webpack 5'in sunduğu değişiklikler ve yeniliklerden bahsettikden sonra, Webpack 4'den Webpack 5'e geçerken izlediğim yolları, webpack ve webpack-dev-server konfigürasyonları üzerinde yaptığım değişiklikleri paylaşacağım.

Webpack için 5. major güncelleme 2 yılın ardından bir çok değişiklikler ile geldi. Hadi bu yeniliklerden konuşalım.

Webpack 5'deki yenilikler

Bu değişikleri belli genel başlıklar altında toplayabiliriz.

Kalıcı çerezleme(Persistent Caching) ile daha hızlı yapılandırma

Bir çok önyüz geliştiricinin popüler problemlerinden biri de uzun yapılandırma süreleridir. Webpack 5, module paketleyicinin önerdiği dahili dosya sistemi çerezleri ile geliştirme ortamındaki yapılandırma sürelerimizi azaltarak üretkenliğimizi artırıyor.

Daha küçük paket boyutları

Ölü kod eleme sisteminde iyileştirmeler yapıldı. Önceki webpack sürümlerinde de çalışan ölü kod eleme algoritması (tree shaking), webpack 5 ile daha da ileri gitti. Modüllerin içerisindeki ölü kod bloklarını da eleyerek daha da küçük paket boyutlarına ulaşmamızı sağlıyor.

Daha iyi uzun-vadeli çerezler

Daha küçük paketleri elde ettikden sonra uygulamamızın yüklenme süresini hızlandırabileceğimiz en etkili yol çerezlerdir. Doğru bir çerezleme ile geri dönen ziyaretçileriniz neredeyse hiç yüklenme süresi beklemeyeceklerdir. Webpack 5 ile birlikte ufaltılmış(minimized) kodunuza etki etmeyen kod değişiklikleri(yorumlar, değişken isimleri vs.) çerezlerinizi geçersiz kılmayacaklar. Bu da kullanıcılarımızın daha uzun süre hızlı bir uygulama deneyimi yaşayacaklarını sağlayacaktır.

Daha büyük iyileştirmeleri mümkün kılacak köklü değişiklikler

Şu an için gözle görülür bir iyileştirme sağlamasalar da yarattıkları altyapılar ile ilerleyen vakitlerde büyük iyileştirmelere zemin hazırlayan bazı değişikler de webpack 5 kapsamında yayımlandı.

Webpack artık minimum Node.JS versiyonu olarak 10.13.0 ı destekliyor.

experiments konfigürasyonu ile birlikte WebAssembly, Asenkron Web Assembly, Üst Seviye Bekleme (Top Level Await) ve paketlerinizi modül olarak dışarı çıkarmak mümkün hale geldi.

Modül Birliği (Module Federation)

Bu yeni özellikle birlikte birden çok derlemenin birlikte çalışması mümkün hale geliyor. Bu özellik uygulamanızın diğer uygulamalardan (diğer webpack derlemesinden) dinamik olarak kod yükleyebilmesini sağlıyor. Module federationın en yaygın uygulama alanı mikro önyüz yapısıdır. Module federation hakkında daha detaylı bilgi sahibi olmak istiyorsanız, şu resmi makaleyi okuyabilirsiniz.

Köklü değişiklikler

Deprecated Araçlar Silindi

Webpack 4'de deprecated uyarısı veren tüm araçlar silinmiş durumda. Versiyonu 5'e çekmeden bu uyarıları adreslediğinizden emin olun.

Gömülü(built-in) eklentilerdeki değişiklikler

Bazı eklentiler öncekine göre farklı argümanlar kabul ediyorlar, aşağıda bahsedeceğim üzere ya da migrasyon yönelgesini takip ederek bunları gerçekleştirmeniz gerekiyor.

Node.JS polyfilleri silindi

Önceki versiyonlarda crypto gibi doğal NodeJS kütüphaneleri dahil haldeydi. Bunlar Webpack 5 ile birlikte silindi. Bunlar yerine önyüz odaklı kütüphaneler kullanmalı veya bu polyfilleri kendiniz yüklemelisiniz.

Adım Adım Göç Senaryosu

Webpack

Bildiğiniz üzere webpack konfigürasyonları farklı istekler doğrultusunda bir çok eklentiyle desteklenerek karmaşık bir yapıya bürünebiliyor. Webpack 4'den 5'e göç ederken bu yan etkileri dikkatlice ele almak gerekiyor.

Öncelikle Webpack versiyonumuzu güncelleyerek işe başlayalım.

npm install webpack@latest

ya da

yarn add webpack@latest

Daha sonra konfigürasyonlarda kullandığımız yan paketleri güncellemeden önce webpack.config.js dosyamızı güncelleyelim. Webpack 5'in getirdiği sadeleştirmeler ve farklı varlık yönetimi(asset management) tarzı ile versiyon 4'de kullanmakta olduğumuz eklentilerden bazıları gereksiz hale gelecek. Bunları kaldırıp, geri kalan eklentileri de Webpack 5'e uyumluluk kapsamında son versiyonlarına güncellememiz gerekecek (bu tüm paketler için zorunlu bir hamle değil fakat uygulamamızın güncel kalabilmesi için güzel bir fırsat).

Kendi projemiz için kullandığımız webpack konfigürasyonunun versiyon 4 ve 5 için oluşan halini paylaşıp, daha sonra bu göç hareketi için takip ettiğim kural dizininden adım adım bahsedeceğim.

Burada Webpack konfigürasyonu yapılan uygulama TypeScript ile ReactJS kullanılarak geliştirilen bir yapıya sahip.

webpack.config.js versiyon 4.* örneği:

webpack.config.js versiyon 5.* örneği:

Webpack 4'den 5'e geçişte izlenmesi gereken noktalar:

  • NodeJS versiyonunuzun en az 10.13.0 olduğundan emin olun.
  • mode tercihinizin production veya development a eşitlendiğinden emin olun.
  • optimization.moduleIds ve optimization.chunkIds seçeneklerini kaldırmayı tercih edin. Varsayılan ayarlar daha iyi sonuç almanızı sağlayacaktır (production modunda uzun-vadeli çerezleri aktif ederken, geliştirme ortamında debug modunu destekliyorlar).
  • [hash] yertutucularınızı [contenthash] ile değiştirin. Aynı değiller ama daha etkili olduğu kanıtlandı.
  • Eğer Yarn’ın PnP eklentisini kullanıyorsanız (pnp-webpack-plugin) artık varsayılan olarak bu destekleniyor. Bu eklentiyi konfigürasyondan kaldırabilirsiniz.
  • Eğer IgnorePlugin i regular expression ile kullanıyorsanız bunu artık seçenek objesi olarak vermeniz gerekiyor: new IgnorePlugin({ resourceRegExp: /regExp/ }) .
  • Eğer node.fs: 'empty' gibi bir yapı kullanıyorsanız bunu şununla değiştirin: resolve.fallback.fs: false .
  • Eğer raw-loader , url-loader ve file-loader kullanarak asset yüklemesi için rules tanımlamaları yapıldıysa bunları Asset Modülünü kullanarak sağlamak daha doğru olacaktır. Bu loaderlar ilerleyen zamanlarda atıl hale gelecekler.
  • Eğer target seçeneğiniz bir fonksiyona eşitse bunu false a eşitleyip fonksiyonunuzu plugins seçeneğinin altına taşıyın.
  • Webpack ekibi tarafından splitChunks seçeneği için ya varsayılan seçeneğin kullanılması ya da optimization.splitChunks: { chunks: 'all' } şeklinde kullanılması öneriliyor.

Aşağıdaki tercihlerinizi yenileriyle güncellemelisiniz:

  • optimization.hashedModuleIds: trueoptimization.moduleIds: 'deterministic'
  • optimization.namedChunks: trueoptimization.chunkIds: 'named'
  • optimization.namedModules: trueoptimization.moduleIds: 'named'
  • NamedModulesPluginoptimization.moduleIds: 'named'
  • NamedChunksPluginoptimization.chunkIds: 'named'
  • HashedModuleIdsPluginoptimization.moduleIds: 'deterministic'
  • optimization.noEmitOnErrors: falseoptimization.emitOnErrors: true
  • optimization.occurrenceOrder: trueoptimization: { chunkIds: 'total-size', moduleIds: 'size' }
  • optimization.splitChunks.cacheGroups.vendorsoptimization.splitChunks.cacheGroups.defaultVendors
  • Compilation.entriesCompilation.entryDependencies
  • serve seçeneği silindi yerine DevServer seçeneği geldi

Bu değişiklikleri uyguladığınızda bazı yükleyicilerinizin (loaders) ve eklentilerinizin boşa çıktığını farketedeceksiniz. Onları bağımlılıklardan kaldırıp, diğer kullanılan eklenti ve yükleyicileri mümkün olan en güncel seviyeye çekmeye çalışın.

Bazı kütüphaneler için webpack 5'e uyumluluk açısından beta versiyonlarını yüklemeniz gerekebilir.

Bizim projemizde package.json’da gerçekleşen durumu paylaşmam gerekirse:

Kaldırılan Eklentiler: workbox-webpack-plugin, @babel/plugin-transform-react-jsx, eslint-loader, file-loader, fork-ts-checker-webpack-plugin-alt, pnp-webpack-plugin, url-loader

Son Versiyona Çekilen Eklentiler: @svgr/webpack, babel-preset-react-app, case-sensitive-paths-webpack-plugin, fork-ts-checker-webpack-plugin, eslint-webpack-plugin, html-webpack-plugin, mini-css-extract-plugin, react-dev-utils, terser-webpack-plugin, ts-loader, webpack, webpack-bundle-analyzer, webpack-dev-server, webpack-manifest-plugin

Webpack Dev Server

Webpack 5 ile uyumluluk açısından webpack-dev-server kütüphanesinin de versiyon 4'e yükseltilmesi gerekiyor. Aksi takdirde zaman zaman beliren Failed to compile. hatası ve hot-reload özelliğini kaybediyorsunuz.

Öncelikle webpack-dev-server versiyonunu 3.11.2 den 4.0.0-beta.2 ye yükseltelim.

npm install webpack-dev-server@4.0.0-beta.2 --save-dev

ya da

yarn add -D webpack-dev-server@4.0.0-beta.2

Sadece paket versiyonu yükseltme ile işimiz bitmiyor. Webpack dev server webpack 5 ile uyumlu olmakla kalmamış, konfigürasyonlarında sadeliğe gitmiş ve bir çok iyileştirme yapmış. Aşağıda detaylıca açıklayacağım bu değişikliklerin konfigürasyon dosyasında yaptığı değişiklikleri görebilirsiniz.

webpack-dev-server versiyon 3.* konfigürasyon dosyası örneği:

webpack-dev-server versiyon 4.* konfigürasyon dosyası örneği:

webpack-dev-server 4 ile gelen değişiklikler:

  • Minimum desteklenen Node versiyonu 10'a yükseldi.
  • hot seçeneği varsayılan olarak açık işaretlendi.
  • hotOnly seçeneği kaldırıldı. Bu mod için hot: 'only' tercihini kullanabilirsiniz.
  • Varsayılan transportMode sockjs den ws e çevrildi.
  • before , after ve setup seçenekleri kaldırıldı. Bunlar yerine onBeforeSetupMiddleware(önceki before) ve onAfterSetupMiddleware(önceki after) geldi.
  • clientOptions seçeneği client olarak değiştirildi.
  • key , cert , pfx , pfx-passphrase , cacert ve requestCert seçenekleri https seçeneğinin altına taşındı.
  • sockHost , sockPath ve sockPort seçenekleri client dan kaldırıldı.
  • inline seçeneği kaldırıldı.
  • lazy ve filename seçenekleri kaldırıldı.
  • features seçeneği kaldırıldı.
  • log , logLevel , logTime , noInfo , quiet , reporter ve warn seçenekleri kaldırıldı. Bu seçeneklerin sağladığı özellikler webpack’in gömülü loglama sistemiyle elde edilebilir. Şu yazıyı okuyup loglamayı kurup etkinleştirebilirsiniz.
  • fs , index , mimeTypes , publicPath , serverSideRender ve writeToDisk seçenekleri dev seçeneğinin altına taşındı.
  • stats seçeneği kaldırıldı. webpack konfigürasyonundaki stat seçeneğiyle gerekli ayarlamalar yapılabilir.
  • socket seçeneği kaldırıldı.
  • contentBase , contentBasePublicPath , serveIndex , staticOptions , watchContentBase , watchOptions seçenekleri yeni static seçeneği altına alındı.
  • disableHostCheck ve allowedHosts seçenekleri yeni firewall seçeneği altına taşındı.
  • server.listen() eğer bir port ayarlanmamış veya arguman olarak verilmemişse, müsait bir portu kendisi bulacaktır.
  • progress seçeneği client seçeneğinin altına taşındı.
  • profile seçeneği kaldırıldı. Profil verisini yazdırmak için client: { progress: 'profile' } ayarlamasını yapabilirsiniz.

Tüm bunları düzenledikten sonra bir ufak düzenleme daha yapmanız gerekebilir. Bilinen bir bug olan;

TypeError: message.split is not a function

hatasıyla karşılaşabilirsiniz. Bu hata webpack 5 güncellemesine henüz adapte olamamış react-dev-utils kütüphanesi ile alakalı. Daha sonra düzeleceği kesin olsa da bu geçiş döneminde bir workaround çözüm oluşturduk.

Öncelikle npm scriptlerinizi oluşturduğunuz klasörün içerisinde postinstall.js dosyası oluşturun ve içerisine şunu ekleyin;

Daha sonra bunu npm install sonrası çalışması üzere package.json scriptlerine ekleyin.

"scripts": {
...
"postinstall": "node scripts/postinstall.js",...
},

Her npm bağımlılıklarını yüklediğinizde bu script gerekli düzeltmeyi yapıp probleminizi çözmüş olacaktır.

Peki bu değişiklik ne gibi bir fayda sağladı ?

Aşağıda kendi projemiz olan Maestro üzerinde Webpack versiyon 4'den 5'e yükseltmenin(TypeScript versiyonu da 3'den 4'e alındı fakat performans olarak bir etkisi olduğunu pek düşünmüyorum) performans indikatörleri üzerinde yaptığı değişiklikleri paylaşıyorum. İndikatörlerin yanı sıra hissedilebilir bir son kullanıcı ve geliştirici deneyimi iyileşmesi olduğu aşikar.

Webpack 4.* + TypeScript 3.* Lighthouse Values
Webpack 5.* + TypeScript 4.2.* Lighthouse Values

Webpack 5 ilk duyduğumda bende yarattığı heyecanın karşılığını vermiş gözüküyor. Ayrıca sağladığı yeni altyapı ile daha keskin gelişmelere olanak sağlayacak gibi.

Bu versiyon yükseltmesi görüldüğü kadar sancılı olmayabilir. Hatta eski versiyonlarda kalmış kütüphanelerinizin güncellenmesi adına iyi bir fırsat olduğunu düşünüyorum.

Kaynaklar
https://webpack.js.org/blog/2020-10-10-webpack-5-release/
https://webpack.js.org/migrate/5/
https://frontend-digest.com/whats-new-in-webpack-5-ef619bb74fae

--

--

Mucahit Gurbuz
Mucahit Gurbuz

Written by Mucahit Gurbuz

Software Engineer at Babbel working mostly with React with TypeScript — Cutting Edges