Henüz vite eklentisi nasıl yazılır bilmiyor musunuz?

Artık vite araçları popülerleştiğine göre, vite eklentisi yazmak gibi anlamlı bir şey yapabilir miyiz, ne dersiniz?
Tam da bu noktada vite eklenti ekosisteminin henüz gelişmekte olan aşamasından faydalanabilir, hem kendimizi hem liderleri hem de topluluğu memnun edecek bir eklenti geliştirebilir ve birlikte büyütebiliriz.
vite ile ilgileniyorsanız şu bölüme göz atabilirsiniz: "Girişten Ustalığa Vite"
Bu makaleden şunları öğrenebilirsiniz:

vite eklenti şablonu oluşturma
vite eklentisindeki her kancanın rolü
vite eklentisi kanca yürütme sırası
Kendi eklentinizi yazma yöntemi

vite eklentileri hakkında bilgi edinin
1. vite eklentisi nedir
vite aslında yerel ES Module tarafından desteklenen yeni bir ön uç web geliştirme aracıdır.
vite eklentisi, dosya görsel sıkıştırma, commonjs desteği, paketleme ilerleme çubuğu gibi vite'ın kendi başına yapamadığı işlevleri etkili şekilde genişletebilir.
2. Neden vite eklentisi yazmalıyız?
Buradaki herkesin artık webpack yapılandırması ve yaygın eklentilere aşina olduğuna inanıyorum.
Yeni bir ön uç derleme aracı olarak vite hâlâ genç ve genişletilebilirlik açısından zengindir; öyleyse neden şimdi onunla birlikte ilerlemeyelim? Sizin, benim ve herkes için daha anlamlı bir şeyler yapalım mı?
Hızlı deneyim
Bir eklenti yazmak istiyorsanız işe bir proje oluşturarak başlamalısınız. Aşağıdaki genel vite eklenti şablonunu gelecekte eklenti yazarken doğrudan klonlayarak kullanabilirsiniz.
Eklenti genel şablonu github: deneyim girişi
Eklenti github: deneyim girişi

Önerilen paket yöneticisi kullanım önceliği: pnpm > yarn > npm > cnpm

Uzatmadan, hemen işe koyulun.
vite eklentisi genel şablonu oluşturun
1. Başlatma
1.1 Bir klasör oluşturun ve başlatın: İstemleri takip ederek başlatın
mkdir vite-plugin-progress && cd vite-plugin-progress && pnpm init

1.2 typescript yükleyin
pnpm i typescript @types/node -D

1.3 tsconfig.json yapılandırması
{
"compilerOptions": {
"module": "ESNext",
"target": "esnext",
"moduleResolution": "node",
"strict": true,
"declaration": true,
"noUnusedLocals": true,
"esModuleInterop": true,
"outDir": "dist",
"lib": ["ESNext"],
"sourceMap": false,
"noEmitOnError": true,
"noImplicitAny": false
},
"include": [
"src/*",
"*.d.ts"
],
"exclude": [
"node_modules",
"examples",
"dist"
]
}

1.4 vite yükleyin
// package.json'a girin
{
...
"devDependencies": {
"vite": "*"
}
...
}

2. eslint ve prettier yapılandırın (isteğe bağlı)


eslint yükleyin
pnpm i eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin --save-dev



.eslintrc yapılandırması: bağlantıyı yapılandırın


prettier yükleyin (isteğe bağlı)
pnpm i prettier eslint-config-prettier eslint-plugin-prettier --save-dev



.prettierrc yapılandırması: bağlantıyı yapılandırın


3. src/index.ts giriş noktası ekleyin
import type { PluginOption } from 'vite';

export default function vitePluginTemplate(): PluginOption {
return {
// eklenti adı
name: 'vite-plugin-template',

// pre, post'tan önce çalıştırılır
enforce: 'pre', // post

// Yalnızca 'build' veya 'serve' modunda çağrıldıklarını belirtir
apply: 'build', // apply bir fonksiyon da olabilir

config(config, { command }) {
console.log('burası config kancası');
},

configResolved(resolvedConfig) {
console.log('burası configResolved kancası');
},

configureServer(server) {
console.log('burası configureServer kancası');
},

transformIndexHtml(html) {
console.log('burası transformIndexHtml kancası');
},
}
}

vite eklenti fonksiyonu kancaları aşağıda ayrıntılı olarak açıklanacaktır.
Bu noktada temel şablonumuz hazır, ancak şimdi düşünelim, bu eklentiyi nasıl çalıştırmalıyız?
O halde bu kodu çalıştırmak için bazı örnekler oluşturmamız gerekiyor.
4. examples dizini oluşturun
Burada üç farklı proje demosu oluşturdum. Bunları doğrudan kopyalayabilirsiniz, detaylı açıklamayacağım.

vite-react
vite-vue2
vite-vue3

Eklentinizin daha fazla demo çalıştırması gerekiyorsa projeyi kendiniz oluşturun.
Ardından examples altındaki projeyi, mevcut kök dizindeki eklentiyle ortak hata ayıklama yapacak şekilde yapılandırmamız gerekir (aşağıda examples/vite-vue3 örnek alınmıştır).
5. examples/vite-vue3 projesini yapılandırın


examples/vite-vue3/package.json dosyasını düzenleyin
{
...
"devDependencies": {
...
"vite": "link:../../node_modules/vite",
"vite-plugin-template": "link:../../"
}
}



Yukarıdakiler şu anlama gelir:


examples/vite-vue3 projesindeki vite sürümünü kök dizindeki vite-plugin-template sürümüyle tutarlı hale getirin.


Aynı zamanda examples/vite-vue3 projesindeki vite-plugin-template'i mevcut kök dizinde geliştirdiğiniz eklentiye yönlendirin.




Eklentiyi dahil edin: examples/vite-vue3/vite.config.ts
import template from 'vite-plugin-template';

export default defineConfig({
...
plugins: [vue(), template()],
...
});



Yükleyin: cd examples/vite-vue3 && pnpm install
cd examples/vite-vue3 && pnpm install




Not: examples/vite-vue2 ve examples/vite-react yapılandırması bununla aynıdır.

düşünün:
Bu noktada tekrar düşünelim. examples/vite-vue3 projesini yapılandırdık, peki nasıl çalıştırmalıyız?
Doğrudan examples/vite-vue3 dizinine gidip pnpm run build veya pnpm run dev mi çalıştıralım?
Bu açıkça başarılı olmaz, çünkü kök dizinimizdeki src/index.ts doğrudan çalıştırılamaz; bu yüzden .ts dosyasını .js dosyasına dönüştürmemiz gerekir.
Peki bunu nasıl hallederiz?
O halde küçük ve yapılandırma gerektirmeyen tsup aracını kullanmayı denemeliyiz.
6. tsup yükleyin ve çalıştırma komutunu yapılandırın
tsup, esbuild tarafından desteklenen hafif ve yapılandırma gerektirmeyen bir derleme aracıdır.
Aynı zamanda .ts, .tsx dosyalarını doğrudan esm, cjs, iife gibi farklı formatlara dönüştürebilir.


tsup yükleyin
pnpm i tsup -D



Kök dizindeki package.json içinde yapılandırın
{
...
"scripts": {
"dev": "pnpm run build -- --watch --ignore-watch examples",
"build": "tsup src/index.ts --dts --format cjs,esm",
"example:react": "cd examples/vite-react && pnpm run build",
"example:vue2": "cd examples/vite-vue2 && pnpm run build",
"example:vue3": "cd examples/vite-vue3 && pnpm run build"
},
...
}



7. Geliştirme ortamında çalıştırma


Geliştirme ortamı işlemi: dosya değişikliklerini gerçek zamanlı izleme ve yeniden paketleme (sıcak güncelleme)
pnpm run dev



examples altındaki herhangi bir projeyi çalıştırın (örnek olarak vite-vue3)
pnpm run example:vue3



Not:

Eklentiniz yalnızca derleme sırasında çalışacaksa "example:vue3": "cd examples/vite-vue3 && pnpm run build" olarak ayarlayın.
Aksi takdirde pnpm run dev çalıştırın.


çıktı:


Buradan itibaren geliştirme yaparken aynı anda çalıştırabilirsiniz. Gördüğünde çok havalı dedi.
8. Yayımlama

Sürüm kontrolü ve etiket eklemek için bumpp yükleyin

pnpm i bumpp -D


package.json yapılandırması

{
...
"scripts": {
...
"prepublishOnly": "pnpm run build",
"release": "npx bumpp --push --tag --commit && pnpm publish",
},
...
}


Eklentiyi geliştirdikten sonra yayımlama komutunu çalıştırın

# ilk adım
pnpm run prepublishOnly

# ikinci adım
pnpm run release

Böylece vite eklenti şablonumuz tamamlandı; kullanmak için vite-plugin-template şablonunu doğrudan klonlayabilirsiniz.
vite eklenti kancaları ve gerçek bir vite eklentisi uygulamakla ilgileniyorsanız aşağıyı okumaya devam edebilirsiniz.
vite için eklenti kancaları
1. vite'a özgü kancalar

enforce: değer pre veya post olabilir, pre post'tan önce çalıştırılır.
apply: değer build, serve veya bir fonksiyon olabilir; yalnızca build veya serve modunda çağrılmalarını belirtir.
config(config, env): vite ayrıştırılmadan önce vite ile ilgili yapılandırmayı değiştirebilirsiniz. Kanca, orijinal kullanıcı yapılandırması config ve yapılandırma ortamını tanımlayan env değişkenini alır.
configResolved(resolvedConfig): vite yapılandırması çözümlendikten sonra çağrılır. Nihai çözümlenen yapılandırmayı okuyup saklamak için bu kancayı kullanın. Eklentinin çalıştırılan komuta göre farklı işlem yapması gerektiğinde yararlıdır.
configureServer(server): esas olarak geliştirme sunucusunu yapılandırmak ve dev-server için özel ara katman eklemek amacıyla kullanılır (connect uygulaması).
transformIndexHtml(html): index.html dönüştürmeye özel kanca. Kanca mevcut HTML dizesini ve dönüştürme bağlamını alır.
handleHotUpdate(ctx): Özel HMR güncellemesi yürütür, ws üzerinden istemciye özel olaylar gönderebilirsiniz.

2. vite ve rollup için ortak kancaların derleme aşaması

options(options): sunucu başladığında çağrılır; Rollup seçeneklerini alır ve manipüle eder; kesin konuşmak gerekirse derleme aşamasından önce yürütülür.
buildStart(options): her derleme başladığında çağrılır.
resolveId(source, importer, options): gelen her modül isteği için çağrılır; üçüncü taraf bağımlılıkları konumlandırmak için kullanılabilecek özel bir doğrulama fonksiyonu oluşturur.
load(id): Gelen her modül isteği için çağrılır; yükleyici özelleştirilebilir ve özel içerik döndürmek için kullanılabilir.
transform(code, id): Gelen her modül isteğinde çağrılır; esas olarak tek bir modülü dönüştürmek için kullanılır.
buildEnd(): Derleme aşamasının sonunda çağrılır; burada derlemenin sonu tüm modüllerin dönüştürüldüğü anlamına gelir.

3. vite ve rollup genel kancasının çıktı aşaması

outputOptions(options): çıktı parametrelerini kabul eder.
renderStart(outputOptions, inputOptions): bundle.generate ve bundle.write her çağrıldığında tetiklenir.
augmentChunkHash(chunkInfo): parçaya hash eklemek için kullanılır.
renderChunk(code, chunk, options): Tek bir parça dönüştürüldüğünde tetiklenir. rollup her parça dosyası çıktısı verildiğinde çağrılır.
generateBundle(options, bundle, isWrite): bundle.write çağrısından hemen önce bu kancayı tetikler.
writeBundle(options, bundle): bundle.write çağrıldıktan ve tüm parçalar dosyaya yazıldıktan sonra writeBundle en sonda çağrılır.
closeBundle(): sunucu kapatıldığında çağrılır.

4. Eklenti kanca fonksiyonlarının yürütme sırası (aşağıda gösterildiği gibi)

5. Eklentilerin yürütme sırası

Takma Ad İşleme Takma Adı
Kullanıcı eklentisi enforce: 'pre' ayarı
vite çekirdek eklentisi
Kullanıcı eklentisi enforce ayarlanmamış
vite build eklentisi
Kullanıcı eklentisi enforce: 'post' ayarı
vite build post eklentileri (minify, manifesto, raporlama)

Bir vite eklentisi teslim edin
Aşağıda vite paketleme ilerleme çubuğu eklentisi örnek alınmıştır.

Eklenti adresi: github Beğendiyseniz yıldız ⭐️ vermeye hoş geldiniz
Eklenti resmi olarak vite tarafından dokümantasyona dahil edilmiştir: bağlantı adresi
Bu makalenin odak noktası bu eklentinin detaylı uygulama süreci olmadığından, burada yalnızca referansınız için kaynak kodu paylaşacağız. Detaylı tanıtım bir sonraki makalede açıklanacaktır, lütfen takipte kalın.

index.ts

import type { PluginOption } from 'vite';
import colors from 'picocolors';
import progress from 'progress';
import rd from 'rd';
import { isExists, getCacheData, setCacheData } from './cache';

type Omit = Pick>;
type Merge = Omit> & N;

type PluginOptions = Merge<
ProgressBar.ProgressBarOptions,
{
/**
* tamamlanacak toplam tik sayısı
* @default 100
*/
total?: number;

/**
* İlerleme çubuğunun formatı
*/
format?: string;
}
>;

export default function viteProgressBar(options?: PluginOptions): PluginOption {

const { cacheTransformCount, cacheChunkCount } = getCacheData()

let bar: progress;
const stream = options?.stream || process.stderr;
let outDir: string;
let transformCount = 0
let chunkCount = 0
let transformed = 0
let fileCount = 0
let lastPercent = 0
let percent = 0

return {
name: 'vite-plugin-progress',

enforce: 'pre',

apply: 'build',

config(config, { command }) {
if (command === 'build') {
config.logLevel = 'silent';
outDir = config.build?.outDir || 'dist';

options = {
width: 40,

...options
};
options.total = options?.total || 100;

const transforming = isExists ? `${colors.magenta('Transforms:')} :transformCur/:transformTotal | ` : ''
const chunks = isExists ? `${colors.magenta('Chunks:')} :chunkCur/:chunkTotal | ` : ''
const barText = `${colors.cyan(`[:bar]`)}`

const barFormat =
options.format ||
`${colors.green('Bouilding')} ${barText} :percent | ${transforming}${chunks}Time: :elapseds`

delete options.format;
bar = new progress(barFormat, options as ProgressBar.ProgressBarOptions);



// önbellek yoksa: src dizinindeki dosyaları döngüye al
if (!isExists) {
const readDir = rd.readSync('src');
readDir.forEach((item) => reg.test(item) && fileCount++);
}
}
},

transform(code, id) {
transformCount++

// önbellek yoksa
if(!isExists) {
const reg = /node_modules/gi;

if (!reg.test(id) && percent < 0.25) {
transformed++
percent = +(transformed / (fileCount * 2)).toFixed(2)
percent < 0.8 && (lastPercent = percent)
}

if (percent >= 0.25 && lastPercent <= 0.65) {
lastPercent = +(lastPercent + 0.001).toFixed(4)
}
}

// önbelleğe git
if (isExists) runCachedData()

bar.update(lastPercent, {
transformTotal: cacheTransformCount,
transformCur: transformCount,
chunkTotal: cacheChunkCount,
chunkCur: 0,
})

return {
code,
map: null
};
},

renderChunk() {
chunkCount++

if (lastPercent <= 0.95)
isExists ? runCachedData() : (lastPercent = +(lastPercent + 0.005).toFixed(4))

bar.update(lastPercent, {
transformTotal: cacheTransformCount,
transformCur: transformCount,
chunkTotal: cacheChunkCount,
chunkCur: chunkCount,
})

return null
},

closeBundle() {
// ilerlemeyi kapat
bar.update(1)
bar.terminate()

// önbellek verisini ayarla
setCacheData({
cacheTransformCount: transformCount,
cacheChunkCount: chunkCount,
})

// başarı mesajı çıktısı ver
stream.write(
`${colors.cyan(colors.bold(`Build successful. Please see ${outDir} directory`))}`
);
stream.write(' ');
stream.write(' ');
}
};

/**
* ilerlemenin önbellek verisini çalıştır
*/
function runCachedData() {

if (transformCount === 1) {
stream.write(' ');

bar.tick({
transformTotal: cacheTransformCount,
transformCur: transformCount,
chunkTotal: cacheChunkCount,
chunkCur: 0,
})
}

transformed++
percent = lastPercent = +(transformed / (cacheTransformCount + cacheChunkCount)).toFixed(2)
}
}



cache.ts

import fs from 'fs';
import path from 'path';

const dirPath = path.join(process.cwd(), 'node_modules', '.progress');
const filePath = path.join(dirPath, 'index.json');

export interface ICacheData {
/**
* Tüm dönüşüm sayısı
*/
cacheTransformCount: number;

/**
* tüm parça sayısı
*/
cacheChunkCount: number
}

/**
*Önbelleğe alınmış mı
* @return boolean
*/
export const isExists = fs.existsSync(filePath) || false;

/**
* Önbelleğe alınmış veriyi al
* @returns ICacheData
*/
export const getCacheData = (): ICacheData => {
if (!isExists) return {
cacheTransformCount: 0,
cacheChunkCount: 0
};

return JSON.parse(fs.readFileSync(filePath, 'utf8'));
};

/**
* Önbelleğe alınacak veriyi ayarla
* @returns
*/
export const setCacheData = (data: ICacheData) => {
!isExists && fs.mkdirSync(dirPath);
fs.writeFileSync(filePath, JSON.stringify(data));
};


son olarak
Bu seri sürekli güncellenecektir. "Girişten Ustalığa Vite" bölümünün tamamını esas olarak aşağıdaki açılardan açıklayacağım, lütfen takipte kalın.

Dostlar, buraya kadar gördünüz, beğenmeyi unutmayın 👍.markdown-body pre,.markdown-body pre>code.hljs{color:#333;background:#f8f8f8}.hljs-comment,.hljs- quote{color:#998;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#333;font-weight:700}.hljs-literal,.hljs-number ,.hljs-tag .hljs-attr,.hljs-template-variable,.hljs-variable{color:teal}.hljs-doctag,.hljs-string{color:#d14}.hljs-section,.hljs-selector -id,.hljs-title{color:#900;font-weight:700}.hljs-subst{font-weight:400}.hljs-class .hljs-title,.hljs-type{color:#458;font -weight:700}.hljs-attribute,.hljs-name,.hljs-tag{color:navy;font-weight:400}.hljs-link,.hljs-regexp{color:#009926}.hljs-bullet, .hljs-symbol{color:#990073}.hljs-built_in,.hljs-builtin-name{color:#0086b3}.hljs-meta{color:#999;font-weight:700}.hljs-deletion{background: #fdd}.hljs-addition{background:#dfd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} Kategori: Ön uç Etiketler: Ön uç Vite Makaleler şu bölüme dahildir:
Girişten Ustalığa Vite

Vite (telaffuzu [weɪt] benzeri, hafif, ışık anlamına gelir) yerel ES Module tarafından desteklenen bir web geliştirme ön uç derleme aracıdır.
Aşağıdaki özelliklere sahiptir:
💡 Son derece hızlı hizmet başlatma;
⚡️ Hafif ve hızlı sıcak yeniden yükleme;
🛠️ Zengin işlevler;
📦 Optimize edilmiş derleme;
🔩 Evrensel eklenti;
🔑 Tamamen tipli API.

İlgili Makaleler

Daha Fazla Özel Teklifi Keşfedin

  1. Kısa Mesaj Servisi (SMS) & E-posta Hizmeti

    50.000 e-posta paketi 1,99 USD'den, 120 kısa mesaj ise sadece 1,00 USD'den başlar.

phone Bize Ulaşın
Hi, I'm Alibaba Cloud AI Assistant!
I can help with questions and solutions.