Vite'in eklenti mimarisini keşfedin ve geliştirme iş akışınızı iyileştirmek için özel eklentiler oluşturmayı öğrenin. Küresel bir kitle için pratik örneklerle temel kavramlarda ustalaşın.
Vite Eklenti Mimarisi Gizemini Çözmek: Özel Eklenti Oluşturmak için Küresel Bir Rehber
Yıldırım hızındaki derleme aracı Vite, frontend geliştirmede devrim yarattı. Hızı ve basitliği büyük ölçüde güçlü eklenti mimarisinden kaynaklanmaktadır. Bu mimari, geliştiricilerin Vite'in işlevselliğini genişletmesine ve özel proje ihtiyaçlarına göre uyarlamasına olanak tanır. Bu rehber, Vite'in eklenti sistemine kapsamlı bir bakış sunarak, kendi özel eklentilerinizi oluşturmanıza ve geliştirme iş akışınızı optimize etmenize olanak sağlar.
Vite'in Temel Prensiplerini Anlamak
Eklenti oluşturmaya dalmadan önce, Vite'in temel prensiplerini kavramak önemlidir:
- İsteğe Bağlı Derleme: Vite, kodu yalnızca tarayıcı tarafından talep edildiğinde derler, bu da başlangıç süresini önemli ölçüde azaltır.
- Doğal ESM: Vite, geliştirme için doğal ECMAScript modüllerini (ESM) kullanır, bu da geliştirme sırasında paketleme ihtiyacını ortadan kaldırır.
- Rollup Tabanlı Production Derlemesi: Production derlemeleri için Vite, verimli ve üretime hazır kod oluşturmak için son derece optimize edilmiş bir paketleyici olan Rollup'ı kullanır.
Vite Ekosisteminde Eklentilerin Rolü
Vite'in eklenti mimarisi son derece genişletilebilir olacak şekilde tasarlanmıştır. Eklentiler şunları yapabilir:
- Kodu dönüştürmek (örn. TypeScript'i dönüştürmek, ön işlemciler eklemek).
- Özel dosyalar sunmak (örn. statik varlıkları işlemek, sanal modüller oluşturmak).
- Derleme sürecini değiştirmek (örn. resimleri optimize etmek, service worker'lar oluşturmak).
- Vite'in CLI'ını genişletmek (örn. özel komutlar eklemek).
Eklentiler, Vite'i basit modifikasyonlardan karmaşık entegrasyonlara kadar çeşitli proje gereksinimlerine uyarlamanın anahtarıdır.
Vite Eklenti Mimarisine Derinlemesine Bir Bakış
Bir Vite eklentisi, temel olarak davranışını tanımlayan belirli özelliklere sahip bir JavaScript nesnesidir. Anahtar unsurları inceleyelim:
Eklenti Yapılandırması
vite.config.js
(veya vite.config.ts
) dosyası, hangi eklentilerin kullanılacağını belirtmek de dahil olmak üzere Vite projenizi yapılandırdığınız yerdir. plugins
seçeneği, eklenti nesneleri veya eklenti nesneleri döndüren fonksiyonlardan oluşan bir dizi kabul eder.
// vite.config.js
import myPlugin from './my-plugin';
export default {
plugins: [
myPlugin(), // Eklenti örneği oluşturmak için eklenti fonksiyonunu çağırın
],
};
Eklenti Nesnesi Özellikleri
Bir Vite eklenti nesnesi, derleme sürecinin farklı aşamalarındaki davranışını tanımlayan birkaç özelliğe sahip olabilir. İşte en yaygın özelliklerin bir dökümü:
- name: Eklenti için benzersiz bir isim. Bu gereklidir ve hata ayıklama ve çakışma çözümüne yardımcı olur. Örnek:
'my-custom-plugin'
- enforce: Eklentinin yürütme sırasını belirler. Olası değerler
'pre'
(çekirdek eklentilerden önce çalışır),'normal'
(varsayılan) ve'post'
(çekirdek eklentilerden sonra çalışır). Örnek:'pre'
- config: Vite'in yapılandırma nesnesini değiştirmeye olanak tanır. Kullanıcı yapılandırmasını ve ortamı (mod ve komut) alır. Örnek:
config: (config, { mode, command }) => { ... }
- configResolved: Vite yapılandırması tamamen çözümlendikten sonra çağrılır. Son yapılandırma nesnesine erişmek için kullanışlıdır. Örnek:
configResolved(config) { ... }
- configureServer: Geliştirme sunucusu örneğine (Connect/Express benzeri) erişim sağlar. Özel ara yazılım eklemek veya sunucu davranışını değiştirmek için kullanışlıdır. Örnek:
configureServer(server) { ... }
- transformIndexHtml:
index.html
dosyasını dönüştürmeye olanak tanır. Betikler, stiller veya meta etiketleri eklemek için kullanışlıdır. Örnek:transformIndexHtml(html) { ... }
- resolveId: Modül çözümlemesini engellemeye ve değiştirmeye olanak tanır. Özel modül çözümleme mantığı için kullanışlıdır. Örnek:
resolveId(source, importer) { ... }
- load: Özel modülleri yüklemeye veya mevcut modül içeriğini değiştirmeye olanak tanır. Sanal modüller veya özel yükleyiciler için kullanışlıdır. Örnek:
load(id) { ... }
- transform: Modüllerin kaynak kodunu dönüştürür. Bir Babel eklentisine veya PostCSS eklentisine benzer. Örnek:
transform(code, id) { ... }
- buildStart: Derleme sürecinin başında çağrılır. Örnek:
buildStart() { ... }
- buildEnd: Derleme süreci tamamlandıktan sonra çağrılır. Örnek:
buildEnd() { ... }
- closeBundle: Paket diske yazıldıktan sonra çağrılır. Örnek:
closeBundle() { ... }
- writeBundle: Paket diske yazılmadan önce çağrılır ve değiştirilmesine olanak tanır. Örnek:
writeBundle(options, bundle) { ... }
- renderError: Geliştirme sırasında özel hata sayfaları oluşturmaya olanak tanır. Örnek:
renderError(error, req, res) { ... }
- handleHotUpdate: HMR üzerinde ayrıntılı kontrol sağlar. Örnek:
handleHotUpdate({ file, server }) { ... }
Eklenti Kancaları ve Yürütme Sırası
Vite eklentileri, derleme sürecinin farklı aşamalarında tetiklenen bir dizi kanca (hook) aracılığıyla çalışır. Bu kancaların hangi sırayla yürütüldüğünü anlamak, etkili eklentiler yazmak için hayati önem taşır.
- config: Vite yapılandırmasını değiştirin.
- configResolved: Çözümlenmiş yapılandırmaya erişin.
- configureServer: Geliştirme sunucusunu değiştirin (yalnızca geliştirme).
- transformIndexHtml:
index.html
dosyasını dönüştürün. - buildStart: Derleme sürecinin başlangıcı.
- resolveId: Modül ID'lerini çözümleyin.
- load: Modül içeriğini yükleyin.
- transform: Modül kodunu dönüştürün.
- handleHotUpdate: Anında Modül Değişimini (HMR) yönetin.
- writeBundle: Çıktı paketini diske yazmadan önce değiştirin.
- closeBundle: Çıktı paketi diske yazıldıktan sonra çağrılır.
- buildEnd: Derleme sürecinin sonu.
İlk Özel Vite Eklentinizi Oluşturma
Production derlemesindeki her JavaScript dosyasının en başına bir banner ekleyen basit bir Vite eklentisi oluşturalım. Bu banner proje adını ve sürümünü içerecektir.
Eklenti Uygulaması
// banner-plugin.js
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
export default function bannerPlugin() {
return {
name: 'banner-plugin',
apply: 'build',
transform(code, id) {
if (!id.endsWith('.js')) {
return code;
}
const packageJsonPath = resolve(process.cwd(), 'package.json');
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
const banner = `/**\n * Project: ${packageJson.name}\n * Version: ${packageJson.version}\n */\n`;
return banner + code;
},
};
}
Açıklama:
- name: Eklentinin adını, 'banner-plugin' olarak tanımlar.
- apply: Bu eklentinin yalnızca derleme işlemi sırasında çalışması gerektiğini belirtir. Bunu 'build' olarak ayarlamak, onu yalnızca production için yapar ve geliştirme sırasında gereksiz yükü önler.
- transform(code, id):
- Bu eklentinin çekirdeğidir. Her modülün kodunu (
code
) ve kimliğini (id
) yakalar. - Koşullu Kontrol:
if (!id.endsWith('.js'))
, dönüşümün yalnızca JavaScript dosyalarına uygulanmasını sağlar. Bu, diğer dosya türlerinin (CSS veya HTML gibi) işlenmesini önler, bu da hatalara veya beklenmedik davranışlara neden olabilir. - Package.json Erişimi:
resolve(process.cwd(), 'package.json')
,package.json
dosyasına mutlak yolu oluşturur.process.cwd()
, geçerli çalışma dizinini döndürerek, komutun nerede yürütüldüğünden bağımsız olarak doğru yolun kullanılmasını sağlar.JSON.parse(readFileSync(packageJsonPath, 'utf-8'))
,package.json
dosyasını okur ve ayrıştırır.readFileSync
dosyayı eşzamanlı olarak okur ve'utf-8'
, Unicode karakterlerini doğru şekilde işlemek için kodlamayı belirtir. Eşzamanlı okuma, dönüşümün başlangıcında bir kez gerçekleştiği için burada kabul edilebilir.
- Banner Oluşturma:
const banner = `/**\n * Project: ${packageJson.name}\n * Version: ${packageJson.version}\n */\n`;
banner dizesini oluşturur. Proje adını ve sürümünüpackage.json
dosyasından kolayca gömmek için şablon değişmezleri (backtick'ler) kullanır.\n
dizileri, banner'ı doğru şekilde biçimlendirmek için yeni satırlar ekler.*
,\*
ile kaçış karakteri kullanılmıştır.
- Kod Dönüşümü:
return banner + code;
banner'ı orijinal JavaScript kodunun başına ekler. Bu, transform fonksiyonu tarafından döndürülen nihai sonuçtur.
- Bu eklentinin çekirdeğidir. Her modülün kodunu (
Eklentiyi Entegre Etme
Eklentiyi vite.config.js
dosyanıza aktarın ve plugins
dizisine ekleyin:
// vite.config.js
import bannerPlugin from './banner-plugin';
export default {
plugins: [
bannerPlugin(),
],
};
Derlemeyi Çalıştırma
Şimdi, npm run build
(veya projenizin derleme komutunu) çalıştırın. Derleme tamamlandıktan sonra, dist
dizinindeki oluşturulan JavaScript dosyalarını inceleyin. Her dosyanın en başında banner'ı göreceksiniz.
İleri Düzey Eklenti Teknikleri
Basit kod dönüşümlerinin ötesinde, Vite eklentileri yeteneklerini geliştirmek için daha gelişmiş tekniklerden yararlanabilir.
Sanal Modüller
Sanal modüller, eklentilerin diskte gerçek dosyalar olarak bulunmayan modüller oluşturmasına olanak tanır. Bu, dinamik içerik oluşturmak veya uygulamaya yapılandırma verileri sağlamak için kullanışlıdır.
// virtual-module-plugin.js
export default function virtualModulePlugin(options) {
const virtualModuleId = 'virtual:my-module';
const resolvedVirtualModuleId = '\0' + virtualModuleId; // Rollup'ın işlemesini önlemek için \0 ile ön ekleyin
return {
name: 'virtual-module-plugin',
resolveId(id) {
if (id === virtualModuleId) {
return resolvedVirtualModuleId;
}
},
load(id) {
if (id === resolvedVirtualModuleId) {
return `export default ${JSON.stringify(options)};`;
}
},
};
}
Bu örnekte:
virtualModuleId
, sanal modülün tanımlayıcısını temsil eden bir dizedir.resolvedVirtualModuleId
, Rollup'ın onu gerçek bir dosya olarak işlemesini önlemek için\0
ile ön eklenmiştir. Bu, Rollup eklentilerinde kullanılan bir kuraldır.resolveId
, modül çözümlemesini engeller ve istenen IDvirtualModuleId
ile eşleşirse çözümlenmiş sanal modül ID'sini döndürür.load
, modül yüklemesini engeller ve istenen IDresolvedVirtualModuleId
ile eşleşirse modülün kodunu döndürür. Bu durumda,options
nesnesini varsayılan olarak dışa aktaran bir JavaScript modülü oluşturur.
Sanal Modülü Kullanma
// vite.config.js
import virtualModulePlugin from './virtual-module-plugin';
export default {
plugins: [
virtualModulePlugin({ message: 'Hello from virtual module!' }),
],
};
// main.js
import message from 'virtual:my-module';
console.log(message.message); // Çıktı: Hello from virtual module!
Index HTML'i Dönüştürme
transformIndexHtml
kancası, betikler, stiller veya meta etiketleri eklemek gibi index.html
dosyasını değiştirmenize olanak tanır. Bu, analiz izleme eklemek, sosyal medya meta verilerini yapılandırmak veya HTML yapısını özelleştirmek için kullanışlıdır.
// inject-script-plugin.js
export default function injectScriptPlugin() {
return {
name: 'inject-script-plugin',
transformIndexHtml(html) {
return html.replace(
'