Повторяющиеся require в Node JS, нормально ли это?

Здравствуйте. На досуге изучаю Node JS и Express, сгенерировал каркас приложения expressjs.com/...​ru/starter/generator.html и вижу, что в нем дважды в разных файлах есть такая строка:

var express = require('express');

Погуглив я узнал, что повторяющиеся require’ы — это нормально, так как модули кешируются, НО по мере роста приложения, не замахаешься ли копипастить кучу реквайров? Можно ли их всех выносить в отдельный файл и вообще, где можно посмотреть лучшие практики организации NodeJS-проекта?

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Вообще для базы в express имеет смысл написать middleware, которое будет создавать соединение с базой и добавлять его к req. Пример для koa, в express похоже будет github.com/...​ddleware/db-middleware.js

Вот это похоже и есть решение (подозреваю). Dependency Injection конечно тоже рассмотрю

Нет, их нельзя выносить. И как раз это лучшая практика.

«if» заборонити

если то, иначе — всё

DRY не распространяется на импорты

Это и есть «don’t repeat». Вы не повторяете СВОЙ код, вы ссылаетесь на чужой. И чем прямее вы это делаете — тем проще в вашем коде разобраться.

Кстати, с точки зрения поведенческой психологии, удобочитаемым будет код с повторением, притом 9:1 в пользу повторений. Правда в этой цифре учитывается всё, включая язык, стилистику, именование, и т.п., но сам факт — код должен быть предсказуемым для читателя. Никто не будет читать ВЕСЬ код, и тем более весь его помнить. Даже ты.

А це не логіка. Це ЗАЛЕЖНІСТЬ. І що б там не змінювалося в інших схожих ділянках, в тебе не має виникати потреби відслідковувати зміни по всіх залежностях. Навпаки: там де треба залежності змінити, ти зміниш, а все інше МАЄ ПРАЦЮВАТИ. Аж до того, що ти робиш залежність на конкретну версію, або декілька версій власного коду з іншими залежностями — наприклад для різних операційних систем.

В жс, в модуль, принято передавать только то что нужно. Потом замахаешся удалять мусор при модификиции кода, это не пхп ведь.

Потом замахаешся удалять мусор

sudo rm -rf /

Ну да, всё что есть в общем файле — это всё нужно. Если в каком-то модуле будет не всё нужно из общего файла, то этот файл сократиться, а другие модули дополнятся еще одной строчкой require

Придется переписывать, но это маловероятно, потому что это уже смена архитектуры приложения, а такое бывает только при резкой смене ТЗ. Ну вот хотя бы эти строки кода:

var mongoose = require('mongoose'); /
var config = require('../config');
mongoose.connect('mongodb://'+config.get('dbuser')+':'+config.get('dbpass')+'@'+config.get('dbhost')+':'+config.get('dbport')+'/'+config.get('db'), 
	{ useNewUrlParser: true });
почему нельзя вынести в отдельный файл? Автоимпорт же не вставит вам mongoose.connect...

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

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

Придется переписывать, но это маловероятно, потому что это уже смена архитектуры приложения, а такое бывает только при резкой смене ТЗ

Такое бывает каждый день. В хорошем случае — раз в неделю. Никто вам в 2019 не даст ТЗ, высеченное в камне и которое 100% никогда не поменяется.

Касаемо вашего вопроса — вынести соединение с базой можно, если нужно одно соединение везде

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

Теперь представим что вы подключили все это в одном файле, первом.
— во первых удаленный модуль будет висеть в памяти, что плохо во всех отношениях,
— во вторых гит, чтобы добавить модуль вы будете модифицировать один файл с другими людьми что равно перманентным гит конфликтам
— в третьих название модулей, перед тем как завести любую переменную, вам будет придется проверять не занято ли это имя где-то, а это запросто, например библиотека request. Сделать такой вариант рационально только глобальными переменными, если сделать иначе, то количество букв что вы набираете при require будет примерно тем же что и при любом другом способе кроме глобальных переменных.

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

А как ты без рекваера будешь к переменным обращаться? Всё в глобал писать? Или в объект и его всегда рекваерить? Зачем?

Или в объект и его всегда рекваерить? Зачем?

Да, общее — в объект, чтоб писать один require в каждом файле. Это же проще (ИМХО), DRY principle типа. Ну и там же не только require’ы будут, подключение к БД например тоже и другие одинаковые куски кода. ХЗ, может я не прав, тогда скажите как правильно

Правильно — разбивать программу на маленькие куски и require только то, что нужно в данном куске программы. Кусок — логически завершення единица.

Dependency injection можешь использовать, если стандартный подход не нравится

чому ви не любите автоімпорт?

не замахаешься ли копипастить кучу реквайров?

Не замахаешься ли копипастить кучу #include в C?

Не замахаешься ли копипастить кучу import в Java или Python?

Не замахаешься ли копипастить кучу using в C#?

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

Не замахаешься ли копипастить кучу #include в C?
Не замахаешься ли копипастить кучу import в Java или Python?
Не замахаешься ли копипастить кучу using в C#?

Хз, я этих языков не знаю, но по-идее должен быть какой-то способ вынести одинаковое отдельно и потом только подключать его. Вот у меня в двух файлах в проекте Node JS были одинаковые куски кода, которые я вынес в файл bootstrap.js:

var express = require('express');
var router = express.Router();
var jwt = require('jsonwebtoken');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var config = require('../config');
var userSchema = require('../models/users');

mongoose.connect('mongodb://'+config.get('dbuser')+':'+config.get('dbpass')+'@'+config.get('dbhost')+':'+config.get('dbport')+'/'+config.get('db'), 
	{ useNewUrlParser: true });

router.use(bodyParser.urlencoded({ extended: false }));
router.use(bodyParser.json());

module.exports = {
	router: router,
	jwt: jwt,
	mongoose: mongoose,
	config: config,
	userSchema: userSchema
};

МОЖНО ЛИ так делать в NodeJS ?

Да это разве куча? Развёл тут песни лебединые. Ты в Java энтерпрайз-приложения не видел, особенно где разные внутрикорпоративные огрызки кода за один нэймспейс воюют, а то и вовсе без такового объявлены. А уж если бы ты видел что творят Java-приложения с горячей перезагрузкой классов и вовсе бы прослезился.

Короче, не жадничай. Хотя это давно считается неправильным, но говномэнеджеры иначе не умеют: ценят тебя тем больше, чем больше кода ты пишешь. Так что не будь букой, и докинь побольше явных импортов и прочей бюрократии, благо концентрации смысла в коде оно не мешает, и лапками писать не надо, всё за тебя IDE делает.

тебе нужен Dependency Injection

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

ну в контексте того, что спрашивает автор, это неважно

И еще, какие сейчас стандарты-де-факто для Node JS?

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

Также искать легко в одном файле. И ненадо навигировать по сотням файлов чтоб понять что от чего зависит.

щас тебя жуны послушаются и потом «прощай целое поколение программистов»

вы что не слышали? новый модный подход у формошлепов: SFA — Single File Application

один файл всегда проще удалять

Распространять тоже проще. Т.н. «amalgamation» для небольших исходников (до лимона строк кода) — пока никто не отменял.

да, и зип компрессия на большом файле лучше работает

Підписатись на коментарі