Tarayıcıda NodeJS ve JavaScript’te Oturum Açmanın Kullanışlı Taktikleri – JSManifest

Tarayıcıda NodeJS ve JavaScript'te Oturum Açmanın Kullanışlı Taktikleri – JSManifest

Geliştiriciler olarak, bir tür kayıt mekanizması olmadan uygulamalarımızda hata ayıklamak son derece zordur.

Bunun nedeni, günlüklerin kodumuzdaki herhangi bir zaman noktasını yakalayabilmesi ve durumu zaman içinde geriye doğru izlemek için kullanılabilecek uygulama yaşam döngümüzün mevcut durumu hakkında yığın izlerini veya faydalı bilgileri yakalayabilmesidir.

Bu yazıda, JavaScript’te hem nodejs hem de tarayıcı ortamlarında oturum açmanın birkaç uygun taktiğini inceleyeceğiz.

İzleme / Hata Ayıklama

Projelerimiz zamanla büyüdükçe, kodumuz daha karmaşık hale geldikçe kodumuzu izlemek için günlükler oluşturmak giderek daha önemli hale geliyor. Kod karmaşıklığındaki artış, bakımın zorlaşmasına ve kodumuzun okunabilirliğine neden olur.

Beklenmeyen bir davranış oluştuğunda, değişiklikleri izlemenin günlüğe kaydetmeden daha iyi bir yolu yoktur.

Aşağıdaki bir örneğe bakalım:


require('jsdom-global')()
const fetch = require('node-fetch').default

function fetchCats() {
  return new Promise((resolve, reject) => {
    fetch('https://api.thecatapi.com/v1/images/search?limit=10')
      .then((resp) => resp.json())
      .then((results) => resolve(results))
      .catch(reject)
  })
}

class GalleryPages {
  constructor(items) {
    this.items = items
  }

  build() {
    const wrapper = document.createElement('div')

    for (const item of this.items) {
      const img = document.createElement('img')
      img.width = item.width
      img.height = item.height
      img.src = item.src
      wrapper.appendChild(img)
    }

    return wrapper
  }
}

fetchCats()
  .then((cats) => {
    return cats.map((cat) => ({
      src: cat.url,
      width: cat.width,
      height: cat.height,
    }))
  })
  .then((cats) => {
    const createPage = (child) => {
      const container = document.createElement('div')
      container.style.width = '250px'
      container.style.maxHeight = '250px'
      container.style.border = '1px solid magenta'
      container.style.margin = '15px 0px'
      container.style.position = 'relative'
      container.style.overflowX = 'hidden'
      container.style.display = 'inline-block'
      container.appendChild(child)
      document.body.appendChild(container)
      return container
    }

    let elements = []
    let cat = cats[cats.length - 1]

    while (cats.length) {
      const page = new GalleryPages([cat])
      elements.push(createPage(page.build()))
      cat = cats.pop()
    }

    return elements
  })
  .catch((error) => console.error(error))

Beklediğimiz davranış, getirilen her kedi görüntüsü için tek bir öğe içeren yeni bir öğe oluşturmamızdır. img sonunda “galeri benzeri” bir görünümde gruplandırılacak olan öğe. İstemcide görüntülenirken her resim görsel olarak aynı boyutta gösterilmelidir ve her resim farklı olmalıdır:

Ancak ilk iki resim kopyadır. Kodumuza basit kaydediciler yerleştirerek, hatanın nerede başladığını tam olarak belirlemek için bir kısayol sağlar:

nodejs-javascript-debug-log-tracking-errors1

{
  src: "https://cdn2.thecatapi.com/images/XT3M3LXmE.jpg",
  width: 259,
  height: 194
}
{
  src: "https://cdn2.thecatapi.com/images/XT3M3LXmE.jpg",
  width: 259,
  height: 194
}
{
  src: "https://cdn2.thecatapi.com/images/yeauSxGXb.jpg",
  width: 1500,
  height: 1124
}
{
  src: "https://cdn2.thecatapi.com/images/dfn.jpg",
  width: 450,
  height: 569
}
{
  src: "https://cdn2.thecatapi.com/images/bl9.jpg",
  width: 468,
  height: 498
}
{
  src: "https://cdn2.thecatapi.com/images/bba.jpg",
  width: 500,
  height: 333
}
{
  src: "https://cdn2.thecatapi.com/images/a88.jpg",
  width: 1200,
  height: 930
}
{
  src: "https://cdn2.thecatapi.com/images/a6s.jpg",
  width: 450,
  height: 300
}
{
  src: "https://cdn2.thecatapi.com/images/9tb.jpg",
  width: 612,
  height: 612
}
{
  src: "https://cdn2.thecatapi.com/images/2lv.png",
  width: 500,
  height: 333
}

İlk iki nesne aynıdır, böylece for döngümüzün nasıl başladığına hemen bakabiliriz:

nodejs-javascript-debug-tracking-log-found-issue1

Artık mesele apaçık ortaya çıkıyor. Her döngü, bir nesne ile başlamayı bekler. pulled diziden. Her döngü, dizinin mutasyona uğramış olmasını bekler, bu nedenle diziyi değiştirmemiz gerekir:

nodejs-javascript-debug-tracking-log-fixed-issue1

nodejs-javascript-dom-cat-gallery-view-output3

Verim

Uygulamalarımızın rekabetçi kalmasını istiyorsak, modern uygulamalarda performans en önemli endişemizdir. Geliştiriciler olarak kullanıcılarımızı mutlu etmek bizim sorumluluğumuzdur ve her şey kodla başlar. kullanarak console performansı kodumuzun farklı bölümlerinde kaydedebiliriz.

Analiz

Günlükler beklediğimizden çok daha kullanışlıdır. Kodumuzun tamamına rastgele günlükler yerleştirmek bile bize uygulamamızı geliştirmek için kullanabileceğimiz bilgiler verir.

Aşağıdaki gibi şeyleri bulmak için günlük bilgilerimizi kullanabiliriz:

  • Yinelenen istekler
  • Bellek sızıntıları
  • gereksiz değişkenler
  • yazım hataları
  • Bize todoları tekrar ziyaret etmeyi hatırlatıyor
  • İzleme işlevi çağrıları
  • Beklenmeyen davranış

Liste devam ediyor.

Önemli Günlüğe Kaydetme Yöntemleri

console.assert bir iddia başarısız olursa veya başarısız olursa konsola hata mesajları yazmak için kullanışlıdır (genel olarak işlevlerimizde girişleri veya çıktıları doğrulamak için kullanılır) false. Aksi takdirde hiçbir şey olmayacak. Bu, jenerik ile karşılaştırıldığında bir tür “tembel yükleme” hissi sağlar. console.log bu da daha fazla bellek kullanımından kaçınmayı kolaylaştırır.

console.clear konsolu temizlemek için kullanılabilir. Bu, çok fazla günlüğünüz olduğunu fark ettiğiniz ve konsolda gördüğünüz ilk mesajın doğrudan işlevden geldiğinden emin olmak için hata ayıkladığınız bir işlevin hemen önüne yerleştirmek istediğiniz durumlarla karşılaştığınızda yararlıdır. Bu, samanlıkta o iğneyi bulmak için gereksiz yere yukarı ve aşağı kaydırmayı önlemeye yardımcı olur.

console.error mesajların konsola kaydedilmesine de yardımcı olabilir, ancak tarayıcı konsolunda kırmızı arka planda olmaları nedeniyle hata gibi görünen mesajları görüntüler. Çoğu durumda bu yeterlidir. Ancak yine de daha gösterişli bir yol seçeceğimiz bazı durumlar var: console.log('%c"obj" is not an object', 'color:red;font-weight:400', obj) hata mesajlarını görüntülemek için

console.debug mesajları konsola “ayrıntılı” düzeyde verir. Kitaplıklar, kullandıkları kitaplıktaki başlığın altındaki teknik ayrıntılara daha derinden inmek isteyen geliştiriciler için daha fazla teknik bilgi kaydetmek için bu yöntemi kullanır.

console.dir görüntüleyebilmenin yanı sıra konsola herhangi bir şey görüntülemek için kullanılabilir tüm konsola nesnelerin özellikleri (konfigüre edilebilir depth seçenek). Tarayıcıda kullanılıyorsa, kullandığımız nesneler console.dir olabilir etkileşimli bunları genişletme/daraltma yeteneğine sahipken özellikleri/yöntemleri tıklayabileceğimiz yer:

tarayıcı-konsol-dir-javascript-etkileşimli-görünüm-nodejs1

console.group ve console.groupEnd konsoldaki “gruplama” efektini simüle ederek, her satırın girintili olabileceği sarılmış bir “kapsayıcı” içine birden çok günlüğü sarmak için kullanılabilir:

const obj = {
  myProfile: {
    firstName: 'Kelly',
    lastName: 'Vaughn',
    age: 31,
  },
  myFavoriteFood: {
    fruits: ['strawberry', 'raspberry'],
    meat: ['steak'],
  },
}

console.group('hello')
console.log(obj.myProfile.firstName)
console.log(obj.myProfile.lastName)
console.log(obj.myFavoriteFood)
console.log(obj.myProfile.age)
console.groupEnd()

nodejs-logging-grouping-messages-javascript1

ilginç bulduğum şey console.group gerekirse, altta yatan mesajları yerleştirmek/girinti yapmak için birden çok kez kullanabilmemizdir:

console.group('')
console.group('hello')
console.log(obj.myProfile.firstName)
console.log(obj.myProfile.lastName)
console.group('')
console.group('hello')
console.group('')
console.log(obj.myFavoriteFood)
console.log(obj.myProfile.age)
console.group('')
console.group('')
console.groupEnd()

nodejs-logging-grouping-messages-javascript2

taktikler

Bazen kendimizi fazla kaptırabilir ve günlüğe kaydedebiliriz. fazla çok bilgi. Bu etkiler çalışma zamanı performansı özellikle günlüklerimize büyük nesneler eklediğimizde.

Günlüğe kaydetme, NodeJS’de çok kullanışlıdır. Ama öyle zamanlar var ki yararlı değil. Ancak, bizim için yararlı olmayan bu günlüklerden bazılarını yapmamız için fırsatlar da var. faydalı olmak.

Aşağıdaki örneğe bakalım:

class Profile {
  #firstName
  #lastName
  #familyMembers

  constructor(firstName, lastName) {
    this.#firstName = firstName
    this.#lastName = lastName
    this.#familyMembers = []
  }

  get firstName() {
    return this.#firstName
  }

  get lastName() {
    return this.#lastName
  }

  get fullName() {
    return `${this.firstName} ${this.lastName}`
  }

  addFamilyMember(profile) {
    this.#familyMembers.push(profile)
  }
}

Örneklerini oluşturduğumuzda Profile ve her örneği konsola kaydedin, aşağıdaki gibi yararlı bilgileri görmek istiyoruz firstName, lastName, fullNameve tüm familyMembers çıktıda.

Ama olan şu ki, konsolda gösterildiklerinde bu bize verilen bilgi türüdür:

const myProfile = new Profile('Kelly', 'Gonzalez')

console.log(myProfile)

nodejs-log-info-gizli-özellikler-gösterilmiyor1

Peki bu çıktıyı nasıl faydalı bilgiler haline getirebiliriz? Neyse ki NodeJS bizim için yararlı bir yol sağlıyor. çıktıyı özelleştir nesnelerin.

Inspect (Önerilen: Genel bir Kullanıcı Snippet’i oluşturun)

Konsoldaki nesnelerin çıktısını özelleştirmek için bir Symbol değer ile "nodejs.util.inspect.custom" şöyle:

class Profile {
  #firstName
  #lastName
  #familyMembers;

  [Symbol.for('nodejs.util.inspect.custom')]() {
    return this.toJSON()
  }

  constructor(firstName, lastName) {
    this.#firstName = firstName
    this.#lastName = lastName
    this.#familyMembers = []
  }

  get firstName() {
    return this.#firstName
  }

  get lastName() {
    return this.#lastName
  }

  get fullName() {
    return `${this.firstName} ${this.lastName}`
  }

  get familyMembers() {
    return this.#familyMembers
  }

  addFamilyMember(profile) {
    this.#familyMembers.push(profile)
  }

  toJSON() {
    return {
      firstName: this.firstName,
      lastName: this.lastName,
      fullName: this.fullName,
      familyMembers: this.familyMembers.map((profile) => profile.toJSON()),
      totalFamilyMembers: this.familyMembers.length,
    }
  }
}

const myProfile = new Profile('Kelly', 'Gonzalez')
const lisa = new Profile('Lisa', 'Gonzalez')
const melon = new Profile('Melon', 'Gonzalez')
const george = new Profile('George', 'Gonzalez')

myProfile.addFamilyMember(lisa)
myProfile.addFamilyMember(melon)
myProfile.addFamilyMember(george)

george.addFamilyMember(new Profile('Terrence', 'Gonzalez'))

console.log(myProfile)

bizim günlüğe kaydetme Profile konsola örnek, bilgileri istediğimiz şekilde görüntüleyebilir:

{
  "firstName": "Kelly",
  "lastName": "Gonzalez",
  "fullName": "Kelly Gonzalez",
  "familyMembers": [
    {
      "firstName": "Lisa",
      "lastName": "Gonzalez",
      "fullName": "Lisa Gonzalez",
      "familyMembers": [],
      "totalFamilyMembers": 0
    },
    {
      "firstName": "Melon",
      "lastName": "Gonzalez",
      "fullName": "Melon Gonzalez",
      "familyMembers": [],
      "totalFamilyMembers": 0
    },
    {
      "firstName": "George",
      "lastName": "Gonzalez",
      "fullName": "George Gonzalez",
      "familyMembers": "[Array]",
      "totalFamilyMembers": 1
    }
  ],
  "totalFamilyMembers": 3
}

Bunu özel bir Kullanıcı Snippet’ine bağlamanızı tavsiye ederim çünkü benim gibiyseniz bunu her seferinde daha fazlası için kullanacaksınız. üretken geliştirme deneyimi.

şunu belirtmekte fayda var [Symbol.for('nodejs.util.inspect.custom')]() {} ayrıca 3 argümanla birlikte gelir:

[Symbol.for('nodejs.util.inspect.custom')](depth, inspectOptions, inspect) {}

Bu argümanlar hakkında daha fazla bilgi edinebilirsiniz. burada.

Otomasyon

Önceki örneklerimiz güzel çünkü uygulamalarımızı geliştirirken oturum açmayı gerçek zamanlı olarak analiz edebiliyoruz.

Ancak, otomatik komut dosyalarımızda günlükleri görmek istediğimiz zamanlar vardır (örneğin, bir komut dosyasının her 15 dakikada bir veri getirmesi gibi). değil artık çalışma zamanında analiz ediyor.

Varsayılan olarak, Console NodeJS’deki yapıcı, çıktısını şuraya aktararak terminale giriş yapar stdout ve stderr. Aslında bu ikisini çıktısını bir dosya gibi başka bir yere iletecek şekilde yapılandırabiliriz:

const logOutput = fs.createWriteStream(path.join(__dirname, 'logs.json'))
const log = new Console({ stdout: logOutput })

const output = []

output.push(myProfile.familyMembers[0].toJSON())
output.push({ timestamp: new Date().toISOString() })

log.info(JSON.stringify(output, null, 2))

nodejs-özel-günlük-çıktı-dosya-json1

Sonuç:

nodejs-javascript-custom-log-output-to-file-json-view-data1

Pratikte kaydediciler

pino-http [pino] içine girmek için bir kitaplık sağlar ekspresjs http isteklerinden istediğimiz her şeyi günlüğe kaydetmek için bir ara katman yazılımı olarak ardışık düzen isteyin.

dosya akışı döndürücü günlüklerini bir dosyanın içinde tutan sunucu uygulamalarında günlük ara yazılımı ile birlikte kullanılabilir. Tarihe, boyut sınırına veya kombinasyona göre döndürülmesi gereken Ekspres günlüklerin düzenli aralıklarla otomatik olarak döndürülmesini sağlamayı ve eski günlük dosyalarını sayıma veya geçen günlere göre kaldırmayı amaçlar.

günlük güncelleme geliştiricilerin, düğümün özelliklerinden yararlanarak terminalde bir ilerleme çubuğunu veya özelleştirilmiş animasyonları simüle etmelerini sağlar. stdout ve stderr (aynı G/Ç Console kullanır)

kükreme bilgileri hem düğümleri hem de tarayıcı ortamlarını destekleyen JSON olarak günlüğe kaydeder

logdown.js markdown sözdizimini desteklemenin yanı sıra hem düğüm hem de tarayıcı ortamları için bir günlük kaydı mekanizması sağlar.

Çözüm

Ve bu yazının sonu burada bitiyor! Umarım bunu değerli bulmuşsunuzdur ve gelecekte daha fazlasını ararsınız!

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.