Skip to content

3. İlk uygulama [nuxt.js]

3.1. Uygulamanın oluşturulması

[nuxt.js] geliştirme çalışmalarımız için VS kodunu kullanmaya devam ediyoruz. Örneklerimizi yerleştireceğimiz boş bir [dvp] klasörü oluşturduk. Ardından bu klasörü açıyoruz:

Image

Çalışma alanını [intro-nuxtjs] [3-5] adıyla kaydediyoruz:

Image

[6-7] terminalini açıyoruz:

Image

Şimdiye kadar [npm] adlı JavaScript paket yöneticisini kullandık. Değişiklik yapmak amacıyla burada [yarn] yöneticisini kullanacağız. Bu yönetici, [npm] gibi, [node.js]'in son sürümleriyle birlikte yüklenmiştir. İlk [nuxt] uygulamasını oluşturmak için [yarn create nuxt-app <dossier>] [1] komutunu kullanıyoruz. Komut, oluşturulacak projeyle ilgili bazı bilgileri isteyecek ve bu bilgiler alındıktan sonra [2]'i oluşturacaktır:

Image

[2] komutunda, tam bir dosya ağacı oluşturulmuştur. [package.json] dosyası, [node-modules] ve [4] klasörlerine indirilen JavaScript kütüphanelerinin listesini verir:


{
  "name": "nuxt-intro",
  "version": "1.0.0",
  "description": "nuxt-intro",
  "author": "serge-tahe",
  "private": true,
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore ."
  },
  "dependencies": {
    "nuxt": "^2.0.0",
    "bootstrap-vue": "^2.0.0",
    "bootstrap": "^4.1.3",
    "@nuxtjs/axios": "^5.3.6"
  },
  "devDependencies": {
    "@nuxtjs/eslint-config": "^1.0.1",
    "@nuxtjs/eslint-module": "^1.0.0",
    "babel-eslint": "^10.0.1",
    "eslint": "^6.1.0",
    "eslint-plugin-nuxt": ">=0.4.2",
    "eslint-config-prettier": "^4.1.0",
    "eslint-plugin-prettier": "^3.0.1",
    "prettier": "^1.16.4"
  }
}

Bu dosya, oluşturulan projeyi tanımlamak için [create nuxt-app] komutuna verilen yanıtları yansıtmaktadır (Kasım 2019). Okuyucunun elinde farklı bir [package.json] dosyası olabilir:

  • sorulara farklı yanıtlar vermiş olabilir;
  • [create nuxt-app] komutu, bu belgenin yazılmasından bu yana gelişmiş olabilir: bağımlılıklar ve sürümler değişmiş olabilir;

Komut dosyasının 8. satırı, uygulamayı başlatan komuttur:

Image

  • [4]'te, uygulamanın URL ve [localhost:3000] adreslerinde erişilebilir olduğu görülmektedir;
  • [5-6] adresinde, uygulamanın bir [6] sunucusu ve (bu sunucunun) bir [5] istemcisi oluşturduğunu görüyoruz;

URL [http://localhost:3000/] adresini bir tarayıcıda açalım:

Image

3.2. [nuxt] uygulamasının dizin yapısı açıklaması

Oluşturulan uygulamanın dizin yapısına tekrar bakalım:

Image

Klasörlerin işlevleri şu şekildedir:

assets
uygulamanın derlenmemiş kaynakları (resimler, ...);
static
bu klasördeki dosyalar uygulamanın kök dizininde erişilebilir olacaktır. Bu klasöre, örneğin arama motorları için hazırlanan [robots.txt] dosyası gibi, uygulamanın kök dizininde bulunması gereken dosyalar yerleştirilir;
components
[layouts] ve [pages] dosyalarında kullanılan uygulamanın [vue] bileşenleri;
layouts
[pages] dosyalarının mizanpajında kullanılan uygulamanın [vue] bileşenleri;
sayfalar
uygulamanın farklı rotaları tarafından görüntülenen [vue] bileşenleri. Bunlara uygulamanın görünümleri de denilebilir. Sayfalar, [nuxt]'te özel bir rol oynar: rotalar, [pages] klasöründe bulunan dizin yapısından dinamik olarak oluşturulur;
middleware
her rota değişikliğinde çalıştırılan komut dosyalarıdır. Bunlar, rotaların kontrol edilmesini sağlar;
eklentiler
adından dolayı kafa karıştırıcı olabilir. Eklentiler içerebileceği gibi klasik komut dosyaları da içerebilir. Bu klasörde bulunan komut dosyaları, uygulamanın başlatılması sırasında çalıştırılır;
depolama
içinde [index.js] adlı bir komut dosyası varsa, bu dosya [Vuex] mağazasının bir örneğini tanımlar;

Bir klasör boşsa, dizin yapısından silinebilir. Yukarıdaki örnekte, [assets, static, middleware, plugins, store] ve [2] klasörleri silinebilir.

3.3. [nuxt.config] yapılandırma dosyası

Uygulamanın çalışması, aşağıdaki [nuxt.config.js] dosyası tarafından kontrol edilir:


export default {
  mode: 'universal',
  /*
   ** Headers of the page
   */
  head: {
    title: process.env.npm_package_name || '',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      {
        hid: 'description',
        name: 'description',
        content: process.env.npm_package_description || ''
      }
    ],
    link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
  },
  /*
   ** Customize the progress-bar color
   */
  loading: { color: '#fff' },
  /*
   ** Global CSS
   */
  css: [],
  /*
   ** Plugins to load before mounting the App
   */
  plugins: [],
  /*
   ** Nuxt.js dev-modules
   */
  buildModules: [
    // Doküman: https://github.com/nuxt-community/eslint-module
    '@nuxtjs/eslint-module'
  ],
  /*
   ** Nuxt.js modules
   */
  modules: [
    // Belge: https://bootstrap-vue.js.org
    'bootstrap-vue/nuxt',
    // Belge: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios'
  ],
  /*
   ** Axios module configuration
   ** See https://axios.nuxtjs.org/options
   */
  axios: {},
  /*
   ** Build configuration
   */
  build: {
    /*
     ** You can extend webpack config here
     */
    extend(config, ctx) {}
  }
}
  • 2. satır: Oluşturulan uygulamanın türü:
    • [universal]: istemci/sunucu uygulaması. Uygulamanın ilk yüklenmesi sırasında ve tarayıcıda her sayfa yenilemesinde, sayfanın sunulması için sunucuya istek gönderilir;
    • [sap]: [Single Page Application] türü uygulama: bir sunucu başlangıçta uygulamanın tamamını sunar. Ardından, tarayıcıda bir sayfa yenilense bile istemci tek başına çalışır;
  • 6-18. satırlar: Uygulamanın farklı sayfalarının HTML <head> başlığını tanımlar:
    • 7. satır: sayfaların başlığı için <title> etiketi;
    • satır 8-16: <meta> etiketleri;
    • 17. satır: <link> etiketleri

Oluşturulan uygulamada, <head> etiketi şu şekildedir (tarayıcıda görüntülenen sayfanın kaynak kodu):


<title>nuxt-intro</title>
<meta data-n-head="ssr" charset="utf-8">
<meta data-n-head="ssr" name="viewport" content="width=device-width, initial-scale=1">
<meta data-n-head="ssr" data-hid="description" name="description" content="nuxt-intro">
<link data-n-head="ssr" rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="preload" href="/_nuxt/runtime.js" as="script">
<link rel="preload" href="/_nuxt/commons.app.js" as="script">
<link rel="preload" href="/_nuxt/vendors.app.js" as="script">
<link rel="preload" href="/_nuxt/app.js" as="script">

Şimdi, [nuxt.config] dosyasını şu şekilde değiştirelim:


head: {
    title: 'Introduction à [nuxt.js]',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      {
        hid: 'description',
        name: 'description',
        content: 'ssr routing loading asyncdata middleware plugins store'
      }
    ],
    link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
},

Uygulamayı yeniden çalıştırdığımızda, <head> etiketi şu şekilde değişmiştir (tarayıcıda görüntülenen sayfanın kaynak kodu):


  <head >
    <title>Introduction à [nuxt.js]</title>
    <meta data-n-head="ssr" charset="utf-8">
    <meta data-n-head="ssr" name="viewport" content="width=device-width, initial-scale=1">
    <meta data-n-head="ssr" data-hid="description" name="description" content="ssr routing loading asyncdata middleware plugins store">
    <link data-n-head="ssr" rel="icon" type="image/x-icon" href="/favicon.ico">
    <link rel="preload" href="/_nuxt/runtime.js" as="script">
    <link rel="preload" href="/_nuxt/commons.app.js" as="script">
    <link rel="preload" href="/_nuxt/vendors.app.js" as="script">
<link rel="preload" href="/_nuxt/app.js" as="script">

[nuxt.config] dosyasına geri dönelim:


export default {
  mode: 'universal',
  /*
   ** Headers of the page
   */
  head: {
    ...
  },
  /*
   ** Customize the progress-bar color
   */
  loading: { color: '#fff' },
  /*
   ** Global CSS
   */
  css: [],
  /*
   ** Plugins to load before mounting the App
   */
  plugins: [],
  /*
   ** Nuxt.js dev-modules
   */
  buildModules: [
    // Belge: https://github.com/nuxt-community/eslint-module
    '@nuxtjs/eslint-module'
  ],
  /*
   ** Nuxt.js modules
   */
  modules: [
    // Belge: https://bootstrap-vue.js.org
    'bootstrap-vue/nuxt',
    // Belge: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios'
  ],
  /*
   ** Axios module configuration
   ** See https://axios.nuxtjs.org/options
   */
  axios: {},
  /*
   ** Build configuration
   */
  build: {
    /*
     ** You can extend webpack config here
     */
    extend(config, ctx) {}
  }
}
  • 12. satır: [nuxt] istemcisinin her bir rotası arasında, rota değişikliği biraz zaman alıyorsa bir yükleme çubuğu (loading) görünür. [loading] özelliği, bu yükleme çubuğunu, burada çubuğun rengini ayarlamaya olanak tanır;
  • 16. satır: genel [css] dosyaları. Bu dosyalar, uygulamanın tüm sayfalarına otomatik olarak eklenecektir;
  • 24-27. satırlar: Uygulamanın derlenmesi (build) için gerekli JavaScript modülleri;
  • satır 31-36: uygulama tarafından kullanılan JavaScript modülleri;
  • 41. satır: Kullanıcı tarafından üçüncü taraf sunucularla HTTP diyalogları için seçildiğinde [axios] kütüphanesinin ayarları;
  • 45-50. satırlar: projenin derlenmesi (build) ayarları;

Yapılandırma dosyasına başka anahtarlar da eklenebilir. Özellikle hizmet bağlantı noktası (varsayılan olarak 3000) ve proje kök dizini (varsayılan olarak projenin kök klasörü) ayarlanabilir. Şimdi bunu, aşağıdaki anahtarları ekleyerek yapacağız:


// kaynak kod dizini
  srcDir: '.',
  router: {
    // URL uygulama sayfalarının kök dizini
    base: '/nuxt-intro/'
  },
  // sunucu
  server: {
    // hizmet bağlantı noktası - varsayılan 3000
    port: 81,
    // dinlenen ağ adresleri - varsayılan olarak localhost=127.0.0.1
    host: '0.0.0.0'
  }
  • 2. satır: projenin kaynak kodunun bulunduğu yer. Burada, geçerli klasörde, yani [nuxt.config.js] dosyasıyla aynı seviyede bulunur. Bu, varsayılan değerdir;
  • satır 8-13: sunucuyu yapılandırır ([nuxt] türündeki bir [universal] uygulamasının hem sunucuya hem de bu sunucunun istemci tarayıcısına yüklü olduğunu unutmamak gerekir);
  • 10. satır: Uygulamanın sayfaları sunucunun 81 numaralı bağlantı noktası üzerinden sunulacaktır;
  • satır 12: varsayılan olarak [localhost] (ağ adresi 127.0.0.1). Bir makine, birden fazla ağa aitse birden fazla ağ adresine sahip olabilir. 0.0.0.0 adresi, web sunucusunun makinenin tüm ağ adreslerini dinlediğini gösterir;
  • 3-6. satırlar: [nuxt] uygulamasının yönlendiricisini yapılandırır;
  • 5. satır: Uygulamanın sayfaları URL ve [http://localhost:81/nuxt-intro/] adreslerinde erişilebilir olacaktır;

Bu satırları [nuxt.config.js] dosyasına ekleyelim ve ardından projeyi çalıştıralım (npm dev komutu). Sonuç şu şekildedir:

Image

  • [1], kamuya açık bir ağdaki makinenin adresi;
  • [2]'te, hizmet bağlantı noktası;
  • [3], uygulamanın kök dizinidir;

3.4. [layouts] klasörü

Image

[layouts] klasörü, mizanpaj bileşenleri içindir. Varsayılan olarak, [default.vue] adlı bileşen kullanılır. Bu projede, bu bileşen şöyledir:


<template>
  <div>
    <nuxt />
  </div>
</template>

<style>
html {
  font-family: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI',
    Roboto, 'Helvetica Neue', Arial, sans-serif;
  font-size: 16px;
  word-spacing: 1px;
  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
  -moz-osx-font-smoothing: grayscale;
  -webkit-font-smoothing: antialiased;
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: border-box;
  margin: 0;
}

.button--green {
  display: inline-block;
  border-radius: 4px;
  border: 1px solid #3b8070;
  color: #3b8070;
  text-decoration: none;
  padding: 10px 30px;
}

.button--green:hover {
  color: #fff;
  background-color: #3b8070;
}

.button--grey {
  display: inline-block;
  border-radius: 4px;
  border: 1px solid #35495e;
  color: #35495e;
  text-decoration: none;
  padding: 10px 30px;
  margin-left: 15px;
}

.button--grey:hover {
  color: #fff;
  background-color: #35495e;
}
</style>

Açıklamalar

  • 1-5. satırlar: bileşenin [template] kısmı;
  • 3. satır: <nuxt /> etiketi, yönlendirmenin geçerli sayfasını belirtir;
  • 7-55. satırlar: mizanpaj bileşeni tarafından gömülü stil. Bu stil, yönlendirmenin geçerli sayfasını içerdiğinden, uygulamanın tüm yönlendirilmiş sayfalarına uygulanacaktır;

Görüldüğü gibi, [default.vue] sayfasının buradaki temel amacı, yönlendirilmiş sayfalara bir stil uygulamaktır.

3.5. [pages] klasörü

Image

[pages] klasörü, kullanıcının gördüğü yönlendirilmiş görünümleri içerir. [index.vue] sayfası, uygulamanın ana sayfasıdır. [nuxt.js] sayfasında yönlendirme dosyası bulunmamaktadır. Yollar, [pages] klasörünün yapısına göre belirlenir. Burada, [index.vue] dosyasının varlığı, otomatik olarak [index] adlı bir yönlendirme oluşturur ve [/index] yolunu, ana sayfa olduğu için [/]'e indirger. Böylece şu rota oluşturulur:

        { name : ‘index’, path : ‘/’}

[index.vue] dosyası şu şekildedir:


<template>
  <div class="container">
    <div>
      <logo />
      <h1 class="title">
        nuxt-intro
      </h1>
      <h2 class="subtitle">
        nuxt-intro
      </h2>
      <div class="links">
        <a href="https://nuxtjs.org/" target="_blank" class="button--green">
          Documentation
        </a>
        <a
          href="https://github.com/nuxt/nuxt.js"
          target="_blank"
          class="button--grey"
        >
          GitHub
        </a>
      </div>
    </div>
  </div>
</template>

<script>
import Logo from '~/components/Logo.vue'

export default {
  components: {
    Logo
  }
}
</script>

<style>
.container {
  margin: 0 auto;
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}

.title {
  font-family: 'Quicksand', 'Source Sans Pro', -apple-system, BlinkMacSystemFont,
    'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  display: block;
  font-weight: 300;
  font-size: 100px;
  color: #35495e;
  letter-spacing: 1px;
}

.subtitle {
  font-weight: 300;
  font-size: 42px;
  color: #526488;
  word-spacing: 5px;
  padding-bottom: 15px;
}

.links {
  padding-top: 15px;
}
</style>

[template] dosyasının 1-25. satırları şu görünümü gösterir:

Image

[1] görüntüsü, [template] dosyasının 4. satırı tarafından oluşturulur. Dolayısıyla, sayfanın [logo] adlı bir bileşen kullandığı görülmektedir. Bu bileşen, sayfanın komut dosyasının 27-35. satırlarında tanımlanmıştır. 28. satırda, [~] ifadesi projenin kök dizinini belirtir.

3.6. [Logo] bileşeni

Image

[Logo.vue] bileşeni şöyledir:


<template>
  <div class="VueToNuxtLogo">
    <div class="Triangle Triangle--two" />
    <div class="Triangle Triangle--one" />
    <div class="Triangle Triangle--three" />
    <div class="Triangle Triangle--four" />
  </div>
</template>

<style>
.VueToNuxtLogo {
  display: inline-block;
  animation: turn 2s linear forwards 1s;
  transform: rotateX(180deg);
  position: relative;
  overflow: hidden;
  height: 180px;
  width: 245px;
}

.Triangle {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
}

.Triangle--one {
  border-left: 105px solid transparent;
  border-right: 105px solid transparent;
  border-bottom: 180px solid #41b883;
}

.Triangle--two {
  top: 30px;
  left: 35px;
  animation: goright 0.5s linear forwards 3.5s;
  border-left: 87.5px solid transparent;
  border-right: 87.5px solid transparent;
  border-bottom: 150px solid #3b8070;
}

.Triangle--three {
  top: 60px;
  left: 35px;
  animation: goright 0.5s linear forwards 3.5s;
  border-left: 70px solid transparent;
  border-right: 70px solid transparent;
  border-bottom: 120px solid #35495e;
}

.Triangle--four {
  top: 120px;
  left: 70px;
  animation: godown 0.5s linear forwards 3s;
  border-left: 35px solid transparent;
  border-right: 35px solid transparent;
  border-bottom: 60px solid #fff;
}

@keyframes turn {
  100% {
    transform: rotateX(0deg);
  }
}

@keyframes godown {
  100% {
    top: 180px;
  }
}

@keyframes goright {
  100% {
    left: 70px;
  }
}
</style>

Bu bileşen, temel olarak hareketli bir görüntü oluşturmak için kullanılan stiller ve animasyonlardan oluşur.

3.7. DevTools görünümü

[Vue DevTools], tarayıcıda [nuxt.js] ve [vue.js] nesnelerini incelememizi sağlayan tarayıcı eklentisidir. Bunu daha önce [vue.js] ile ilgili bölümde kullanmıştık. Uygulamamızın ana sayfası görüntülendiğinde bu aracın neler bulduğuna bir göz atalım:

Image

  • [1]'te, [PagesIndex] bileşeni [pages/index.vue] sayfasını ifade eder;
  • [2]'te görüldüğü gibi, bu bileşenin [$route] adlı bir özelliği vardır; bu, [index] sayfasına yönlendiren yoldur;

Basit bir alıştırma olarak, bu yolu konsolda görüntüleyelim.

3.8. Ana sayfanın değiştirilmesi

[index.vue] dosyasını değiştireceğiz. Proje kurulumumuzda iki bağımlılık yükledik:

  • [eslint]: JavaScript dosyalarının ve Vue bileşenlerinin sözdizimini denetler. VSCode uzantısı olan [ESLint] kurulmuşsa, metinler yazılırken bu sözdizimi kontrol edilir ve hatalar anında bildirilir;
  • [prettier]: JavaScript kodlarını standart bir şekilde biçimlendirir;

Bu bağımlılıklar [package.json] dosyasına kaydedilmiştir:


"devDependencies": {
    "@nuxtjs/eslint-config": "^1.0.1",
    "@nuxtjs/eslint-module": "^1.0.0",
    "babel-eslint": "^10.0.1",
    "eslint": "^6.1.0",
    "eslint-config-prettier": "^4.1.0",
    "eslint-plugin-nuxt": ">=0.4.2",
    "eslint-plugin-prettier": "^3.0.1",
    "prettier": "^1.16.4"
}

(Kasım 2019'da) [yarn create nuxt-app] komutuyla yapılan kurulumda, metin yazarken [eslint, prettier] araçlarının çalışmadığını fark ettim. Hatalar yalnızca derleme sırasında bildiriliyor. Biraz araştırma yaptıktan sonra, çalışan bir yapılandırma buldum:

Image

Projenin kök dizinine, içinde aşağıdaki [settings.json] dosyasının bulunduğu bir [.vscode] klasörü kurulur:


{
  "eslint.validate": [
    {
      "language": "vue",
      "autoFix": true
    },
    {
      "language": "javascript",
      "autoFix": true
    }
  ],
  "eslint.autoFixOnSave": true,
  "editor.formatOnSave": false
}
  • 2-11. satırlar: [eslint], .vue ve .js dosyalarını denetlerken düzeltebileceği hataları düzeltmesi gerektiğini belirtir;
  • 12. satır: Bir dosya kaydedildiğinde, [eslint] düzeltilebilecek hataları düzeltmelidir;
  • 13. satır: Kaydetme sırasında VSCode tarafından varsayılan olarak yapılan biçimlendirmeyi devre dışı bırakır. Bu işlemi [prettier] gerçekleştirecektir;

Bu yapılandırma ile:

  • sözdizimi veya biçimlendirme hataları, metinler yazılır yazılmaz bildirilir;
  • biçimlendirme hataları, dosya kaydedilirken otomatik olarak düzeltilir;

[prettier] kütüphanesi, [.prettierrc] dosyası ile yapılandırılır:

Image

Bu dosya varsayılan olarak şöyledir:


{
  "semi": false,
  "arrowParens": "always",
  "singleQuote": true
}
  • 1. satır: komutların sonunda ; işareti yoktur;
  • 2. satır: Bir "ok" (arrow) işlevinin tek bir parametresi varsa, bu parametre parantez içine alınır;
  • 3. satır: Dize karakterleri tek tırnak işaretleri ile çevrelenir (düz tırnak işaretleri kullanılmaz);

Aşağıdaki iki kuralı ekliyoruz:


{
  "semi": false,
  "arrowParens": "always",
  "singleQuote": true,
  "printWidth": 120,
  "endOfLine": "auto"
}
  • satır 5: kod satırı en fazla 120 karakterden oluşabilir;
  • 6. satır: Satır sonu işareti, CRLF (Windows) veya LF (Unix) olabilir;

Son olarak, [package.json] dosyası şu şekilde değiştirilir:


"scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
    "lintfix": "eslint --fix --ext .js,.vue --ignore-path .gitignore ."
},
  • 7. satır: 6. satırdaki [lint] komutuyla aynı olan, ancak ek olarak [--fix] parametresini içeren [lintfix] komutunu ekliyoruz. [lint] komutu, projedeki tüm dosyaların sözdizimini ve biçimini kontrol eder ve hataları bildirir. [lintfix] de aynı işlevi görür; ancak düzeltilebilecek biçimlendirme sorunları otomatik olarak düzeltilir. Dosya biçimlendirme sorunları nedeniyle derleme başarısız olursa, [lintfix] komutu kullanılmalıdır;

Bunu yaptıktan sonra, [index.vue] dosyasını şu şekilde değiştiriyoruz:

Image


<script>
/* eslint-disable no-console */
import Logo from '~/components/Logo.vue'

export default {
  components: {
    Logo
  },
  // yaşam döngüsü
  created() {
    console.log('created, route=', this.$route)
  }
}
</script>
  • 10-12. satırlar: Bileşen oluşturulduğunda otomatik olarak çalıştırılan [created] işlevini ekliyoruz;
  • 11. satır: geçerli rotayı görüntüleyin;
  • 2. satır: [eslint] için bir açıklama. Bu açıklama olmadan, [eslint] bir hata bildirir; 11. satır: yaşam döngüsü işlevlerinde [console] komutlarının bulunmasını istemez. [eslint] yapılandırılabilir. Varsayılan yapılandırmasını koruyacağız ve [eslint]'in belirli bir kuralını devre dışı bırakmak için 2. satırdaki gibi yorumlar kullanacağız. İki tür yorum kullanacağız:
    • /* [eslint] kuralını devre dışı bırakma */: tüm dosya için bir kuralı devre dışı bırakma;
    • // [eslint] kuralını devre dışı bırakma: takip eden satır için bir kuralı devre dışı bırakma;

Yazarken hatalar bildirilir ve [Quick Fix] işlevi kullanılabilir:

Image

Projeyi çalıştırıyoruz:

Image

  • [1]'te, tarayıcının geliştirme araçlarının (F12) [Vue] sekmesinde;
  • [2] ve [3]'te, rota gösterimi;

Neden tek bir görüntüleme değil de iki tane var?

Bir [nuxt] uygulaması, bir sunucu ve bir istemci olmak üzere iki bileşenden oluşur:

  1. sunucu, uygulamanın başlatılması sırasında ve ardından tarayıcıda bir sayfa her yenilendiğinde (F5) veya kullanıcı uygulamanın bir URL adresini elle girdiğinde uygulama sayfalarını sağlar;
  2. tarayıcı tarafından sağlanan her sayfa, istenen sayfanın yanı sıra tüm uygulamanın JavaScript kodunu da içerir ve bu kod daha sonra tarayıcıda çalıştırılır. Bu, istemcidir. Tarayıcıda sayfa yenilenmediği sürece, uygulama [sap] modunda (Tek Sayfalı Uygulama) klasik bir Vue uygulaması gibi çalışır. Kullanıcı manuel olarak sayfa yenilemesini tetiklediği anda, sayfa sunucudan istenir ve önceki 1. aşamaya geri dönülür.

Anlaşılması gereken nokta, sunucu ya da istemci tarafından sağlanan sayfaların [pages] klasöründeki aynı sayfalar olduğudur. Bu nedenle, [nuxt]'in tasarımcıları bu tür sayfalara izomorfik sayfalar adını vermektedir. Aynı [.vue] sayfaları hem istemci hem de sunucu tarafından yorumlanabilir. [index] sayfasını örnek olarak ele alalım:


<template>
  <div class="container">
    <div>
      <logo />
      <h1 class="title">
        nuxt-intro
      </h1>
      <h2 class="subtitle">
        nuxt-intro
      </h2>
      <div class="links">
        <a href="https://nuxtjs.org/" target="_blank" class="button--green">
          Documentation
        </a>
        <a
          href="https://github.com/nuxt/nuxt.js"
          target="_blank"
          class="button--grey"
        >
          GitHub
        </a>
      </div>
    </div>
  </div>
</template>

<script>
/* eslint-disable no-console */
import Logo from '~/components/Logo.vue'

export default {
  components: {
    Logo
  },
  // yaşam döngüsü
  created() {
    console.log('created, route=', this.$route)
  }
}
</script>

Bu sayfa ana sayfa olduğu için, uygulamanın başlatılmasıyla birlikte sunucu tarafından sunulur. Sunucudaki sayfanın da bir yaşam döngüsü vardır; bu, sunucu tarafında bulunmayan [beforeMount, monted] işlevleri hariç olmak üzere, klasik bir [Vue] sayfasınınkiyle aynıdır. [created] işlevi yürütülür; bu da ilk günlüğü açıklar. Bu arada, bu durum sunucunun JavaScript komut dosyalarını çalıştırabildiğini gösterir. Burada ve genel olarak, bu sunucu bir [node.js] sunucusudur. Sayfa sunucuda oluşturulduktan sonra tarayıcıya ulaşır ve burada yaşam döngüsünü yeniden geçirir. [created] işlevi ikinci kez çalıştırılır; bu da ikinci günlüğü oluşturur.

Bir [nuxt] uygulamasının mimarisi şu şekilde olabilir:

Image

  • [1]: [nuxt] uygulaması tarayıcıya yüklendiğinde, bu uygulamayı barındıran tarayıcıdır. Buna [nuxt] istemcisi denir;
  • [3]: [nuxt] uygulamasını başlangıçta barındıran sunucu. Bu uygulama, uygulamanın başlatılması sırasında ve kullanıcı tarayıcının mevcut sayfasını her yenilediğinde veya uygulamanın URL adresini elle girdiğinde [1] tarayıcısına yüklenir. İşte klasik bir Vue uygulamasıyla işleyişindeki fark burada yatmaktadır. Bu uygulamada ise, tarayıcıya yüklendikten sonra sunucuya bir daha hiç başvurulmazdı. Şu ana kadar göze çarpmayan bir diğer önemli fark ise, bir Vue uygulamasının sunucusunun [.vue] sayfalarını yorumlayamayan statik bir sunucu olması, buna karşın [universal] türündeki bir Nuxt uygulamasının sunucusunun ise bir JavaScript sunucusu olmasıdır. Bir sayfayı tarayıcıya göndermeden önce, sunucu komut dosyalarını çalıştırabilir ve örneğin [2] sunucusundan veri alabilir;
  • [2]: [nuxt] ve [1] istemcilerine ya da [nuxt] ve [3] sunucularına veri sağlayan sunucudur;

Yukarıdaki şemada üç istemci/sunucu alt sistemi ayırt edilebilir:

  • [1, 3]: [nuxt] uygulamasını barındırır. [3], uygulamanın başlatılması sırasında ana sayfayı ve kullanıcı her manuel olarak bir sayfa talep ettiğinde bu sayfayı sağlar. [1],[3]'ten alınan [nuxt] uygulamasını barındırır; bu uygulama, sayfalar [3]'e manuel olarak talep edilmediği sürece [SAP] modunda çalışır;
  • [1, 2]: [SAP] modunda, [nuxt] istemcisi bir veya daha fazla sunucudan harici verileri alır;
  • [3, 2]: Kullanıcı tarafından istenen sayfanın oluşturulması sırasında, [3] sunucusu da bir veya daha fazla sunucudan harici verileri alabilir;

Dolayısıyla, bir [nuxt] uygulamasını bir [vue] uygulamasından ayıran, [3] sunucusudur. Bu sunucuya, kullanıcı bir sayfayı manuel olarak her talep ettiğinde başvurulur. Bu sunucu, [.vue], [vue] ve [1] istemcileriyle aynı sayfaları işler. Bu, sayfada bulunan komut dosyalarını çalıştırabilen bir JavaScript sunucusudur. Bu, örneğin dış verilerle ana sayfanın oluşturulma şeklini değiştirebilir: bir [vue] uygulamasının bu verileri zorunlu olarak [1] istemcisinden aldığı durumlarda, burada veriler sayfa istemciye gönderilmeden önce [3] sunucusu tarafından alınabilir. Böylece ana sayfa anlam kazanır ve uygulamanın SEO değerini iyileştirmeye katkıda bulunabilir.

Not: Geliştirme modunda, üç [1, 2, 3] varlığı genellikle aynı makinede bulunur. Tüm örneklerimizde durum böyle olacaktır.

3.9. Uygulamanın kaynak kodunu ayrı bir klasöre taşıma

Daha sonra, aynı [dvp] klasöründe çeşitli [nuxt] uygulamaları oluşturacağız. Nitekim, her bir [nuxt] projesi için oluşturulan [node_modules] bağımlılık klasörü, yüzlerce megabayt büyüklüğünde olabilir. Test edilecek örneklerin kaynak kodlarını barındırmak üzere [dvp] klasörü içinde çeşitli [nuxt-00, nuxt-01, ...] klasörleri oluşturacağız. Ardından, [nuxt-config.js] yapılandırma dosyasını kullanarak, bu öğreticinin tek projesi olarak kalacak olan [dvp] projesinin kaynak kodunun nerede bulunduğunu belirteceğiz.

Başlangıçta [yarn create nuxt-app] komutuyla oluşturulan uygulamanın kaynak kodunu [nuxt-00] klasörüne taşıyoruz:

Image

  • [2]'te, [components, layouts, pages] klasörlerini [nuxt-00] klasörüne taşıdık;
  • [3]'te, [nuxt.config.js] dosyasını değiştirmemiz gerekiyor;

[nuxt.config.js] dosyasını şu şekilde değiştiriyoruz:


export default {
  mode: 'universal',
  /*
   ** Headers of the page
   */
  ...
  /*
   ** Build configuration
   */
  build: {
    /*
     ** You can extend webpack config here
     */
    extend(config, ctx) {}
  },
  // kaynak kod dizini
  srcDir: 'nuxt-00',
  // yönlendirici
  router: {
    // uygulamanın URL kök dizini
    base: '/nuxt-00/'
  },
  // sunucu
  server: {
    // hizmet bağlantı noktası, varsayılan olarak 3000
    port: 81,
    // dinlenen ağ adresleri, varsayılan olarak localhost: 127.0.0.1
    // 0.0.0.0 = makinedeki tüm ağ adresleri
    host: '0.0.0.0'
  }
}

Dosyada iki değişiklik yapıyoruz:

  • 17. satır: [dvp] projesinin kaynak kodunun [nuxt-00] klasöründe bulunduğu belirtilir;
  • 21. satır: Uygulamanın kök dizininin artık [/nuxt-00/] olduğu belirtilir. Bu değişiklik zorunlu değildi. Bu özelliği eklemeseydik, URL'in kökü [/] olurdu. Burada bu, yürütülen kaynak kodun [nuxt-00] klasöründekini olduğunu hatırlamamızı sağlayacaktır;

Bu işlem tamamlandıktan sonra, [dvp] projesi daha önce olduğu gibi çalıştırılır:

Image

3.10. [nuxt-00] uygulamasının dağıtımı

[nuxt-00] uygulamasını, VSCode'in entegre ortamından farklı bir ortamda çalıştıracağız.

Öncelikle uygulamayı derleyeceğiz:

Image

  • [3] olarak, yani istemcinin derleme sonucu. Tarayıcı tarafından çalıştırılacaktır;
  • [4] olarak, sunucu derlemesinin sonucu. [node.js] sunucusu tarafından çalıştırılacaktır;

Derleme sonucu [.nuxt] klasörüne yerleştirilir:

Image

[.nuxt, node_modules] klasörlerini ve [package.json, nuxt.config.js] dosyalarını ayrı bir klasöre kopyalıyoruz:

Image

[package.json] dosyası şu şekilde basitleştirilir:


{
  "scripts": {
    "start": "nuxt start"
  }
}
  • Projenin derlenmiş sürümünü çalıştırmaya olanak tanıyan yalnızca [start] komut dosyası saklanır;

[nuxt.config.js] dosyası şu şekilde basitleştirilir:


export default {
  // yönlendirici
  router: {
    // uygulamanın URL kökü
    base: '/nuxt-00/'
  },
  // sunucu
  server: {
    // hizmet bağlantı noktası, varsayılan olarak 3000
    port: 81,
    // dinlenen ağ adresleri, varsayılan olarak localhost: 127.0.0.1
    // 0.0.0.0 = makinedeki tüm ağ adresleri
    host: '0.0.0.0'
  }
}
  • 5. satır: Derlenmiş uygulamanın temel URL dosyası belirlenir;
  • 8-14. satırlar: hizmet bağlantı noktası ve dinlenecek ağ adresleri tanımlanır;

Bu işlem tamamlandıktan sonra, bir Laragon terminali açılır ve projenin derlenmiş sürümünü içeren klasöre gidilir. Herhangi bir terminal türü açılabilir, ancak [npm] yürütülebilir dosyasının terminalin PATH dizininde bulunması gerekir. Laragon terminalinde durum böyledir.

Bunu yaptıktan sonra, [npm run start] komutunu yazın:

Image

[3]'te, bir sunucunun başlatıldığını ve URL [http://192.168.1.128:81/nuxt-00/] adresinde dinleme halinde olduğunu görüyoruz. Şimdi bir tarayıcıyla URL adresine erişelim. [4] adresinde olduğu gibi aynı sonuçla karşılaşıyoruz. Terminal tarafında ise [5] logları kaydedildi. Bu log, [node.js] sunucusu tarafından yürütülen [index.vue] sayfasındaki [created] yöntemine yerleştirilen logdur.

Image

[6] tarayıcı tarafında ise, [index.vue] sayfasındaki [created] yöntemine ait günlük de bulunur; ancak bu sefer yöntem istemci tarafından yürütülmüştür.

3.11. Güvenli bir sunucunun kurulması

Yukarıda, uygulamanın URL değeri [http://192.168.1.128/nuxt-00/]'tir. Bunun [https://192.168.1.128/nuxt-00/] olmasını istiyoruz. Bu nedenle güvenli bir sunucu kurmamız gerekiyor. Nasıl yapılacağını göstereceğiz.

Not: Bu yöntem, [https://stackoverflow.com/questions/56966137/how-to-run-nuxt-npm-run-dev-with-https-in-localhost] başlıklı makaleden alınmıştır.

Öncelikle, [openssl] ile bir özel anahtar ve bir açık anahtar oluşturuyoruz. [openssl] normalde Laragon sunucusuyla birlikte kurulur. Dolayısıyla, bu komut tüm Laragon terminallerinde kullanılabilir. Şimdi bir Laragon terminali açalım ve dağıtılmış uygulamanın bulunduğu klasöre gidelim:

Image

Image

  • [2]'te, [openssl genrsa 2048 > server.key] komutunu yazalım;
  • [3] dosyasına, [server.key] dosyası oluşturulur;
  • [4] komutunda, [openssl req -new -x509 -nodes -sha256 -days 365 -key server.key -out server.crt] komutu girilir;
  • [5] dosyasında, [server.crt] dosyası oluşturulur;

Bu iki dosya, kendinden imzalı bir sertifikayı oluşturur. Çoğu tarayıcı, sayfayı talep eden kullanıcının onayı olmadan bu dosyaları kabul etmez.

[server.key, server.crt] dosyaları artık web uygulaması tarafından kullanılmalıdır. Bunun için [nuxt.config.js] dosyası şu şekilde değiştirilmelidir:


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

export default {
  // yönlendirici
  router: {
    // uygulamanın URL kökü
    base: '/nuxt-00/'
  },
  // sunucu
  server: {
    // hizmet bağlantı noktası, varsayılan olarak 3000
    port: 81,
    // dinlenen ağ adresleri, varsayılan olarak localhost: 127.0.0.1
    // 0.0.0.0 = makinedeki tüm ağ adresleri
    host: '0.0.0.0',
    // kendinden imzalı sertifika
    https: {
      key: fs.readFileSync(path.resolve(__dirname, 'server.key')),
      cert: fs.readFileSync(path.resolve(__dirname, 'server.crt'))
    }
  }
}

[https] protokolünü devreye sokan satırlar 18-21'dir.

Şimdi uygulamayı yeniden çalıştıralım:

Image

3.12. İlk örneğin sonu

İlk örnek artık tamamlandı. Bu örnek bize [nuxt] ile ilgili birçok kavramı öğretti. Şimdi, [nuxt-01, nuxt-02, ...] klasörlerine yerleştireceğimiz başka örnekler geliştireceğiz. Bu örnekler farklı bir [nuxt.config.js] dosyası kullanacağından, her bir klasöre, bunları çalıştırmak için kullanılan [nuxt.config.js] dosyasını kaydedeceğiz:

Image