Jak przygotować serwer do korzystania ze składni ES6? Zwięźle i na temat o konfiguracji babel-cli po stronie serwera, czyli dodatek do przyszłych postów na temat REST API.

NPM, Babel

Dobrą praktyką jest używanie w projekcie kilku mniejszych serwerów niżeli jednego odpowiedzialnego za wszystko. Najczęściej spotykanym podziałem jest oddzielenie API od clienta, co znacznie zwiększa wydajność i wygodę użytkowania zarówno aplikacji, jak i serwera. Dokładnie ten schemat wykorzystuję w projekcie AliTracker; serwer znajduje się w osobnym folderze i posiada własny plik package.json utworzony poprzez npm init.

Potrzebne packages to:

npm i -D babel-cli babel-preset-es2015 babel-preset-stage-2 nodemon
npm i -S express morgan body-parser cors

Konfigurację zaczynamy od utworzenia pliku .babelrc definiujący używane babel-presets:

{
  "presets": [
    "es2015",
    "stage-2"
  ]
 }

Do pliku package.json dodajemy skrypty, które obsłużą nową składnię ES6 i zajmą się kompilacją do wersji produkcyjnej:

  "scripts": {
    "start": "nodemon index.js --exec babel-node", //uruchomienie babel-node w nodemon, czyli zwiększamy wygodę pracy automatycznym resetowaniem serwera po wprowadzeniu zmian
    "build": "babel . -d build --ignore node_modules", //kompilacja kodu do wersji produkcyjnej
    "serve": "node build/index.js" //uruchomienie serwera w środowisku produkcyjnym
   },

index.js

Index.js domyślnie jest plikiem głównym, startowym projektu, dlatego tam umieścimy podstawę serwera. Dzięki uprzedniej konfiguracji korzystamy z wszelkich dogodności ES6. Najczęściej będą to:

  • arrow functions
  • import, export, export default
  • template strings
  • async, await
  • spread operator

W pliku głównym importujemy wszystkie potrzebne moduły, ustawiamy middlewares aplikacji takie jak morgan (loguje w konsoli dane o przychodzących requestach), cors (potrzebne, aby otrzymać requesty z innego źródła) oraz body-parser (w naszym przypadku wszelkie przechodzące dane parsuje do jsona). Poza tym inicjujemy zmienną PORT ze środowiska, ewentualnie jako 3010. Potem już tylko załączamy serwer:

import express from 'express';
import http from 'http';
import cors from 'cors';
import bodyParser from 'body-parser';
import morgan from 'morgan';
import router from './router';

const app = express();

app.use(cors());
app.use(morgan('tiny'));
app.use(bodyParser.json({ type: '*/*' }));
router(app);

const PORT = process.env.PORT || 3010;
const server = http.createServer(app);
server.listen(PORT, () => {
  console.log(`API server listening on ${PORT}`);
});

router.js

Na uwagę zasługuje jeszcze funkcja router, którą zaimportowałem z pliku router.js. Dzięki niej wszystkie nasze endpointy znajdują się w osobnym pliku:

export default function(app) {
  app.get('/api/hello', (req, res, next) => {
    res.status(200).send({ message: "If you spend too much time thinking about a thing, you'll never get it done. Make at least one definite move daily toward your goal." });
  });
}

Po takiej konfiguracji możemy sprawdzić czy wszystko działa i przemyśleć słowa Bruce’a Lee, które wstawiłem do powitalnego GET’a 🙂

quote

Cytat Bruce’a Lee

W następnych postach przejdziemy już do części dydaktycznej, ponieważ postaram się wyjaśnić czym API jest w ogóle, opisać podstawowe metody (ciekawe zagadnienie PUT vs PATCH) oraz pokazać jak korzystać z async/await podczas pracy z bazą danych.

Do zobaczenia!