Photo by Jenny Hill on Unsplash

REACT MODULES

React Bileşenleri Oluşturmak — (NPM Link)

Bu yazıda amacımız projemiz içerisindeki bileşenleri Local Makine’de (NPM Link) kullanarak diğer projelerde de kullanabilir hale getirmek.

5 min readAug 29, 2022

--

Bazen bir kod parçası, bazende bir bileşeni NPM publish etmeden nasıl ortak bir NPM Modülü haline getirebilirizi inceleyeceğiz.

Bu durumun farklı farklı nedenleri olabilir, Ben 2 tanesinden bahsedeyim;

  • İnternete kapalı bir ortamda geliştirme yapıyorsunuz veya private bir ortam sağlamak istiyorsunuz.
  • Veya kütüphane haline getireceğiniz bileşeni geliştirinceye kadar farklı farklı projelerinizde deneyim, iyice olgunlaştıktan sonra NPM Publish etmeyi düşünüyorsunuz.

Bu gibi durumların çözümü NPM Link . den söz etmek gerekirse. Siz React projenizde kullanmak istediğiniz kütüphaneleri npm üzerinde install ile node_modules altına indirir ve package.json bu modüllerin kontrolünü sağlarsınız. npm install sırasında paketleri indirebileceğiniz 3 kısım bulunur.

  • dependencies : Projenizin çalışması için ihtiyaç duyduğunuz modül bağımlılıkları ve versiyonlarını tutar.
  • devDependencies: Proje geliştirme ortamının ihtiyaç duyduğu Babel, SaSS Loader, ESLint vb.. modüllerin tanımlandığı kısımlardır.
  • peerDependencies: Proje içerisinde bağımlılık kurulan modüllerin direk olarak kullanılmamasını saglar. Bazı modüller , bağımlılık kurduğumuz diğer modüllerinde kullandığı kütüphaneler olabilir. Bu durumda eğer kullanılıyorsa yenisinin yüklenmesini engelleyecek bu paketlerin bir şekilde versiyon uyumunu kontrol edebildiğiniz dependency kısmıdır.

NPM Link Nasıl Çalışır ?

NPM link aslında sizin node projeniz için sanal bir node modüle linki oluşturarak bunu Global olarak diğer projelerin kullanmasına olanak sağlar.

Adım1: Ortak modül veya ortak bileşenin olduğu projenize gidip npm link çalıştırın ve globalden erişilebilen ve projenize işaret eden bir link oluşur.

Adım 2: Basit bir React Projesi Oluşturalım. Ve bu proje içerisinden bu ortak sınıfı kullanmak isteyelim. npm link package ismi veriyoruz ve artık geliştirdiğimiz projeye modülü linklemiş olduk.

Ortak kullandığımız bir modüle ekleme yaptığımızda, herhangi bir dosyada değişiklik olduğunda bunu kullanan proje direk olarak görecek , böylece versiyon güncelleme ve yayınlama gibi işlemler ile uğraşmadan projemizde güncellemeleri direk deneyebiliriz.

React Bileşenleri Oluşturup Bunu Bir Kütüphane Olarak Paylaşabilir miyiz ?

Bunu cra(create-react-app) ile oluşturduğumuz projeler üzerinden geliştirelim. Bu kısımda 3 proje geliştireceğiz;

  • Comp_AAA: Bileşenlerin(CounterClass ve CounterHook) yer aldığı proje
  • Proj_AAA ve Proj_AAA2 : Projelerinde CompA içerisindeki bileşenleri kullanmak istiyoruz.
Kullanım Senaryosu Şeması

Comp_AAA kısmını Oluşturalım

npx create-react-app comp_aaa // projemizi oluşturalım.

Daha sonrasında bunun içerisinde 2 tane bileşen oluşturalım;

  • CounterClass: Class Component ile oluşturulmuş Counter
  • CounterHook: Hook ile oluşturulmuş Counter
  • Bu bileşenleri oluşturduktan sonra App.js içerisinden bu bileşenleri import ederek kullanalım
  • İkinci olarak bunlar bir kütüphane olacağı için index.js dosyası aşağıdaki resimdeki şekilde değiştirelim. Amacımız bileşenleri dışarıya açmak.
import { CounterClass } from "./counter/CounterClass";
import { CounterHook } from "./counter/CounterHook";
export { CounterClass, CounterHook };
  • Burada amacımız bileşenin build edilmiş yani tarayıcının anlayacağı HTML, CSS ve JS dosyalarına dönüşümü sağlamak. Çünkü tarayıcılar JSX, SaSS gibi kısımları anlayamayacağı için projemizin geliştirme ortamında build edilmesi gerekiyor. package.json içerisinde bir takım güncellemeler yapmamız gerekiyor.
  • Babel paketlerini kuralım ki bunlar ile JSX gibi kısımları React API call dönüştürelim. Aşağıdaki kurulumu yapalım.
npm install —-save-dev @babel/cli @babel/plugin-transform-react-jsx @babel/preset-env @babel/preset-react
  • package.json içerisinde scripts objesi içerisine build-lib scriptini tanımlayalim.
“build-lib”: “rm -rf dist/* && babel src/ — out-dir dist — copy-files — no-copy-ignored — ignore src/**/*.stories.js”
  • JSON içerisine property olarak files ve main tanımlamalarını yapalım.
"files": ["dist"],
"main": "dist/index.js"
  • Sonunda package.json dosyasında aşağıdaki şekilde değişiklikler olacaktır.
  • Şimdi yapmamız gereken projemizi babel ile build ederek component bileşenlerinin → dist klasörünün altına atmak istiyoruz
npm run build-lib // Kütüphanemizi build edelim

Daha sonrasında npm link komutunu çalıştırarak projemizi global erişebilecek bir link haline dönüştürüyoruz.

npm link   //package.json  olduğu yerde çalıştırıyoruzOutput (Aşağıdaki Linki Oluşturdu)
/Users/onurdayibasi/.nvm/versions/node/v14.16.1/lib/node_modules/comp_aaa -> /Users/onurdayibasi/Documents/poc/complib/aaa/comp_aaa

Proj_AAA Oluşturalım. (webpack.config.js)

  • Proj_AAA React projesini cra(create-react-app) ile oluşturalım
npx create-react-app proj_aaa // projemizi oluşturalım.

Oluşturduğumuz projenin içerisinde comp_aaa kullanabilmek için

npm link comp_aaa // artık sanki npm install yapmıs gibi comp_aaa projesini paket olarak projemizde kullan

Burada karşımıza şu şekilde bir problem çıkıyor. Class Component yaptığımız Counter çalışırken, CounterHook ile ilgili hata alıyoruz.

Hata’da Hook’larda verilen genel hata. (Invalid Hook Call Warning)

You might have mismatching versions of React and React DOM.
You might be breaking the Rules of Hooks.
You might have more than one copy of React in the same app.

Buradaki Hatanın çözülmesinde Ercan Er'in büyük desteği oldu. Bu kısımda oluşan 2 problem var.

  • React kütüphanesinin NPM Link yanında geliyor olması
  • create-react-app oluşturulan projelerde dosyalara erişimin sadece src klasörün altına bakacak şekilde ModuleScopePlugin tarafından kontrol edilmesi

Bu kısımları aşmak için Webpack Configurasyonunu değiştirmemiz gerekiyor

npm run eject // react script dışarıya çıkarıyoruz. 

ve webpack.config.js içerisinde aşağıdaki react sadece node_modules altından kullanmasını bildiyoruz. Bu dublication sorununu çözecek.

react: path.resolve("./node_modules/react"),

2nci olarak webpack.config.js içerisinde ModuleScopePlugin kaldırmamız gerekiyor. (Stackoverflow bu linkinde bundan bahsediyor) . Plugini disabled ediyoruz.

En sonunda projemiz çalıştı.

Proj_AAA2 Oluşturalım (react-app-rewired)

2nci bir react projesi oluşturduk fakat bu sefer npm run eject çalıştırmadan bu işi nasıl gerçekleştirebiliriz. Bunun için react-app-rewired npm modülünden faydalanalım.

npm install --save-dev customize-cra react-app-rewired

ve ardından package.json dosyasında aşağıdaki resimdeki değişiklikleri yapalım.

Burada package.json seviyesinde config-overrides.js ile bir önceki projede yaptığımız config değişikliklerini ezerek gerçekleştiriyoruz.

Bu proje içinde artık comp kütüphanesi çalışır hale geldi.

Src Path ile ilgili Alias Path → Relative Path Dönüştürülmesi

Component Kütüphanenizde bu tipte bir relative path varsa, bunlar babel build ederken absolute path dönüştürmek istiyorsanız. Yapmanız gereken .babelrc dosya alias tanımlamalarını yapmanız gerekiyor

{   "presets": [ "@babel/preset-env","@babel/preset-react"],
"plugins": [["@babel/plugin-transform-react-jsx",{"runtime": "automatic"}],
["module-resolver", {"root": ["./"],"alias": {"components": "./src/components", "utils": "./src/utils"}}]]
}

Okumaya Devam Et 😃

Bu yazının devamı veya yazı grubundaki diğer yazılara erişmek için bu linke tıklayabilirsiniz.

--

--