Вступление

За свою карьеру я просмотрел сотни статей, посвященных NodeJS, и множество полных примеров NodeJS либо в типичном стеке MEAN, либо в конкретных примерах с использованием различных модулей NPM. Неотъемлемой частью написания на NodeJS является использование NPM или Yarn для установки библиотек, которые делают определенные вещи. В качестве примера, который знают все программисты Node, есть библиотеки Express-Passport-JWT-Mongo NPM.

Мы все знаем, что стек не останавливается на достигнутом. Express, вероятно, также потребует установки «body-parser» и «cors» и, возможно, дополнительных модулей Express NPM. Не забывайте Lodash, Underscore, Moment… и этот список можно продолжать и продолжать, поскольку есть тысячи и тысячи модулей NPM, которые можно использовать.

Разумное поддержание структуры модуля NPM

Обычно, когда вы просматриваете фрагменты кода или системы в поиске или пишете свой собственный, каждый файл будет содержать модули, необходимые для этого конкретного файла. Следующие фрагменты кода взяты из реальных фрагментов кода, доступных в сети:

  • Обратите внимание, что в этих примерах «var» следует заменить на «let» или «const» в зависимости от того, что делается.
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var bodyParser = require('body-parser');

Тогда другой файл может начинаться с:

var morgan = require('morgan');
var mongoose = require('mongoose');
var passport = require('passport');

И третий файл начнется с:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bcrypt = require('bcrypt-nodejs');

Вы можете представить себе остальные файлы, и их обычно очень много, даже в микросервисах, как они выглядят.

Что еще хуже, так это то, что вы также можете найти «require» в середине файла. Другими словами, код может занимать много строк, и внезапно кодировщик представит еще один модуль NPM. Обычно это происходит с неопытными или неорганизованными кодировщиками, но это невероятно распространенная практика, которая наносит ущерб пониманию и отладке кода.

Проблема, как вы хорошо понимаете, заключается в том, что это множество модулей NPM рано или поздно вызовет огромную головную боль при обслуживании системы, особенно в команде программистов, которым необходимо знать, что уже установлено и доступно, а что нет.

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

К счастью, Node предлагает довольно простой метод решения этих проблем. Ниже приводится метод, который я использую для серверных команд, работающих со стеком. Он поддерживает порядок, его легко найти, и каждый знает, что установлено, а что не установлено в системе. Это также позволяет выполнять чистую деинсталляцию, когда модуль NPM больше не нужен.

Если вы «функциональный» программист, другими словами, не все должно быть ООП с классами и «этим-› », следующее может фактически позволить вам пересмотреть совершенно новый метод использования функций и хранимых процедур.

Я предлагаю создать каталог в корневом каталоге проекта. Обычно я называю этот каталог «env», но вы можете называть его как хотите. «env» - это место, где я храню все свои библиотеки функций и хранимые процедуры, включая, если он используется, файл среды, необходимый для библиотеки NPM «dotenv». (Переменные среды могут храниться где угодно, их необязательно хранить в корневом каталоге проекта. Тем не менее, обсуждение переменных среды и «dotenv» относится к другой статье.) Другими словами, ваш «env» должен содержать только файлы, которые должны быть востребованы или доступны частям системы.

В каталоге «env» вне корня создайте файл с именем «helperMods.js». (Опять же, вы можете называть этот файл как хотите.) Кроме того, если ваша система будет использовать много модулей NPM или те, которые используются только для целей разработки (например, «мел»), вы можете разделить это на два или три файла. Однако в нашем простом примере мы будем использовать один файл.

module.exports = {
    request: require("request"), //used for request http
    fs: require('fs'),
    path: require('path'),
    chalk: require('chalk'),
    moment: require('moment'),
    express: require('express'),
    session: require('express-session'),
    eJWT: require('express-jwt'),
    bodyParser: require('body-parser'),
    cors: require('cors'),
    passport: require('passport'),
    passportLocal: require('passport-local'),
    crypto: require('crypto'),
    dotenv: require('dotenv'),
    jwt: require('jsonwebtoken'),
    jwtclaims: require('jwt-claims'),
    redis: require('redis'),
    mongodb: require('mongodb'),
    mongoose: require('mongoose'),
    assert: require('assert'),
    shortid: require('shortid'),
    badWords: require('bad-words'),
    enum: require('enum'),
    errorHandler: require('errorhandler'),
    morgan: require('morgan')
};

Сначала установите модуль NPM, который вы хотите использовать, например:

npm i jsonwebtoken --s

Теперь определитесь с вызывающим абонентом для этого модуля. Например, в приведенном выше файле jsonwebtoken сначала определяется как «jwt». Затем потребуйте фактический модуль, который вы установили. Итак, строка будет гласить:

jwt: require('jsonwebtoken'),

(Запятая в конце связана с форматом файла JSON.)

В этом файле нужно знать следующее:

1. Держите свои имена для призвания отчетливыми.

2. Несмотря на то, что вы видите выше, я бы расположил их в алфавитном порядке в соответствии с именами вызывающих абонентов или порядком алфавита модуля NPM.

3. Помните также, что даже если это встроенный модуль NodeJS, такой как «крипто» (да, «крипто» теперь, наконец, является частью внутреннего NodeJS) или «запрос», вам необходимо его потребовать.

4. Действительно, если вам действительно требуется много «собственных» модулей, вы можете разделить их на файлы, которые можно будет вызывать из первых нескольких строк в каждом файле, который вы запускаете.

5. Помните, что «пространства имен» защитят вас от двойной загрузки модуля в память. После того, как вы вызовете этот модуль в своем требовании, даже если вы снова вызовете его из другого файла, он не будет занимать больше или «дублировать» память.

После того, как вы настроили свой файл, метод вызова из любого файла довольно прост.

Каждый файл, который вы настраиваете или используете, должен начинаться с двух (или более) строк в зависимости от требуемых модулей. Например:

"use strict";
const helpMods = require("./env/helperMods");

Для приведенных выше строк потребуются все модули в вашем файле. Затем становится простым методом их вызова с использованием точечной записи.

Например, если вам нужно вызвать модуль badWords, ваша точечная нотация будет выглядеть так:

helpMods.badWords.(do whatever needs to be done normally here)

Если вы забудете helpMods, IDE, такая как WebStorm, выдаст вам предупреждение об ошибке, что модуль не требуется, которое немедленно сообщит вам, что вы забыли правильную точечную нотацию или что вы забыли включить этот модуль в свои основные экспортные данные. файл.

Поддержание функций пользователя в нормальном состоянии

Опять же, просмотрев множество примеров, вы найдете функции в файле. Часто эти функции являются «одноразовыми», другими словами, используются специально для очень конкретной ситуации, которая не повторяется. Или будет?

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

По этой причине я поддерживаю набор библиотек функций в каталоге «env». Обычно я стараюсь разделить эти функции на логические структуры. Например, все CRUD и другие действия с БД будут помещены в один файл библиотеки функций. Все охранные функции перейдут в другую. Это всего лишь предложение.

Что делает этот тип программирования:

  • Предоставляет вам и вашей команде контроль над окружающей средой.
  • Снижает потребность в определенных модулях снова и снова в каждом файле.
  • Предоставляет немедленный доступ к модулям NPM, которые, возможно, вам не нужны в файле.
  • Использует стандартную точечную нотацию без каких-либо обходных путей.
  • Позволяет вам разделить вашу структуру любым способом, который вы сочтете нужным, включая вызов функций в файлах функций и т. Д. Таким образом. Однако файл функции не записывается в структуре одного и того же типа. Вам потребуются:
"use strict";
const helpMods = require("./env/helperMods");

И любые другие файлы модулей, которые вы выбрали.

В этом примере мы будем использовать несколько функций, разделенных по порядку для нашей системы. Затем напишем и определим все функции с обратными вызовами, обещаниями или async / await. Назовем файл «generalFuncs.js». У каждой функции есть имя.

Function(getExactTime(passed params go in here){
/do stuff in here
}
Function(logFile(passed params go in here){
//do stuff in here
}

Добавьте в этот файл столько функций, сколько вам нужно. Итак, в конце файла функции вы должны написать:

module.exports = {getExactTime, logfile, HTMLResponse, getRemoteConnect, doesKeyExist, generateUniqueKey, restartAll, createDateFromString};

Вышеупомянутое позволит этим функциям быть доступными в точечной нотации для любого файла, который вы добавляете:

"use strict";
const helpMods = require("./env/helperMods");
const generalFuncs = require (../env/generalFuncs");

Теперь, когда вы используете функцию «getExactTime», вы получаете доступ к ней следующим образом:

generalFuncs.getExactTime(whatever is needed goes here);

В качестве дополнительного плюса в любой хорошей среде IDE вы сможете увидеть, какие функции никогда не экспортируются, поскольку они никогда не потребуются ни в одной системе.

Заключение

Вышеупомянутые методы позволят вам контролировать и понимать, что используется в системе. Файлы функций позволят рефакторинг функций по маршруту всякий раз, когда это необходимо. Точечная запись позволит вам просто и упорядоченно вызывать модули или функции.

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

Между прочим, ничто из этого не повлияет на версии GitHub или элементы управления версиями. Действительно, проверка, рефакторинг и тестирование станут намного проще. Отдельные строки могут быть отмечены только для систем разработки, другие - для производственных систем.

Если вы сможете обернуться вокруг этого стиля кодирования, по крайней мере, с точки зрения модулей и, возможно, функций, вы найдете свой код более чистым, более легким для чтения, доступным для всей команды и более легким для рефакторинга.

________________________________________________________

Об авторе: Тед Гросс много лет занимал должность технического директора с опытом работы в технологиях баз данных, NodeJS, MongoDB, шифровании, PHP и ООП. Он имеет опыт в технологиях виртуального мира и дополненной реальности. Он также опубликовал множество статей на технологические темы, особенно по Big Data & Chaos Theory (в профессиональных журналах и в Интернете на @ Medium и LinkedIn). Он также является автором художественной литературы, детских книг и различных научно-популярных статей. Его сборник рассказов « Древние сказки, современные легенды » получил отличные отзывы.

С Тедом можно связаться по электронной почте: [email protected]; Твиттер (@tedwgross); LinkedIn; "Середина"