Неконсистентное форматирование кода. Посмотрите в сторону prettier.
// ━━━━━━━━━━━━━━━━━━━━━━━━━┑ Есть пробел перед ":"
constructor(private logLevel : number = 2, readonly path: string = "") { }
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┙Нет проблела перед ":"
/**
* Logs a stack debug to the console.
* @param {any[]} args - Information parts for log message.
*/
debug(...args: any[]) {
if (this.logLevel <= 0) console.debug(this.generateOutput(args));
}
// Комментарий куда-то сместился влево
/**
* Logs a message to the console.
* @param {any[]} args - Information parts for log message.
*/
log(...args: any[]) {
if (this.logLevel <= 1) console.log(this.generateOutput(args));
}
Потенциальный crash приложения, если вдруг будет циклический JavaScript объект. console.log в такой ситуации отработает корректно.
if (typeof arg === 'object') {
return JSON.stringify(arg);
}
Потенциальные утечки памяти. Вы храните все логгеры в Map, но я не вижу как можно удалить один конкретный логгер. Есть только clearAllLoggers, который не факт что вызовется. Попробуйте посмотреть в сторону WeakMap.
Метод setLogLevelsByAllLoggers и setLogLevel делают почти одно и тоже (дублирование кода). Почему просто не сделать параметр searchPath в setLogLevel опциональным и устанавливать значения во всех логгерах если он не передан?
Вместо метода containsPath можно было бы обойтись регулярным выражением.
Зачем defaultPathPostfix в LoggerFactory public?
Зачем LoggerFactory это класс если имеет только static методы? Такого же эффекта можно добиться если переписать класс на функции и экспортировать только публичные.
Если уж так хочется в ООП, то его нужно реализовывать правильно. А как правильно, можно посмотреть тут на примере. В данный момент ощущение что LoggerFactory это недобилдер-недофабрика ещё и синглтон.
Множественные опечатки
defaultLogLeevl
recetDefaults
mathc to searchPath
unic name
Если Вам вдруг нужен удобный функциональный логгер для браузера, посмотрите в сторону consola. Как будто бы он удовлетворяет всем Вашим потребностям.
В redux проблему бойлерплейта (а как я понял с ним автор и борется) легко можно решит библиотекой от самих же создателей redux redux-toolkit, которая под капотом как раз использует Immer, позволяя в редьюсерах работать как-бы в mutable way
Вот пример
const counterSlice = createSlice({
name: 'counter',
initialState: 0,
reducers: {
increment: state => state + 1,
decrement: state => state - 1
}
})
const store = configureStore({
reducer: counterSlice.reducer
})
document.getElementById('increment').addEventListener('click', () => {
store.dispatch(counterSlice.actions.increment())
})
Всё, разобрался. Думал что executor промиса отработать должен после вызова than/catch (подобно потокам rxjs), но оказалось что отрабатывает он сразу при создании промиса.
ИМХО меняете шило на мыло как по мне. Как минимум, вы могли бы иметь index.js файл для компонентов, в котором бы экспортился законнекченный к стору компонент, и соответственно когда вам нужна связь с хранилищем вы юзаете его, когда нет — используете напрямую Component.js. Своим подходом вы создаёте жёсткую связь (что является антипаттерном в программировании в принципе, вспоминаем high cohesion и low coupling) между компонентами.
Ну и плюс в вашем подходе нужно разбираться, у него могут быть свои подводные камни, а с redux уже всё всем понятно и всё известно. Так что как по мне, не стоит изобретать велосипед в очередной раз.
А в чём собственно сложность тестирования? Если мы например берём redux, то там всё достаточно просто. Это ж просто чистые функции.
И ещё интересно, где в такой архитектуре хранилище? В бекендах хранилищем обычно выступает БД. Вам же всяко информацию где-то надо хранить (надеюсь не предполагается этого делать в моделях). И тут приходим к тому что всё равно нужно что-то типа redux (единый источник правды), иначе будут проблемы с неконсистеными состояниями и всем тем что react сообщество успешно побороло 4+ лет назад
Мне кажется, даже размер команды, и размер приложения это ещё не повод выбирать именно чистую архитектуру. Как вариант, приложение можно разбить на несколько разных модулей (lerna/monorepo), контролируя тем самым их размер. И это будет тоже довольно просто поддерживать и расширять.
Ну не знаю…
Пилю средне-большие проекты на react-redux и никаких архитектурных проблем не встречал. Как по мне это overengeenring, т.к. в основном все правила бизнес логики должны быть реализованы на бекенде. А ради валидации формы пилить такой огород классов и связей…
ИМХО на бекенд/native приложения это ложится гораздо лучше.
Я конечно не эксперт, но некоторые моменты меня смутили. А именно:
Как-то странно что в generic библиотеке логирования описаны
peerDependencies
ангуляраСсылка на репозиторий наверное должна вести в актуальный репозиторий, а не на конкретную ревизию
Неконсистентное форматирование кода. Посмотрите в сторону prettier.
Потенциальный crash приложения, если вдруг будет циклический JavaScript объект.
console.log
в такой ситуации отработает корректно.Потенциальные утечки памяти. Вы храните все логгеры в Map, но я не вижу как можно удалить один конкретный логгер. Есть только
clearAllLoggers
, который не факт что вызовется. Попробуйте посмотреть в сторону WeakMap.Метод
setLogLevelsByAllLoggers
иsetLogLevel
делают почти одно и тоже (дублирование кода). Почему просто не сделать параметрsearchPath
вsetLogLevel
опциональным и устанавливать значения во всех логгерах если он не передан?Вместо метода
containsPath
можно было бы обойтись регулярным выражением.Зачем
defaultPathPostfix
в LoggerFactorypublic
?Зачем LoggerFactory это класс если имеет только static методы? Такого же эффекта можно добиться если переписать класс на функции и экспортировать только публичные.
Если уж так хочется в ООП, то его нужно реализовывать правильно. А как правильно, можно посмотреть тут на примере. В данный момент ощущение что LoggerFactory это недобилдер-недофабрика ещё и синглтон.
Множественные опечатки
defaultLogLeevl
recetDefaults
mathc to searchPath
unic name
Если Вам вдруг нужен удобный функциональный логгер для браузера, посмотрите в сторону consola. Как будто бы он удовлетворяет всем Вашим потребностям.
В redux проблему бойлерплейта (а как я понял с ним автор и борется) легко можно решит библиотекой от самих же создателей redux redux-toolkit, которая под капотом как раз использует Immer, позволяя в редьюсерах работать как-бы в mutable way
Вот пример
Ссылочка на документацию
Всё, разобрался. Думал что executor промиса отработать должен после вызова than/catch (подобно потокам rxjs), но оказалось что отрабатывает он сразу при создании промиса.
Почему во втором примере вывод
а не
Почему вызов промиса
a.then(...)
обработался синхронно?Вот прям как раз недавно была статья про то, что context + useReducer не лучшая идея для управления состоянием.
Объясните пожалуйста почему в примере
выводится 1 а не 2? Почему функция
b
принимает контекстwindow
а не контекст текущего вызова функцииb.a()
?ИМХО меняете шило на мыло как по мне. Как минимум, вы могли бы иметь index.js файл для компонентов, в котором бы экспортился законнекченный к стору компонент, и соответственно когда вам нужна связь с хранилищем вы юзаете его, когда нет — используете напрямую Component.js. Своим подходом вы создаёте жёсткую связь (что является антипаттерном в программировании в принципе, вспоминаем high cohesion и low coupling) между компонентами.
Ну и плюс в вашем подходе нужно разбираться, у него могут быть свои подводные камни, а с redux уже всё всем понятно и всё известно. Так что как по мне, не стоит изобретать велосипед в очередной раз.
А в чём собственно сложность тестирования? Если мы например берём redux, то там всё достаточно просто. Это ж просто чистые функции.
И ещё интересно, где в такой архитектуре хранилище? В бекендах хранилищем обычно выступает БД. Вам же всяко информацию где-то надо хранить (надеюсь не предполагается этого делать в моделях). И тут приходим к тому что всё равно нужно что-то типа redux (единый источник правды), иначе будут проблемы с неконсистеными состояниями и всем тем что react сообщество успешно побороло 4+ лет назад
Мне кажется, даже размер команды, и размер приложения это ещё не повод выбирать именно чистую архитектуру. Как вариант, приложение можно разбить на несколько разных модулей (lerna/monorepo), контролируя тем самым их размер. И это будет тоже довольно просто поддерживать и расширять.
Ну не знаю…
Пилю средне-большие проекты на react-redux и никаких архитектурных проблем не встречал. Как по мне это overengeenring, т.к. в основном все правила бизнес логики должны быть реализованы на бекенде. А ради валидации формы пилить такой огород классов и связей…
ИМХО на бекенд/native приложения это ложится гораздо лучше.
Сохраняется контекст если передать метод по ссылке.
Обычное такое используют в обработчиках событий. Конкретно тут, да, это можно считать лишним.