Vue Component Paketi Oluşturma ve Nexus’ta Yayınlamak

Ediz Ağarer
TeamDefineX
Published in
9 min readJan 3, 2024

Giriş

Günümüzde geliştirilen birçok önyüz uygulaması component bazlı yapılar kullanmaktadır. Tekrar kullanılabilirlik, kod tekrarlarından kaçınmak ve bakımının kolaylığı gibi avantajlar component bazlı yapıları cazip hale getirmiştir. Bununla beraber bu yapılar da dikensiz gül bahçesi değildir. Component’lerin dağıtımı konusu component kullanımıyla beraber yaşanabilecek zorlukların başında gelir. Component’lerin oluşturulup yayınlanması, component’lerin yeniden kullanılabilirliği için önemli olduğundan bu yazımda component’lerin oluşturulması, yayınlanması ve tekrar tekrar kullanılabilmesi konularını, aşağıdaki Genel Bakış resminde görülebileceği gibi, belli bir akış üzerinden ele alacağım. Buna göre, öncelikle component’leri oluşturacağım ve bunun için vuejs kullanacağım. Ardından componenti npm paketi yapıp yayınlayacağım. Bu npm paketini depolamak için ise nexus’u kullanacağım. Son olarak da bu npm paketini bir vue projesine import etme işlemini ele alacağım.

Genel Bakış

Başlamadan önce component kullanımının avantajlarına ve zorluklarına kısaca değinmek istiyorum.

Component Kullanımının Avantajları ve Zorlukları

Projemiz içerisinde o uygulamaya özel birçok component geliştiririz. Bu component’leri de aynı proje içerisinde tekrar tekrar farklı yerlerde kullanırız. Ancak başka bir projeye geçtiğimiz zaman benzer component’lerin bu projede de ihtiyaç olduğunu fark ederiz.

Bu durumda iki seçeneğimiz olur:

1. Diğer projemizden ihtiyaç duyduğumuz component’leri kopyalarız.

2. Ortak bir kütüphane mantığı ile bir yerde tutarız.

İlk seçenek hem profesyonel değil hem de bağımlılıkları yönetebilmek açısından zorluklar içerir. Bu durumda ikinci seçenek yani ortak bir yerde tutarak diğer projelerimizde de kullanılmasını sağlayabiliriz.

Component’leri ortak bir yerde tutarak diğer projelerimizde de kullanılmasını sağlamak için iki çözüm yolu sunacağım:

1. Component’lerimizi npm paket depolama hizmeti veren bir uygulamada tutabiliriz. Bunun için npm sitesinde bir hesap açıp paketlerimizi burada depolayabiliriz. Ancak, paketlerimizi kimsenin görmesini istemiyorsak bunları private yapmalıyız. Bunun için de npm sitesinde bir limit var ve ücretli bir hesap açmanız gerekiyor.

2. Kendi sunucularımızda paket yönetimi için bir ürün kullanarak paketlerimizi depolayıp dağıtımını sağlayabiliriz. Bu seçenek, daha fazla kontrol ve esneklik sağlar. Ancak aynı zamanda daha fazla bakım ve yönetim maliyeti çıkarabilir.

Her iki seçeneğin de kendi avantajları ve dezavantajları vardır. Hangi çözümün sizin için en uygun olduğuna karar verirken, projenizin özel gereksinimlerini ve kaynaklarınızı göz önünde bulundurmanız önemlidir.

İlk Adım: Component’imizi Oluşturmak

Öncelikle, vue component oluşturmak için “my-card” adında projemizi oluşturalım:

vue create my-card

Projemizi oluşturulduktan sonra /src klasörü içinde “components” adında bir klasör oluşturalım. Bu klasörün altına da MyCard.vue isminde bir dosya ekleyelim. MyCard.vue dosyası şu şekilde yapılandırılmış olsun:

<template>
<div class="my-container">
{{msg}}
</div>
</template>

<script>
export default {
name: 'MyCard',
props: {
msg: String
}
}
</script>

<style>
.my-container {
background-color: #f2f2f2;
width: max-content;
box-sizing: border-box;
padding: 16px;
border-radius: 12px;
}
</style>

Bu Vue bileşeni, “MyCard” adını taşıyor ve bir prop (“msg”) alabiliyor. Bileşenin görünümü basit bir kutu içindeki metni içeriyor ve stil olarak arka plan rengi, genişlik, dolgu ve kenar yuvarlaklığı gibi özelliklere sahip. Bu bizim özel component’imiz.

Bu component’i npm paketi olarak yayınlamak için derlemeli ve tek bir Javascript dosyasına dönüştürmeliyiz. İlk olarak component’imizi bir .js dosyasının içine aktarmalıyız. Bu amaçla src/components.js adında bir dosya oluşturup component’imizi aşağıdaki gibi import edebiliriz.

import MyCard from './components/MyCard.vue'
export default { MyCard }

Burada dikkat edilmesi gereken nokta import ettiğimiz bu componenti aynı isimle export ediyor olmamak. Bu ileride işimize yarayacak. Not: Eğer birden fazla componenti yayınlamak istiyorsak hepsini bu dosya içerisine import etmeliyiz. Sonrasında bütün yayınlamak istediğimiz component’leri export objesi içine dahil edebiliriz.

Yayınlamak istediğimiz component(ler)i bir Vue plug-in’i altında toplamamız gerekiyor. Bunun için src/index.js dosyasını oluşturup içerisine aşağıdaki kodları yazabiliriz.

import components from './components'

const plugin = {
install (Vue) {
for (const prop in components) {
if (components.hasOwnProperty(prop)) {
const component = components[prop]
Vue.component(component.name, component)
}
}
}
}

export default plugin

Bu işlem, components.js dosyası içerisinden export edilen bütün component’leri isimleriyle birlikte Vue instance’ına kaydedecek bir kod içermektedir.

Şimdi bunu derlememiz gerekiyor. Bu işlem için ‘rollup’ aracını kullanacağım. Rollup genellikle JavaScript proje dosyalarınızı küçültmek (minify) ve birleştirmek için kullanılan bir JavaScript modül paketleme aracıdır. Şimdi rollup paketlerini yüklememiz gerekiyor:

npm i -D rollup rollup-plugin-vue rollup-plugin-peer-deps-external rollup-plugin-import-css

Yükleme işlemleri tamamlandıktan sonra rollup için bir config dosyası hazırlamamız gerekiyor. Bunun için projemizin kök dizinine rollup.config.js adında bir dosya oluşturup içerisine aşağıdaki kodları yazalım.

import vue from 'rollup-plugin-vue'
import peerDepsExternal from 'rollup-plugin-peer-deps-external'
import css from 'rollup-plugin-import-css'

export default [
{
input: 'src/index.js',
output: [
{
format: 'esm',
file: 'dist/library.mjs'
},
{
format: 'cjs',
file: 'dist/library.js'
}
],
plugins: [
vue({
css: true,
compileTemplate: true
}),
peerDepsExternal(),
css()
]
}
]

Burada dikkat etmemiz gereken nokta kullandığımız Vue versiyonu. Eğer Vue3 kullanıyorsanız yukarıdaki kod işinizi görecektir. Ancak, Vue2 kullananların rollup-plugin-vue yerine rollup-plugin-vue2’yi kurup import etmeleri gerektiğini hatırlatayım.

Rollup ile build almak için package.json içerisine “build” scriptini aşağıdaki şekilde ekliyoruz:

"scripts": {
"build": "rollup -c"
}

Build ve publish işlemleri için package.json içerisinde aşağıdaki alanların olması gerekmektedir:

{
"name": "@yourname/yourlibrary",
"version": "0.1.0",
"private": false,
"author": "Ediz Agarer",
"type": "module",
"main": "dist/library.js",
"module": "dist/library.mjs",
"files": [
"dist/*"
]
}

“name”: @yourname kısmı grubunuzu, yourlibrary kısmı library isminizi

“type”: “module” Bunun bir npm modulü olduğunu belirtiyor.

“main”: “dist/library.js”, Burası rollup.config.js dosyasındaki output formatlarından “cjs” olanının “file” bilgisi ile aynı olması gerekiyor.

“module”: “dist/library.mjs”, Burası rollup.config.js dosyasındaki output formatlarından “esm” olanının “file” bilgisi ile aynı olması gerekiyor.

“files”: Publish edilecek paketin içine dahil edilecek dosyaları belirliyoruz.

Artık derlemeye hazırız. Kök dizinine gelip, aşağıdaki komutu yazarak derlemeyi gerçekleştiriyoruz.

npm run build

Kök dizini altında /dist klasörünün oluştuğunu, içerisinde de library.mjs, library.js ve library.css dosyalarının yaratıldığını görmemiz gerekiyor.

Şimdi sıra paketlerimizi yayınlamak için kullanacağımız Nexus’un kurulumuna geldi.

Nexus Kurulumu

NPM paketlerimizi yayınlamak ve daha sonra başka projelerde de kullanabilmek amacıyla bu paketleri Nexus’ta depolayacağız. Bu işlemi gerçekleştirebilmek için öncelikle localinizde Docker’ın kurulu olduğu varsayımıyla aşağıdaki komutları kullanarak Nexus’u kuralım:

docker pull sonatype/nexus
docker run -d -p 8081:8081 --name my-npm sonatype/nexus3:latest

Kurulum tamamlandıktan sonra http://localhost:8081 adresine giderek admin kullanıcı girişi yapmalısınız. Default kullanıcı bilgileri ile (Kullanıcı adı: admin, Şifre: admin123) giriş yapıyoruz.

Blob Store Oluşturma

Paketlerimizi deploy etmek için öncelikli olarak blob-store’lar oluşturmamız gerekiyor. Nexus’a giriş yaptıktan sonra çark ikonuna tıklayarak sol taraftaki menüden Blob Stores sekmesine gidiyoruz. Buradan “Create Blob Store” butonuna tıklıyoruz. Açılan formdan sadece “name” alanını doldurmak yeterlidir. ‘npm-private’, ‘npm-registry’, ‘npm-group’ isimlerinde üç tane blob-store oluşturup kaydediyoruz.

Repositories Oluşturma

Paketlerimizi yayınlamak ve Nexus’ta depoladığımız paketleri kullanabilmek için repository’ler oluşturmalıyız. Bunun için Nexus’ta soldaki menüden “Repositories” sekmesine gidip “Create Repository” butonuna tıklıyoruz. Açılan repository seçeneklerinden 3 tanesi ile ilgileneceğiz. Resim 1’de bu üç repository’yi görüyorsunuz.

Resim 1

Öncelikle npm (hosted) seçeneğini seçiyoruz. Bu repository bizim özel component’lerimizi depolayacağımız bir repo olacak.

Resim 2

Resim 2’deki gibi bir ekran bizi karşılıyor. Burada isim olarak “npm-private”ı veriyoruz. Blob-store olarak daha önce oluşturduğumuz “npm-private” blob-store’unu seçip kaydediyoruz.

Daha sonra public npm paketlerini alabilmemiz için bir proxy reposu tanımlamamız gerekiyor. Menüden Repositories > “create repository” seçeneklerinden npm (proxy) seçeneğini belirleyip ilerliyoruz.

Resim 3

Resim 3’deki ekran bizi karşılıyor. Burada isim olarak “npm-registry” ve blob-store olarak önceden oluşturduğumuz aynı isimli “npm-registry” blob-store’u seçiyoruz. Remote storage olarak https://registry.npmjs.org adresini verip kaydediyoruz. Bu repo bizim public npm paketlerine ulaşmamız için proxy görevi görecek.

En son bu iki repoyu kapsayan bir grup reposu oluşturacağız. Bunun için menüden Repositories > “create repository” diyerek npm (group)’u seçip ilerliyoruz.

Resim 4

Resim 4’deki ekran karşımıza çıkacak. Burada isim olarak “npm-group” ve blob-store olarak “npm-group” seçiyoruz. Member repositories kısmında npm-private ve npm-registry repolarını seçip sağ tarafa ekliyoruz.

Group reposu için işlemler bu kadar. Artık “create repository” diyip işlemi tamamlayabiliriz. Bu repo’yu özel paketlerimizi kullanacak projeler için oluşturduk.

Not: Normalde bir npm paketini indirmek istediğimiz zaman, npm bu işlem için https://registry.npmjs.org adresine gider ve isteğimiz paketi bulur ve indirir. Ancak Nexus’ta sakladığımız özel paketlerimizi projemize import edebilmek için projemizde bazı konfigürasyonlar yapmamız gerekiyor (Bunu aşağıda daha sonra anlatacağım). Bu konfigürasyonlardan sonra projemiz herhangi bir npm paketini indirmek istediği zaman artık ilk başvuracağı adres Nexus server’ımız olacak. Nexus server’ımıza npm paketi indirme isteği geldiği zaman Nexus, npm-private altını kontrol edecektir. İstenilen paket npm-private altında mevcut mu? Mevcutsa paketin indirilme işlemi başlayacaktır. Eğer burada bu paket yoksa npm-registry (bu bir proxy; https://registry.npmjs.org) altını kontrol eder ve paket indirme işlemini gerçekleştirir.

Şimdi de paketleri publish etmek için yeni bir Nexus kullanıcısı oluşturalım. Bunun için menüden Users > “create user”u seçerek ilerleyelim. İsim, mail gibi alanları doldurduktan sonra Roles kısmından nx-admin rolünü vererek kullanıcıyı oluşturuyoruz.

Nexus sunucumuza herhangi birinin erişememesi için menüden Anonymous seçip Resim 5’te gösterilen “Allow anonymous users to Access the server” ifadesinin yanındaki tick’i kaldırıyoruz.

Resim 5

Paketleri sunucuya gönderebilmek için bir güvenlik ayarına daha ihtiyacımız var. Menüden Realms kısmına gidip Resim 6’da görülen “Nexus Authenticating Realm”, “Nexus Authorizing Realm” ve “npm Bearer Token Realm” yetkilerini veriyor ve kaydediyoruz.

Resim 6

Nexus yapılandırmalarımız tamamlandı. Şimdi yayınlamak istediğimiz paketimizin olduğu projeye gidilerek package.json’ı aşağıdaki gibi düzenliyoruz.

"publishConfig": {
"registry": "http://localhost:8081/repository/npm-private/"
}

Daha sonra projenin kök dizinindeyken terminalden npm login olmamız gerekiyor.

npm login --registry=http://localhost:8081/repository/npm-private/

Komut çalıştırılınca username, password ve email gibi bilgileri isteyecektir. Bu bilgileri Nexus’da az önce oluşturduğumuz admin kullanıcısının bilgileri ile dolduruyoruz. Burada dikkat etmemiz gereken husus /npm-private vermiş olmamız. Zira, bu repository adresi bizim özel paketlerimizin tutulacağı repoydu. Eğer herhangi bir hata alırsanız, C:\Users\<youruser> klasörü altındaki .npmrc dosyasını silip yukarıdaki login işlemini tekrar etmenizi öneriyorum.

Artık paketimizi Nexus’ta yayınlayabiliriz. Bunun için aşağıdaki komutu kullanıyoruz:

npm publish

Bu işlemden sonra Nexus’a gidip paket ikonuna tıklayınca soldaki menüden Components > npm-private a gidebilir ve buradan paketimizin geldiğini görebiliriz. Böylece, paket yayınlama işlemimiz tamamlandı ve aşağıdaki komutla bu admin kullanıcısından çıkış yapabiliriz.

npm logout --registry=http://localhost:8081/repository/npm-private/

NPM Paketinin Kullanımı

Sırada, Nexus’da yayınladığımız özel paketimizin kullanımı var. Bunun için öncelikle C:\Users\<youruser> altındaki .npmrc dosyasını silelim. Daha sonra paketi kullanmak istediğimiz projenin kök dizinine giderek .npmrc dosyası oluşturalım. İçerisine aşağıdaki tek satır komutu yazalım:

registry=http://localhost:8081/repository/npm-group/

Bu repo bizim özel paketlerimize ve npm sitesindeki public paketlere ulaşmamız için gerekli.

Şimdi yetkisi sadece bu paketleri okumak ile sınırlı bir kullanıcı oluşturalım. Bunun için yeni bir rol oluşturacağız. Nexus’da sol menüden Security > Roles > Create role diyerek ilerleyelim.

Resim 7

Bu rolün ismini npm-read-only olarak veriyorum (Bkz. Resim 7). Privileges olarak sadee browse ve read yetkilerini veriyorum ve kaydedip rolü oluşturuyorum. Az sonra yeni oluşturacağımız kullanıcıyı bu rolü vereceğiz. Bunun için kullanıcı oluşturma ekranına gidiyoruz:

Resim 8

Resim 8’deki ekran bizi karşılıyor. Burada “npm-consumer” adında bir kullanıcı oluşturuyorum. Rol olarak az önce oluşturduğumuz npm-read-only rolünü veriyorum. Kaydedip kullanıcı oluşturma işlemini tamamlıyorum.

Artık nexus’taki ayarlarımız tamam. Şimdi sıra bu paketleri kullanacağımız projeyi ayarlamaya geldi. Nexus URL’imizi .npmrc içine yazmıştık. Şimdi bu nexus serverdan paket indirebilmek için oluşturduğumuz kullanıcı ile npm login işlemi yapmamız gerekiyor. Nexus’taki paketlerimizi kullanacağımız projenin kök dizinine tekrardan gelip terminalden aşağıdaki komut ile login oluyorum:

npm login --registry=http://localhost:8081/repository/npm-group/

Komutu girdikten sonra kullanıcı bilgilerini soracaktır. En son oluşturduğumuz npm-consumer kullanıcısının bilgilerini gireceğiz. Login işlemini başarılı bir şekilde yaptıktan sonra kontrol etmek için C:\Users\<username> altındaki .npmrc dosyasının içine bakalım. Bu dosyanın içinde aşağıdaki gibi ifadelerin olması gerekiyor.

//localhost:8081/repository/npm-group/:_authToken=72bd9630-9d00-3497-8a67-20207bd48a36

Buradaki authToken kısmını kopyalıyıp projenin kök dizininde oluşturduğumuz .npmrc dosyasının içine aşağıdaki gibi ekliyoruz. Proje içerisinde .npmrc dosyası oluşturmamızın amacı sonrasında tekrar login olmaya ihtiyaç duymamak içindir.

registry=http://localhost:8081/repository/npm-group/
_authToken=72bd9630-9d00-3497-8a67-20207bd48a36

İşlemimiz bitti. Artık bu kullanıcıdan çıkış yapabiliriz.

npm logout - registry=http://localhost:8081/repository/npm-group/

Paketimizin Projeye Dahil Edilmesi

Paketimizi kurmak için aşağıdaki komutu çalıştırıyoruz.

npm i @yourname/yourlibrary

Projenin src klasörü altındaki main.js içerisine aşağıdaki şekilde import edip vue instance’ına plug-in’imizi kaydedelim:

import '@yourname/yourlibrary/dist/library.css'
import plugin from '@yourname/yourlibrary'

.
.
.

const app = createApp(App)
app.use(plugin)

Component’imizi istediğimiz zaman aşağıdaki gibi kullanabiliriz.

<MyCard msg="test mesajı"/>

Sonuç:

Bu yazıda Vue ile component oluşturmayı, bunu bir npm paketi haline dönüştürmeyi, bu paketleri private Nexus sunucusunda depolayıp tekrar kullanabilmeyi görmüş olduk. Component paketleri oluşturma, yönetme ve daha sonra tekrar bu paketleri kullanabilmeyi sağlamış olduk.

Kaynaklar

--

--