197 lines
7.6 KiB
TeX
197 lines
7.6 KiB
TeX
\section{Node.js Alapok}
|
|
|
|
\begin{frame}{Mi a Node.js?}
|
|
\footnotesize
|
|
A Javascript eredetileg kizárólag böngészőkben futott. A \textbf{Node.js} ezt változtatta meg: kiszedte a Google Chrome V8 motorját a böngészőből, és lehetővé tette, hogy Javascript kód a szerveren, önállóan is fusson -- így írhatunk vele backend alkalmazásokat, parancssori eszközöket, akár build-rendszereket is.
|
|
|
|
\begin{itemize}
|
|
\item JavaScript futtatókörnyezet a V8 motoron alapulva
|
|
\item Szerveroldali JavaScript fejlesztés lehetősége
|
|
\item Eseményvezérelt, nem blokkoló (non-blocking) I/O modell
|
|
\item Létrehozta: Ryan Dahl (2009)
|
|
\end{itemize}
|
|
|
|
\begin{block}{Miért Node.js?}
|
|
Ugyanazt a nyelvet használhatjuk frontend és backend oldalon is, hatalmas npm ökoszisztéma áll rendelkezésre szinte bármilyen problémára, és gyors vele a fejlesztés, prototípuskészítés.
|
|
\end{block}
|
|
\end{frame}
|
|
|
|
\begin{frame}{Node.js architektúra}
|
|
\footnotesize
|
|
A Node.js két fő komponensre épül: a Javascript kódot lefordító és futtató \textbf{V8 motorra}, valamint a háttérben futó \textbf{libuv} könyvtárra, ami az aszinkron I/O műveleteket (fájl, hálózat) kezeli.
|
|
|
|
\begin{columns}
|
|
\begin{column}{0.48\textwidth}
|
|
\begin{block}{V8 JavaScript Engine}
|
|
\begin{itemize}
|
|
\item Google Chrome motorja
|
|
\item JIT (Just-In-Time) fordítás
|
|
\item C++ nyelven íródott, rendkívül gyors
|
|
\end{itemize}
|
|
\end{block}
|
|
\end{column}
|
|
\begin{column}{0.48\textwidth}
|
|
\begin{block}{libuv}
|
|
\begin{itemize}
|
|
\item Event loop implementáció
|
|
\item Aszinkron I/O műveletek
|
|
\item Cross-platform támogatás
|
|
\end{itemize}
|
|
\end{block}
|
|
\end{column}
|
|
\end{columns}
|
|
|
|
\begin{alertblock}{Event Loop}
|
|
Timers $\to$ Pending callbacks $\to$ Poll (I/O) $\to$ Check $\to$ Close callbacks. A Node.js egyetlen szálon (single-threaded) fut, de az I/O műveletek aszinkron módon, a háttérben zajlanak -- így egy lassú fájlművelet nem blokkolja a többi kérés kiszolgálását.
|
|
\end{alertblock}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]{Első Node.js program}
|
|
\footnotesize
|
|
Nézzünk egy egyszerű, de tanulságos első programot, ami megmutatja, milyen beépített, Node.js-specifikus változókhoz férünk hozzá.
|
|
|
|
\begin{block}{hello.js -- futtatás: \texttt{node hello.js}}
|
|
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
|
console.log('Hello, Node.js!');
|
|
console.log('Node verzio:', process.version);
|
|
console.log('Aktualis konyvtar:', __dirname);
|
|
\end{lstlisting}
|
|
\end{block}
|
|
|
|
\begin{alertblock}{Fontos}
|
|
A Node.js nem böngésző! Nincs \texttt{window}, nincs \texttt{document}, de van helyette \texttt{global} (a böngésző \texttt{window}-jának megfelelője) és \texttt{process} (a futó Node.js folyamatról ad információt).
|
|
\end{alertblock}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]{Modulrendszer -- CommonJS}
|
|
\footnotesize
|
|
Ahogy a kódunk növekszik, elkerülhetetlen, hogy több fájlra bontsuk. A Node.js hagyományos, alapértelmezett modulrendszere a \textbf{CommonJS}, ahol a \texttt{require} és a \texttt{module.exports} párossal osztunk meg kódot fájlok között.
|
|
|
|
\begin{columns}
|
|
\begin{column}{0.48\textwidth}
|
|
\begin{block}{math.js -- export}
|
|
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
|
function add(a, b) {
|
|
return a + b;
|
|
}
|
|
module.exports = { add };
|
|
\end{lstlisting}
|
|
\end{block}
|
|
\end{column}
|
|
\begin{column}{0.48\textwidth}
|
|
\begin{block}{app.js -- import}
|
|
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
|
const math = require('./math');
|
|
console.log(math.add(2, 3));
|
|
// 5
|
|
\end{lstlisting}
|
|
\end{block}
|
|
\end{column}
|
|
\end{columns}
|
|
|
|
\begin{block}{Beépített (core) modulok}
|
|
A Node.js számos hasznos modult ad eleve a kezünkbe, telepítés nélkül: \texttt{fs} (file system, fájlkezelés), \texttt{path} (útvonalak kezelése), \texttt{http} (webszerver készítése).
|
|
\end{block}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]{ES Modules (ESM)}
|
|
\footnotesize
|
|
A modern Javascript szabvány, az ECMAScript saját, egységes modulrendszert vezetett be \texttt{import}/\texttt{export} kulcsszavakkal -- ugyanezt ismerheted a frontend keretrendszerekből (React, Vue) is. A Node.js is támogatja ezt, ha bekapcsoljuk.
|
|
|
|
\begin{columns}
|
|
\begin{column}{0.48\textwidth}
|
|
\begin{block}{math.mjs -- export}
|
|
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
|
export function add(a, b) {
|
|
return a + b;
|
|
}
|
|
\end{lstlisting}
|
|
\end{block}
|
|
\end{column}
|
|
\begin{column}{0.48\textwidth}
|
|
\begin{block}{app.mjs -- import}
|
|
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
|
import { add } from './math.mjs';
|
|
console.log(add(2, 3));
|
|
\end{lstlisting}
|
|
\end{block}
|
|
\end{column}
|
|
\end{columns}
|
|
|
|
\begin{alertblock}{package.json}
|
|
Az ESM használatához be kell állítani: \texttt{\{"type": "module"\}} a \texttt{package.json} fájlban -- ekkor a \texttt{.js} kiterjesztésű fájlok is ES modulként fognak viselkedni.
|
|
\end{alertblock}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]{File System műveletek}
|
|
\footnotesize
|
|
A backend fejlesztés egyik leggyakoribb feladata fájlokkal dolgozni (konfiguráció olvasása, log írása, feltöltött fájlok kezelése). A Node.js \texttt{fs} modulja ehhez háromféle API-t is kínál.
|
|
|
|
\begin{block}{Fájl olvasás -- Promise API (ajánlott)}
|
|
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
|
const fs = require('fs').promises;
|
|
|
|
async function readData() {
|
|
const data = await fs.readFile('input.txt', 'utf8');
|
|
console.log(data);
|
|
}
|
|
\end{lstlisting}
|
|
\end{block}
|
|
|
|
\begin{itemize}
|
|
\item \texttt{readFileSync} -- szinkron, blokkolja a végrehajtást, amíg be nem fejeződik (kerülendő szerveroldalon)
|
|
\item \texttt{readFile} callback-kel -- aszinkron, a régebbi, callback-alapú stílus
|
|
\item \texttt{fs.promises} -- aszinkron, \texttt{async/await}-tel szépen, szinkron kódként olvasható -- ma ez az ajánlott megoldás
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]{HTTP szerver létrehozása}
|
|
\footnotesize
|
|
Ahogy korábban láttuk, a HTTP request-response modellt bármilyen nyelven meg lehet valósítani. Node.js-ben a beépített \texttt{http} modullal mindössze néhány sorból már működő webszervert tudunk indítani -- ez az alapja mindannak, amit a következő heteken Express.js-szel fogunk csinálni.
|
|
|
|
\begin{block}{Egyszerű HTTP szerver}
|
|
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
|
const http = require('http');
|
|
const server = http.createServer((req, res) => {
|
|
res.statusCode = 200;
|
|
res.setHeader('Content-Type', 'text/plain');
|
|
res.end('Hello, Node.js szerver!\n');
|
|
});
|
|
server.listen(3000, () => {
|
|
console.log('Szerver fut: http://localhost:3000');
|
|
});
|
|
\end{lstlisting}
|
|
\end{block}
|
|
\end{frame}
|
|
|
|
\begin{frame}{Node.js vs. Böngésző}
|
|
\footnotesize
|
|
Fontos tudatosítani, hogy bár mindkét környezetben Javascript kód fut, a Node.js és a böngésző \emph{teljesen más} környezetet biztosítanak -- más API-k érhetők el, és más a rendeltetésük is.
|
|
|
|
\begin{tabular}{|l|l|l|}
|
|
\hline
|
|
\textbf{Jellemző} & \textbf{Node.js} & \textbf{Böngésző} \\
|
|
\hline
|
|
DOM API & Nincs & Van \\
|
|
\texttt{window} objektum & Nincs & Van \\
|
|
Globális objektum & \texttt{global} & \texttt{window} \\
|
|
File system & Van (\texttt{fs}) & Nincs \\
|
|
HTTP szerver & Készíthető & Nem \\
|
|
Használat & Backend, CLI & Frontend \\
|
|
\hline
|
|
\end{tabular}
|
|
\end{frame}
|
|
|
|
\begin{frame}{Összefoglalás -- Node.js}
|
|
\footnotesize
|
|
\begin{block}{Node.js alapok}
|
|
\begin{itemize}
|
|
\item V8 engine alapú JavaScript futtatókörnyezet, szerveroldalon
|
|
\item Event-driven, non-blocking I/O modell -- egy szálon, de aszinkron módon
|
|
\item Modulrendszer: CommonJS (\texttt{require}) és ES Modules (\texttt{import})
|
|
\item Beépített modulok: \texttt{fs} (fájlok), \texttt{path} (útvonalak), \texttt{http} (szerver)
|
|
\item HTTP szerver készítése pár sorban -- ez az alapja a jövő heti Express.js-nek
|
|
\end{itemize}
|
|
\end{block}
|
|
\end{frame}
|