Базовое приложение на Node.js и TypeScript

Создание базового приложения Node.js на языке TypeScript

29 июня 2019
Node.js TypeScript

Введение

В этой статье, я хочу рассказать, как создать базовое приложение на Node.js используя типизированный язык TypeScript.

Мне очень нравится программировать на Node.js, а так же из за частого использования на фронтендах Angular, я уже совсем привык писать на TypeScript языке. Стоит его использовать в node.js или нет все же рашать вам, но раз вы читаете эту статью, значит уже пришли к такой мысли ;)

Исходный код этой статьи находится в моем GIT репозитории в открытом доступе https://git.s-vl.ru/httpxss/nodejs-typescript-starter

Создание приложения

Итак создаем нашу основу для проекта, определимся где он будет у нас лежать и создадим там под него директорию:

mkdir nodejs-typescript-starter

Инициализируем наш проект:

npm init

Далее мы будем устанавливать необходимые пакеты, все что относится к TypeScript я ставлю в "devDependencies", остальное то, что уже будет работать в скомпилированном виде на сервере в "dependencies".

Для начала поставим пакет tsc и typescript, а так же установим tsc глобально в систему:

npm i -D tsc typescript
sudo npm i -g tsc

В package.json добавляем исполнение команды для npm чтобы использовать tsc:

...
"scripts": {
    "tsc": "tsc",
...

Сгенерируем tsconfig.json для нашего приложения:

npm run tsc -- --init

В директории "src" будем хранить исходники приложения, а в "dist" собранное приложение. Для начала надо настроить tsconfig.json, в нем уже имеются все необходимые параметры, нужно только раскоментировать нужную опцию и задать по необходимости свои параметры. Каждая опция подробно расписана для чего предназначена, для примера я составил такой конфиг:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "lib": [
      "es2016",
      "dom"
    ],
    "declaration": false,
    "sourceMap": false,
    "outDir": "./dist",
    "removeComments": true,
    "strict": true,
    "noImplicitAny": true,
    "moduleResolution": "node",
    "baseUrl": "src",
    "paths": {
      "*": [
        "node_modules/*"
      ]
    },
    "typeRoots": [
      "node_modules/@types"
    ],
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "resolveJsonModule": true
  },
  "include": [
    "src/**/*",
  ]
}

Установим Express, причем поставим его как в типизированном виде для разработки, так и для работы на сервере.

npm i @types/express -D
npm i express -s

Создаем стартовый скрипт index.ts в директории с исходниками:

import Express, { Application, Request, Response } from 'express';

const app: Application = Express();

app.get('/', (req: Request, res: Response) => {
    res.send('Hello im Node.js & TypeScript starter!');
});

app.listen(3000, _ => {
    console.info('Application listening on http://localhost:3000');
});

Отлично, теперь проверим процесс компиляции:

npm run tsc

В директории "dist" лежит собранный index.js который можно запустить и проверить, что все работает отлично:

node dist/index.js

Но теперь нам надо отладить процесс разработки, node.js может исполнять .ts файлы, для этого ставим специальный пакет ts-node-dev с помощью которого можно запускать .ts файлы, а так же выполнять перезапуск скрипта в случае внесенных изменений:

npm install ts-node-dev -D

Добавим в package.json команду для запуска development окружения:

...
  "scripts": {
    "tsc": "tsc",
    "dev": "ts-node-dev --respawn --transpileOnly ./src/index.ts",
...

Теперь запускаем node.js командой:

npm run dev

Сервер запущен! Теперь когда будут вноситься изменения в приложение ts-node-dev будет перезапускаться и это позволит его отлаживать. 

Пример дальнейшего использования

Важным моментом явзяется то, что не забывайте ставить пакеты для сервера (не типизированные). Для примера, я расширю немного это приложение, чтобы было понимание происходящего.

Установим пакеты для Express:

npm i @types/cookie-parser -D
npm i @types/body-parser -D

Эти пакеты типизированны и они будут у вас работать пока вы не скомпилируете проект, т.к. после компиляции у вас будут уже .js файлы и соответственно пакеты нужны для запуска в production обычные. Ставим тоже самое, только для production:

npm i cookie-parser -s
npm i body-parser -s

Создаем директорию static для статики и router. Поместим в роутер - главну страницу, назовем файл main.ts:

import Express, { Request, Response, NextFunction } from 'express';

const router = Express.Router();

router.get('/', (req: Request, res: Response, next: NextFunction) => {
    res.send('Hello im Node.js & TypeScript starter!');
});

export default router;

Соответственно приведу главный файл index.ts примерно к такому же виду, как это на Express только уже в TS виде:

import path from 'path';
import http from 'http';
import Express, { Application, Request, Response } from 'express';
import cookieParser from 'cookie-parser';
import bodyParser from 'body-parser';

// Router
import mainRouter from './router/main';

const app: Application = Express();

app.use(Express.json());
app.use(Express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: true
}));

app.use('/static', Express.static(path.join(__dirname, 'static')));

app.use('/', mainRouter);

const server = http.createServer(app);
server.listen(3000);

server.on('error', error => {
    console.error(`Error HTTPD Server: ${error.message}`);
    process.exit();
});

server.on('listening', () => {
    console.info('Application listening on http://localhost:3000');
});

Теперь можно скомпилировать приложение и посмотреть результат выполнив команду npm run tsc. Как будет видно в директории "dist" будет вся структура проекта на .js, но без статики (директории static), а так же необходимо чистить предыдущую компиляцию, малоли вы решите поменять структуру.

Для удобства ставим глобально пакет npm-run-all, он позволит запускать команды npm по очереди:

sudo npm i -g npm-run-all

Добавим команды для чистки, компиляции копирования статических файлов:

...
  "scripts": {
    "clean": "if [[ -d ./dist ]]; then rm -rf ./dist; fi;",
    "copy-static": "cp -r ./src/static ./dist/static",
    "build": "npm-run-all clean tsc copy-static",
    "tsc": "tsc",
    "dev": "ts-node-dev --respawn --transpileOnly ./src/index.ts",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
...

Теперь собрать проект для production можно выполнив команду npm run build.

Заключение

Как видно, разрабатывать на TypeScript с Node.js просто, бывает конечно, что некоторых модулей нет в типизированном виде в npm репозитории но для этого можно задекларировать ихние методы на TS и использовать.

Исходный код, вы можете склонировать с моего GIT репозитория - https://git.s-vl.ru/httpxss/nodejs-typescript-starter

Design by Popov Aleksey

Copyright S-VL © 2010. All rights reserved.