Prosty i Nowoczesny Framework dla Vue.js
7 godz. 2 min · Vue.js · Full-stack i Programowanie
Wojciech PołowniakSr. Fullstack EngineerW tym projekcie tworzyć będziemy praktyczny projekt - klona Wikipedii! Minipedia pobierze dane z prawdziwego źrodła danych, zewnętrznego API WikiMedia - będzie łudząco podobna do oryginału oraz współdzieliła najważniejsze funkcjonalności, takie jak dostarczanie treści w różnych wersjach językowych, możliwość wyszukiwania artykułów, czy pobieranie najpopularniejszych wpisów dla danego języka. Stworzymy także podstronę wyświetlającą za każdym razem losowy artykuł w danej wersji językowej.Zobaczysz też, jak dokonać migracji ze statycznej strony HTML na Nuxt - oraz jak tworzyć przykładowe komponenty podczas tego procesu.Dzięki temu wszystkiemu, dowiesz się jak wykorzystać nabytą wiedzę w praktyce.
Dzięki Nuxtowi dowiesz się jak optymalizować Twoje strony www z duchem idei progressive enhancement, dostarczając coraz to lepsze doświadczenia dla swoich użytkowników oraz tworząc aplikację napisaną w 100% w JavaScript, która będzie działała nawet wtedy, gdy użytkownik jawnie wyłączy go w przeglądarce! To wszystko za SSR (Server Side Rendering), dzięki któremu treści będą gotowe do konsumpcji już przy wstępnej, pierwszej odpowiedzi z serwera WWW.Oczywiście, ma to swoje implikacje na wydajność naszej aplikacji - sprawiając że Lighthouse czy optymalizacja pod SEO staje się coraz prostsza!
Czymże jest ekosystem danego frameworka bez wsparcia społeczności! Dlatego podczas tego kursu nauczysz się instalować i wykorzystywać różne pluginy i moduły, które zaoszczędzą Ci dużo czasu. Dowiesz się też, jak tworzyć własne moduły - które rozszerzą działanie Twojej aplikacji Nuxt w sposób czysty i zarządzalny.
Nuxt jest frameworkiem w którym pracujemy zarówno po stronie front-endu, jak i back-endu. W związku z czym, stworzymy swoje własne API (bazujące na express.js) które będzie pewnego rodzaju pośrednikiem pomiędzy API WikiMedia oraz Twoją aplikacją internetową.
W tym kursie, dowiesz się także jak tworzyć swoje własne Middleware'y - czyli fragmenty kodu wywoływane pomiędzy przechodzeniem między stronami, czy podczas innych zapytań HTTP.Dodatkowo, zobaczysz jakie narzędzia daje nam Nuxt aby tworzyć progresywne aplikacje internetowe, oferując wsparcie dla takich funkcjonalności jak np. animacje między przejściami pojedynczymi podstronami naszego serwisu.
Tajemnicze i18n - czyli numeronim odpowiadający angielskiemu słowu "internalisation" - odnosi się w kontekście web developmentu do tłumaczenia danych na różne języki. Podczas realizacji projektu Minipedii, nie tylko wykorzystamy standardowe podejście do tłumaczeń stałych elementów naszego interfejsu użytkownika, ale także przetłumaczymy same dane zwracane z API, wykorzystując inną wersję językową w zależności od preferencji użytkownika!
Poznasz też kilka ciekawych pluginów i rozwiązań dotyczących optymalizacji pod SEO - poza faktem, że podejście spełniające intencje użytkownika jest najlepszym, co możemy zrobić - pluginy generujące nam mapę stron automatycznie na podstawie zadeklarowanych przez nas podstron, czy generatory danych jsonld pomogą w pozycjonowaniu Twojej wydajnej aplikacji jeszcze wyżej w hierarchii wyszukiwarek.
Aby móc efektywnie korzystać z tego kursu, powinieneś posiadać średnio zaawansowaną wiedzę z kategorii Front End, z naciskiem na umiejętność posługiwania się JavaScriptem oraz solidne podstawy NodeJS. Konieczna jest znajomość Vue, jako że Nuxt jest frameworkiem korzystającym z niego u swoich podstaw. Jeśli czujesz się dość swobodnie w wyżej wymienionych aspektach web developmentu, ten kurs będzie idealny dla Ciebie.
Cześć!
Z tej lekcji opowiem o budowaniu side map i generalnie w tym
całym dziale skupimy się na optymalizacji nexta dla wyszukiwarek.
Czy pod kątem wydajności?
Nie będziemy oczywiście tutaj aktualizować
całego projektu, ponieważ jest to proces bardzo długotrwały.
Natomiast wskażę tutaj różne moduły i rozwiązania, których można wykorzystać,
aby usprawnić te aspekty naszej strony www.
W związku z czym takim najpopularniejszym
modułem do generowania side map, czyli map strony dla Nexta jest
Next jest Sigma, czyli oficjalne rozszerzenie dla organizacji stronie.
Jest i mamy tutaj informacje jak z niego
korzystać, więc standardowo zainstalujemy sobie tą paczkę.
Przejdźmy tylko do odpowiedniego katalogu.
To jest lekcja 34, a ja instalujemy
i w międzyczasie możemy zacząć konfigurować nasz projekt.
Czyli analogicznie dodajemy do naszych modułów.
Next Czy jest Sigma?
Juz.
I tutaj jest chyba napisane
aby zawsze dodawać SID mapy na samym końcu naszych modułów.
W związku z czym jeżeli byśmy dodaj nowy moduł musimy przesunąć mapę.
Na koniec jest jakieś wymaganie, które
prawdopodobnie wiąże się z tym, że paczka próbuje wyrenderować tak dużo
podstron jak to tylko możliwe, w związku z czym musi być zatem budowana na końcu.
Zapiszemy.
I teraz konfiguracja SID mapy znajduje się tutaj.
Jak używać naszej zabawy.
Tutaj widzimy, że możemy przekazać obiekt konfiguracyjny.
Do naszej mapy.
Do tego modułu i przekazać domyślny URL na którym stoi nasz serwer.
W naszym przypadku jest to localhost 8000.
Więc.
Zastosujmy to NATO.
Jest to taka forma kompresji, która po prostu zmniejsza rozmiar naszych.
Assetów, które są później wysyłane
do przeglądarki, w związku z czym możemy go tutaj wyłączyć.
Ale generalnie produkcyjnie na pewno powinno być to włączone.
Możemy wyłączyć niektóre routery z renderowania.
Jeżeli chcemy ukryć panel logowania np.
z SID mapy, możemy wyeksportować niektóre
produkty z naszej mapy, jeżeli nie chcemy ich wyświetlać np.
jeżeli jest to admin panel czy inne tego typu ścieżki.
Nam na tym nie zależy, ale możemy to tak zostawić i tutaj, które są dynamiczne,
tak jak w przypadku Next Generation musieliśmy tutaj je ręcznie wpisać.
I przykładowo moglibyśmy tutaj napisać wiki.
Janusz czasem 20.
Korczak i w ten sposób wyrenderować te informację.
Dodatkowo dla każdego z raportów możemy podać różne parametry, takie jak Jak
często ta strona się zmienia i kiedy została ostatnio modyfikowana.
Na tym etapie nie jest nam to potrzebne, więc zapiszemy to.
I zobaczmy jakie tutaj mamy jeszcze opcje konfiguracji.
Czy coś jeszcze musimy zrobić.
Zobaczmy gdzie domyślnie ona jest renderowane.
Teraz mapa.
Wydaje mi się, że znajduje się ona pod głównym katalogiem Sitemap XML.
I faktycznie tak jest.
Jak widzimy te nasze rakiety, które mamy
zadeklarowane w naszych naklejkach, one się tutaj wygenerowały bez problemu.
Nie ma tutaj najbardziej popularnych stron.
Z naszego homepage.
Jestem ciekawy w sumie czemu tak się dzieje.
Wydaje mi się, że powinny się one tam
wyświetlić, chyba, że faktycznie nie są one wykrywane ze względu na to, że.
Jest to taki dynamiczny komponent, który przejmuje dane z serwerem serwera.
Byłoby to dosyć dziwne, ale generalnie jest to naprawdę proste.
Jak widzicie Sigma generuje się naprawdę szybko.
Tak naprawdę nie musieliśmy za dużo konfigurować, tylko wpisać nazwę.
Naszej podstrony http nie https i cała reszta stała się za nas.
A sitemap XML jest plikiem, z którego
wyszukiwarki takie jak Google często korzystają, aby indeksować treści.
Nie jest to oczywiście jedyny sposób, którego Google czy inne wyszukiwarki
wykorzystują, aby precyzować dane strony, w związku z czym fajnie jest mieć właśnie
taki plik xml, który jest generowane automatycznie.
Bo to zaś możemy tutaj sobie zautomatyzować, dodać jakieś skrypty,
które będą domyślnie wygrywały naszą domenę.
A jak widzimy sprowadziło się to tylko i wyłącznie do zainstalowania paczki i
przekazania prostego pliku konfiguracyjnego.
W kolejnej lekcji skupimy się na innym
module dla Nexta, którym będzie rozszerzenie do GM ld, czyli
czegoś co pozwala nam wykorzystywać deklaracje schema.
Org do określania semantyki naszej strony www.
Zmiany wprowadzone w lekcji · 5 min
diff --git a/34/minipedia/components/FullInfoBox.vue b/34/minipedia/components/FullInfoBox.vue
index 86dc3af..d753d18 100644
--- a/34/minipedia/components/FullInfoBox.vue
+++ b/34/minipedia/components/FullInfoBox.vue
@@ -7,13 +7,12 @@
<img
:src="mainImage" alt="Main image for the query">
<figcaption>
- Main image representing
+ Main image representing {{ $route.params.id }}
</figcaption>
</figure>
</td>
</tr>
-
<tr v-for="detail in textDetails">
<td>{{ convertToStartCase(detail[0]) }} </td>
<td>{{ renderOption(detail[1]) }} </td>
diff --git a/34/minipedia/nuxt.config.js b/34/minipedia/nuxt.config.js
index 9b868dc..33236bb 100644
--- a/34/minipedia/nuxt.config.js
+++ b/34/minipedia/nuxt.config.js
@@ -44,13 +44,24 @@ module.exports = {
buildModules: [
'~/modules/envalid.js'
],
-
+ sitemap: {
+ hostname: 'http://localhost:8000',
+ gzip: false,
+ exclude: [
+ '/secret',
+ '/admin/**'
+ ],
+ routes: [
+ '/wiki/Janusz%20Korczak'
+ ]
+ },
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
// https://go.nuxtjs.dev/axios
'@nuxtjs/axios',
'nuxt-basic-auth-module',
'nuxt-i18n',
+ '@nuxtjs/sitemap'
],
i18n: {
locales: [
diff --git a/34/minipedia/package-lock.json b/34/minipedia/package-lock.json
index c3ee6ce..9716e97 100644
--- a/34/minipedia/package-lock.json
+++ b/34/minipedia/package-lock.json
@@ -1976,6 +1976,47 @@
"http-proxy-middleware": "^1.0.6"
}
},
+ "@nuxtjs/sitemap": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/@nuxtjs/sitemap/-/sitemap-2.4.0.tgz",
+ "integrity": "sha512-TVgIYOtPp7KAfaUo76WRpGbO20j4D/xi/A7shFIGjARHs+FvfAWXNCtBT87dTwe/RoYzAsEKtijFFUTaSu5bUA==",
+ "requires": {
+ "async-cache": "^1.1.0",
+ "consola": "^2.13.0",
+ "etag": "^1.8.1",
+ "fresh": "^0.5.2",
+ "fs-extra": "^8.1.0",
+ "is-https": "^2.0.2",
+ "lodash.unionby": "^4.8.0",
+ "minimatch": "^3.0.4",
+ "sitemap": "^4.1.1"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
+ }
+ }
+ },
"@nuxtjs/youch": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/@nuxtjs/youch/-/youch-4.2.3.tgz",
@@ -2052,6 +2093,14 @@
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz",
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug=="
},
+ "@types/sax": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.1.tgz",
+ "integrity": "sha512-dqYdvN7Sbw8QT/0Ci5rhjE4/iCMJEM0Y9rHpCu+gGXD9Lwbz28t6HI2yegsB6BoV1sShRMU6lAmAcgRjmFy7LA==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"@types/source-list-map": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
@@ -2759,6 +2808,30 @@
"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
"dev": true
},
+ "async-cache": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/async-cache/-/async-cache-1.1.0.tgz",
+ "integrity": "sha1-SppaidBl7F2OUlS9nulrp2xTK1o=",
+ "requires": {
+ "lru-cache": "^4.0.0"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
+ }
+ }
+ },
"async-each": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
@@ -6824,6 +6897,11 @@
"is-extglob": "^2.1.1"
}
},
+ "is-https": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-https/-/is-https-2.0.2.tgz",
+ "integrity": "sha512-UfUCKVQH/6PQRCh5Qk9vNu4feLZiFmV/gr8DjbtJD0IrCRIDTA6E+d/AVFGPulI5tqK5W45fYbn1Nir1O99rFw=="
+ },
"is-negative-zero": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
@@ -7199,6 +7277,11 @@
"integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
"dev": true
},
+ "lodash.unionby": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/lodash.unionby/-/lodash.unionby-4.8.0.tgz",
+ "integrity": "sha1-iD8Jj/ePVkpye3UI4JzdU5c0u4M="
+ },
"lodash.uniq": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
@@ -10089,6 +10172,30 @@
"totalist": "^1.0.0"
}
},
+ "sitemap": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-4.1.1.tgz",
+ "integrity": "sha512-+8yd66IxyIFEMFkFpVoPuoPwBvdiL7Ap/HS5YD7igqO4phkyTPFIprCAE9NMHehAY5ZGN3MkAze4lDrOAX3sVQ==",
+ "requires": {
+ "@types/node": "^12.0.2",
+ "@types/sax": "^1.2.0",
+ "arg": "^4.1.1",
+ "sax": "^1.2.4",
+ "xmlbuilder": "^13.0.0"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "12.20.12",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.12.tgz",
+ "integrity": "sha512-KQZ1al2hKOONAs2MFv+yTQP1LkDWMrRJ9YCVRalXltOfXsBmH5IownLxQaiq0lnAHwAViLnh2aTYqrPcRGEbgg=="
+ },
+ "arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
+ }
+ }
+ },
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -12498,6 +12605,11 @@
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz",
"integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g=="
},
+ "xmlbuilder": {
+ "version": "13.0.2",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz",
+ "integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ=="
+ },
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
diff --git a/34/minipedia/package.json b/34/minipedia/package.json
index 6b8cca7..b88b88a 100644
--- a/34/minipedia/package.json
+++ b/34/minipedia/package.json
@@ -12,6 +12,7 @@
},
"dependencies": {
"@nuxtjs/axios": "^5.13.1",
+ "@nuxtjs/sitemap": "^2.4.0",
"body-parser": "^1.19.0",
"core-js": "^3.9.1",
"dotenv": "^9.0.0",
diff --git a/34/minipedia/pages/login.vue b/34/minipedia/pages/login.vue
index d3f84ec..d6304e6 100644
--- a/34/minipedia/pages/login.vue
+++ b/34/minipedia/pages/login.vue
@@ -1,7 +1,7 @@
<template>
<article class="content">
<h2>
- Login
+ {{ $t('Login') }}
</h2>
</article>
</template>
diff --git a/34/minipedia/pages/register.vue b/34/minipedia/pages/register.vue
new file mode 100644
index 0000000..3a27d9e
--- /dev/null
+++ b/34/minipedia/pages/register.vue
@@ -0,0 +1,12 @@
+<template>
+ <article class="content">
+ <h2>
+ {{ $t('Register') }}
+ </h2>
+ </article>
+</template>
+
+<script>
+export default {
+}
+</script>
\ No newline at end of file