Сейчас доступно приличное количество материалов по написанию API на node.js. Большинство из них в виде туториалов и демо-примеров в документациях. Этого достаточно, чтобы быстро разобраться и написать что-то свое. Но в них редко найдутся детали, почему это делается именно так. А некоторые моменты и вовсе опускаются для простоты и краткости.
Это статья нацелена, чтобы заполнить некоторые пробелы, которые могли возникнуть, и в конечном счете улучшить вам сервис на node.js.
P.S. Ни в коем случае не считаю себя экспертом: есть куда расти. Но вместе с тем есть чем поделиться.
Файловая структура — базовая, но очень важная вещь. При ее создании стоит предусмотреть возможность масштабирования сервиса, именно по этой причине не стоит размещать файлы в плоской структуре одного каталога. Нужна иерархия, нужна модульность.
При наименовании каталогов необходимо придерживаться устоявшихся стандартов. Это поможет коллегам и самому через пару месяцев быстро сориентироваться где и что находится.
Пример файловой структуры
Примечания:
Конечно, вы можете не использовать babel или typescript для преобразования вашего javascript`а. Как правило, новые стандарты ECMAScript`а быстро оказываются в node.js, да и вы, в исключение от браузерного javascript'a, способны контролировать их поддержку.
Но я убежден, что их стоит использовать. И вот почему:
Рассмотрим добавление babel`я в проект:
Установим зависимости:
Добавим конфигурационный файл .babelrc в корень проекта
Пример запуска скрипта
Примечания:
Начнем с очевидного факта: линтеры нужны. Мы пишем код, много кода. Так много что, сами не способны контролировать его единообразие. Этот пункт неимоверно усиливается при командной разработке.
А единообразие — залог читаемости кода.
Остается вопрос о строгости линтера. Выбор которой должен основывается на размерах команды, их профессиональном уровне, важным критерием выступает сам проект.
Добавление простого линтера в проект
Установим зависимости:
Добавим конфигурационный файл .eslintrc в корень проекта:
Как правило, такого конфига не достаточно. Тут либо самому расширять правила или присмотреться на заготовленные более строгие варианты.
Использование более строгого линтера
Сейчас есть несколько популярных конфигураций на основе одноименных стайл-гайдов.
Соответственно, необходимо будет подправить .eslintrc
Также необходимо добавить запуск линтера в отдельный скрипт.
Любой, кто имеет доступ к репозиторию проекта, должен суметь запустить его. Сможет ли он это сделать и сколько ему для этого понадобиться времени — это один из ваших критериев качества проекта.
Важно заранее продокументировать как пошагово запустить сервис в README.md файле, а также прописать команды для основных действий.
Чтобы использовать вышеприведенные команды, вам возможно понадобиться установить следующие пакеты:
Примечание:
Первоначально в статье хотелось осветить гораздо больше рекомендаций по написанию API на node.js, но хочется укладываться в 3-5 мин. прочтении статьи. При условии хорошей обратной связи выйдет продолжение.
Это статья нацелена, чтобы заполнить некоторые пробелы, которые могли возникнуть, и в конечном счете улучшить вам сервис на node.js.
P.S. Ни в коем случае не считаю себя экспертом: есть куда расти. Но вместе с тем есть чем поделиться.
Файловая структура проекта
Файловая структура — базовая, но очень важная вещь. При ее создании стоит предусмотреть возможность масштабирования сервиса, именно по этой причине не стоит размещать файлы в плоской структуре одного каталога. Нужна иерархия, нужна модульность.
При наименовании каталогов необходимо придерживаться устоявшихся стандартов. Это поможет коллегам и самому через пару месяцев быстро сориентироваться где и что находится.
Пример файловой структуры
src/
controllers/
users/
index.js
index.js
db/
mongo/
index.js
index.js
helpers/
middlewares/
auth.js
models/
users.js
routes/
users/
index.js
index.js
index.js
.eslintrc
.gitignore
README.md
...
package.json
Примечания:
- Все исполняемые файлы должны располагаться в ./src
Это позволит отделить исходные файлы от скомпилированных typescript`ом или babel`ем, которые будут располагаться в ./dist или ./build.
Также это позволит легче настроить линтеры и прочие конфигурируемые инструменты, так как целевые файлы располагаются в отдельном каталоге.
- Все сущности контроллеров и роутов размещайте в отдельных каталогах
Это позволит открыв ./routes или ./controller, увидеть лишь один index.js файл, импортирующий и экспортирующий сущности подкаталогов.
Это позволит быстрее сориентироваться в имеющемся функционале, так как он описывает лишь интерфейс контроллеров или роутеров без вникания в их реализацию.
О компиляции Javascript
Конечно, вы можете не использовать babel или typescript для преобразования вашего javascript`а. Как правило, новые стандарты ECMAScript`а быстро оказываются в node.js, да и вы, в исключение от браузерного javascript'a, способны контролировать их поддержку.
Но я убежден, что их стоит использовать. И вот почему:
- Не всегда последняя версия Node.js доступна для продакшена.
- У Node.js (v. 13) до сих пор есть проблемы с поддержкой ECMAScript модулей, хоть они и появились и ушли из-под флага, но до сих пор являются экспериментальными. Для прода рано.
Рассмотрим добавление babel`я в проект:
Установим зависимости:
npm install @babel/core @babel/node @babel/preset-env --save-dev
Добавим конфигурационный файл .babelrc в корень проекта
{
"presets": [
"@babel/preset-env"
]
}
Пример запуска скрипта
"start": "nodemon --exec babel-node src/index.js",
Примечания:
- Не забывайте при установки зависимостей, необходимых только на этапе разработки проставлять ключ --save-dev (-D). Это необходимо как минимум для семантики.
О необходимости линтеров
Начнем с очевидного факта: линтеры нужны. Мы пишем код, много кода. Так много что, сами не способны контролировать его единообразие. Этот пункт неимоверно усиливается при командной разработке.
А единообразие — залог читаемости кода.
Остается вопрос о строгости линтера. Выбор которой должен основывается на размерах команды, их профессиональном уровне, важным критерием выступает сам проект.
Добавление простого линтера в проект
Установим зависимости:
npm install eslint --save-dev
Добавим конфигурационный файл .eslintrc в корень проекта:
{
"env": {
"node": true,
"es6": true,
},
"extends": "eslint:recommended"
}
Как правило, такого конфига не достаточно. Тут либо самому расширять правила или присмотреться на заготовленные более строгие варианты.
Пример добавление, новых правил
...
"extends": "eslint:recommended",
"rules": {
"quotes": ["error", "single"]
}
}
Использование более строгого линтера
Сейчас есть несколько популярных конфигураций на основе одноименных стайл-гайдов.
- Google
npm install --save-dev eslint-config-google
- Airbnb
npm install --save-dev eslint-config-airbnb-base eslint-plugin-import
- Idiomatic
npm install --save-dev eslint-config-idiomatic
Соответственно, необходимо будет подправить .eslintrc
{
"env": {
"node": true,
"es6": true,
},
"extends": "google" | "airbnb-base" | "idiomatic"
}
Также необходимо добавить запуск линтера в отдельный скрипт.
"lint": "eslint ./src --cache && echo \"eslint: no lint errors\"",
"lint:fix": "eslint ./src --fix && echo \"eslint: no lint errors\""
О запуске приложения
Любой, кто имеет доступ к репозиторию проекта, должен суметь запустить его. Сможет ли он это сделать и сколько ему для этого понадобиться времени — это один из ваших критериев качества проекта.
Важно заранее продокументировать как пошагово запустить сервис в README.md файле, а также прописать команды для основных действий.
"start": "npm run dev",
"dev": "nodemon --exec babel-node ./src/index.js",
"build": "babel ./src --out-dir ./build",
"prod": "NODE_ENV=production node ./build/index.js",
"lint": "eslint ./src --cache && echo \"eslint: no lint errors\"",
Чтобы использовать вышеприведенные команды, вам возможно понадобиться установить следующие пакеты:
npm install --save-dev @babel/cli nodemon babel-node
Примечание:
- Если вы даже добавили основные команды в package.json, все равно опишите в README.md процесс запуска.
Заключение
Первоначально в статье хотелось осветить гораздо больше рекомендаций по написанию API на node.js, но хочется укладываться в 3-5 мин. прочтении статьи. При условии хорошей обратной связи выйдет продолжение.