На месте интервьювера я бы спросил что такое 37. Ожидал бы, что человек после этого вопроса скажет, что magic numbers это плохо и вынесет это в константу. А заодно даст внятный комментарий. И тут самое интересное — почему 37? Может лучше 16.7 (1/60 секунды).
P.S. забыл дописать — нет обработки ошибок асинхронного запроса (хотя бы console.error)
Вот тут грубая ошибка. Либо у вас это реактивный state, и тогда вы можете вернуть это из хука наружу. Либо это не реактивный стейт, и тогда render vDom древа ни в коем случае не должен от таких значений зависеть. Т.е. не используйте useRef для рективных вещей. Для этого есть useState и useReducer (ну и всякие mobX и прочие внешние сторы).
Возможно у вас сейчас этот баг никак не проявляется ввиду того, что помимо currentPage и allPages обновляется что-нибудь ещё и соответственно необходимый render всё равно происходит. Но на такие вещи точно нельзя полагаться. Это скорее из области "случайно работает".
Если вы используете useRef вместо useState только чтобы избежать лишних ререндеров — useReducer или unstable_... вам в помощь. А сейчас вы ходите по минному полю.
Обратите внимание на useReducer. Проще хранить всё в одном объекте (все эти page и пр. штуки, которые вы почему-то храните в ref-ах), и менять разом.
Ещё стоит пресекать race-condition. Если проект большой и важный, то без этого вообще никак. Правда это само по себе — тема для целой статьи.
Обработку ошибок делать более централизовано. console.error-ы раскиданные по коду это плохо. И вообще хорошо бы уметь возвращать её (ошибку) из хука.
Кеш лучше делать опциональным (или вообще не делать), т.к. это далеко не всегда желаемое поведение.
Ещё я бы выпилил всё что касается URL из этого хука, т.к. вы таким образом нарушаете принцип ограниченной ответственности. Такие вещи должны быть извне.
Не увидел никакой мемоизации. Это странно для хука базового назначения.
Мы используем похожую, но кратно более сложную схему.
P.S. ещё можно посмотреть в сторону отказа от page, в пользу курсоров.
Good. А если не убирать пустые пробелы и перенос строки перед <div class тоже работает?
Есть как подсветка локальных переменных
Тут как раз всё просто — это же интерполяция. Так любой редактор сможет. А вот воспринять автоматически это как HTML без бубнов, возможно, только Idea.
Ожидал от статьи какой-то конкретики. Ведь все итак знают, что можно вынести часть логики в worker-ы, но потом встаёт проблема коммуникации между основным thread-ом и worker-ом. И вот тут дилемма — а как организовать это всё так, чтобы потери на обмен не превышали выгоды от выноса логики в worker-ы. Вот это было бы интересно почитать. А в статье имеем много-много воды и красивых диаграмм. Ух.
Не стоит. Он в своей нелюбви к Typescript давно уже перестал быть объективным. Его категоричность давно перешла грань здравого смысла. Особенно когда в одном видео он топит за то что типы не нужны, пишите на JS + тесты, а в другом давайте писать на sound re-script, ибо "всё или ничего". Либо язык без типов, либо сразу sound. Климов — просто TS хейтер. TS есть за что ругать, но Климов воюет не туда.
Лично я с ним только в одном согласен — писать на TS хорошо могут немногие. Язык богат на возможности, но задействовать их с пользой бывает весьма нетривиально. Уровень входа в язык высокий.
Множество стандартных библиотек тоже не типизировано
Если брать не количественно, а по популярности\частотности их использования, то почти всё типизировано. Это как сказать что большая часть интернета до сих пор на HTTP, что отчасти правда, если считать число сайтов. Но если учесть долю на рынке, то всё наоборот (посмотрите среди открытых вкладок сколько из них не HTTPS). Такая же ситуация и с типами.
Проблема типов "стандартных" библиотек не в том, что типов нет, а в том что часто они посредственного качества. Скажем не все методы описаны, не все объекты полны, местами стоят any и т.д..
можно будет перестать использовать any
Его и сейчас нет необходимости использовать. В тех редких случаях когда типов нет вообще, они пишутся руками в d.ts файлах в кратчайшие сроки, т.к. не требуется покрывать всю библиотеку. Достаточно только того API что вы используете в своём проекте.
Понятно, спс. Да, у нас очень много алгебры типов, поэтому ломается в очень неочевидных местах. Нужен весь граф связей, которых никаким find usages не получить. Да и пробегать всё это вручную то ещё удовольствие.
Не сказал бы. Да, за счёт запаздывания ошибки бывают нерелевантными, и это бесит. Но вот выяснить, что у тебя полпроекта развалилось на pre-commit очень обидно. Хочется своевременной реакции. И желательно быстрой. Я бы так работать не смог, т.к. рефакторинг спутник моей жизни. Он как ремонт. Никогда не заканчивается.
при неблокирующем — медленнее, чем бабель с вырезанием ts-типов
Не совсем понял мысль. При неблокирующем как раз и получается что одновременно babel+плагин и ts-fork. Получается быстрый инкрементальный билд, и медленный догоняющий TS.
У нас где-то 1.5-2 секунды на JS часть, и 5-10 секунд на TS часть (она в отдельном потоке и не блокирует билд). +- 80-90K LOC. Вспоминая как на моей машине Scala проект по 20-30 секунд на инкрементальный билд тратил, а на полный больше 2 минут… соглашусь с вами. Во фронте это ещё по божески.
Babel написан быть гибким, а не быстрым. Неспроста esbuild уделывает его на два десятичных порядка по скорости. Typescript тоже написан быть гибким и удобным. А если учесть, что Babel и Typescript и Eslint имеют свои собственные AST (т.е. все делают одно и то же с нуля, без коллаборации), то там есть что оптимизировать. А если подружить webpack и редактор...
Везёт вам. А мы обмазались тайпскриптами, линтерами и бабель плагинами. В итоге мало того что даже инкрементальная сборка подтормаживает, так ещё и приходится пару раз в день\два её убивать и перезапускать. Либо она сама от Out of memory дохнет. Особенно у меня умиляет, что из-за разных AST у меня одновременно работает минимум 4 instance-а от typescript-а: vscode ts, vscode eslint ts, webpack ts, webpack eslint ts. Ух. Но, имхо, оно того стоит. Но во мне ещё теплится надежда, что когда-нибудь это всё перестанет так сильно глючить и лагать.
Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my Patreon. Not sure how much of my modules you're using? Try feross/thanks!
var toString = {}.toString;
module.exports = Array.isArray || function (arr) {
return toString.call(arr) === '[object Array]';
};
А он хорош! :-) И даже сюда автор затащил зависимость от какого-то tape. Благо хоть dev-зависимость.
Это также решается продакшен сборкой и использованием babel-plugin-htm
Что и требовалось доказать. Убегали от babel, вернулись к babel. Осталась разве что возможность запустить проект в dev-режиме без сборки. Неплохо, но не сказать, чтобы уж сильно нужно.
Согласен. Всякий раз подключая такую крошечную библиотеку я думаю, что никто не мешает все эти left-pad сгруппировать в какой-нибудь один пакет где будет сразу несколько десятков типовых утилит для работе со строками. Никто ведь не мешает сделать много endpoint-ов, как например сделано в lodash.
Вот пример такого left-pad: @mapbox/geo-viewport. 73 строки кода. Неужели их нельзя было засунуть в сам mapbox :)
java особых проблем с пакетами и сборкой не наблюдается уже лет
А там случаем нет "бинарной совместимости" с тем, что уже не получается собрать? Мне кажется это сильная сторона (ещё одна) статически типизированных языков.
Ну и, как мне кажется, вне web разработки, мало кого интересует вес получившегося бинарника. Нередкое явление когда какое-нибудь, скажем, десктопное приложение просит зависимостей под 50 MiB. Во фронте за такое бьют ногами, ибо каждому пользователю это всё грузить… Отсюда и перегибы с DRY в виде left-pad и подобных штук.
А ещё безалаберность приводит к тому, что пакет где полезной нагрузки 15 строк тащит за собой в node_modules кучу тестов, криво указанные dev-зависимости, всякие ридми и документацию. В итоге node_modules под 400 MiB, а итоговый JS-bundle со всем этим добром меньше MiB до gzip.
ES модули… в браузере… Поэтому их можно и нужно использовать в продакшене.
Зачем и кому нужно? Одна из проблем — каждый последующий уровень вложенности это очередной последовательный запрос. Условно с latency в 1000ms и глубиной в 10, ваше приложение будет грузиться 10 секунд (вместо одной). Никакой HTTPS2 не спасёт. В первых имплементациях импортов доходило до того, что lodash грузился 21 секунду.
В лучшем случае вы сможете как-то заранее уведомить браузер о полном древе всех задействованных ресурсов… коих в большом проекте может быть много тысяч. Не помню завезли это уже или ещё нет. Так или иначе вам снова потребуется автоматизация. А заодно вы лишаетесь dead code elimination и прочих оптимизаций.
Импорты и экспорты удобны для разработки. Но come on, для чего они вам в production-е? По крайней мере в текущем виде.
Чтобы решить эту проблему сейчас разрабатывается сложная спецификация нового формата файлов — bundle-ов. Недавно что-то бегло читал про них. Но они ещё дальше от ваших идей. Это снова нужно натравливать софт на кодовую базу.
Следующий инструмент, который может помочь нам, это HTM. Удобная библиотека, с помощью которой можно писать JSX-like-синтаксис с помощью tagged templates, который будет работать прямо в браузере.
Который парсит ваши шаблоны прямо в браузере. Для небольших проектов ещё сгодится. Но прошу не тащите подобное в крупные. Ahead of time — наше всё.
писать все типы в JSDocs.
Как человек который длительное время страдал такой фигнёй (вынужденно, не было возможности моментально перевести большую кодовую базу на TS), я торжественно заявляю — это адов изврат. Не делайте так без острой необходимости.
На мой взгляд, такой подход хорошо подойдет как для быстрой проверки гипотез, так и для приложений среднего размера
А ещё лучше для проверки гипотез и приложений среднего размера подойдёт единожды сделанный простой шаблон. Он же вам поможет и тестовые задания в разные компании проходить.
добавить свой сайт в список сайтов, которые всегда работают по httpS, а для этого понадобиться дописать preload в заголовок; Strict-Transport-Security
Собственно это меня и удивило. Всего лишь добавить заголовок и ты в глобальном HSTS? Да ладно?!
Не я понимаю, что Chrome может шпионить за пользователями и собирать свою статистику по этому заголовку, и, по достижению некоего лимита, автоматически принудительно заносить домен в список HSTS… Но звучит диковато.
По ссылке выше указано что нужно маниуально отправлять заявку в спортлото.
На месте интервьювера я бы спросил что такое
37
. Ожидал бы, что человек после этого вопроса скажет, что magic numbers это плохо и вынесет это в константу. А заодно даст внятный комментарий. И тут самое интересное — почему 37? Может лучше 16.7 (1/60 секунды).P.S. забыл дописать — нет обработки ошибок асинхронного запроса (хотя бы console.error)
Вот тут грубая ошибка. Либо у вас это реактивный state, и тогда вы можете вернуть это из хука наружу. Либо это не реактивный стейт, и тогда render vDom древа ни в коем случае не должен от таких значений зависеть. Т.е. не используйте
useRef
для рективных вещей. Для этого естьuseState
иuseReducer
(ну и всякиеmobX
и прочие внешние сторы).Возможно у вас сейчас этот баг никак не проявляется ввиду того, что помимо
currentPage
иallPages
обновляется что-нибудь ещё и соответственно необходимыйrender
всё равно происходит. Но на такие вещи точно нельзя полагаться. Это скорее из области "случайно работает".Если вы используете
useRef
вместоuseState
только чтобы избежать лишних ререндеров —useReducer
илиunstable_...
вам в помощь. А сейчас вы ходите по минному полю.Пара советов:
useReducer
. Проще хранить всё в одном объекте (все этиpage
и пр. штуки, которые вы почему-то храните в ref-ах), и менять разом.console.error
-ы раскиданные по коду это плохо. И вообще хорошо бы уметь возвращать её (ошибку) из хука.Мы используем похожую, но кратно более сложную схему.
P.S. ещё можно посмотреть в сторону отказа от
page
, в пользу курсоров.Good. А если не убирать пустые пробелы и перенос строки перед
<div class
тоже работает?Тут как раз всё просто — это же интерполяция. Так любой редактор сможет. А вот воспринять автоматически это как HTML без бубнов, возможно, только Idea.
А какие, если не секрет? WebStorm?
Ожидал от статьи какой-то конкретики. Ведь все итак знают, что можно вынести часть логики в worker-ы, но потом встаёт проблема коммуникации между основным thread-ом и worker-ом. И вот тут дилемма — а как организовать это всё так, чтобы потери на обмен не превышали выгоды от выноса логики в worker-ы. Вот это было бы интересно почитать. А в статье имеем много-много воды и красивых диаграмм. Ух.
Не стоит. Он в своей нелюбви к Typescript давно уже перестал быть объективным. Его категоричность давно перешла грань здравого смысла. Особенно когда в одном видео он топит за то что типы не нужны, пишите на JS + тесты, а в другом давайте писать на sound re-script, ибо "всё или ничего". Либо язык без типов, либо сразу sound. Климов — просто TS хейтер. TS есть за что ругать, но Климов воюет не туда.
Лично я с ним только в одном согласен — писать на TS хорошо могут немногие. Язык богат на возможности, но задействовать их с пользой бывает весьма нетривиально. Уровень входа в язык высокий.
Если брать не количественно, а по популярности\частотности их использования, то почти всё типизировано. Это как сказать что большая часть интернета до сих пор на HTTP, что отчасти правда, если считать число сайтов. Но если учесть долю на рынке, то всё наоборот (посмотрите среди открытых вкладок сколько из них не HTTPS). Такая же ситуация и с типами.
Проблема типов "стандартных" библиотек не в том, что типов нет, а в том что часто они посредственного качества. Скажем не все методы описаны, не все объекты полны, местами стоят any и т.д..
Его и сейчас нет необходимости использовать. В тех редких случаях когда типов нет вообще, они пишутся руками в
d.ts
файлах в кратчайшие сроки, т.к. не требуется покрывать всю библиотеку. Достаточно только того API что вы используете в своём проекте.Понятно, спс. Да, у нас очень много алгебры типов, поэтому ломается в очень неочевидных местах. Нужен весь граф связей, которых никаким find usages не получить. Да и пробегать всё это вручную то ещё удовольствие.
Не сказал бы. Да, за счёт запаздывания ошибки бывают нерелевантными, и это бесит. Но вот выяснить, что у тебя полпроекта развалилось на pre-commit очень обидно. Хочется своевременной реакции. И желательно быстрой. Я бы так работать не смог, т.к. рефакторинг спутник моей жизни. Он как ремонт. Никогда не заканчивается.
Не совсем понял мысль. При неблокирующем как раз и получается что одновременно babel+плагин и ts-fork. Получается быстрый инкрементальный билд, и медленный догоняющий TS.
У вас какая-то другая схема?
У нас где-то 1.5-2 секунды на JS часть, и 5-10 секунд на TS часть (она в отдельном потоке и не блокирует билд). +- 80-90K LOC. Вспоминая как на моей машине Scala проект по 20-30 секунд на инкрементальный билд тратил, а на полный больше 2 минут… соглашусь с вами. Во фронте это ещё по божески.
Babel написан быть гибким, а не быстрым. Неспроста esbuild уделывает его на два десятичных порядка по скорости. Typescript тоже написан быть гибким и удобным. А если учесть, что Babel и Typescript и Eslint имеют свои собственные AST (т.е. все делают одно и то же с нуля, без коллаборации), то там есть что оптимизировать. А если подружить webpack и редактор...
В общем всё возможно.
Везёт вам. А мы обмазались тайпскриптами, линтерами и бабель плагинами. В итоге мало того что даже инкрементальная сборка подтормаживает, так ещё и приходится пару раз в день\два её убивать и перезапускать. Либо она сама от Out of memory дохнет. Особенно у меня умиляет, что из-за разных AST у меня одновременно работает минимум 4 instance-а от typescript-а: vscode ts, vscode eslint ts, webpack ts, webpack eslint ts. Ух. Но, имхо, оно того стоит. Но во мне ещё теплится надежда, что когда-нибудь это всё перестанет так сильно глючить и лагать.
А он хорош! :-) И даже сюда автор затащил зависимость от какого-то
tape
. Благо хоть dev-зависимость.Что и требовалось доказать. Убегали от babel, вернулись к babel. Осталась разве что возможность запустить проект в dev-режиме без сборки. Неплохо, но не сказать, чтобы уж сильно нужно.
Согласен. Всякий раз подключая такую крошечную библиотеку я думаю, что никто не мешает все эти left-pad сгруппировать в какой-нибудь один пакет где будет сразу несколько десятков типовых утилит для работе со строками. Никто ведь не мешает сделать много endpoint-ов, как например сделано в lodash.
Вот пример такого left-pad:
@mapbox/geo-viewport
. 73 строки кода. Неужели их нельзя было засунуть в сам mapbox :)Кажется вот оно
Любые мои попытки использовать
npm link
оборачивались вселенскими страданиями. Избегаю symlink-ов в nodejs всеми силами.А там случаем нет "бинарной совместимости" с тем, что уже не получается собрать? Мне кажется это сильная сторона (ещё одна) статически типизированных языков.
Ну и, как мне кажется, вне web разработки, мало кого интересует вес получившегося бинарника. Нередкое явление когда какое-нибудь, скажем, десктопное приложение просит зависимостей под 50 MiB. Во фронте за такое бьют ногами, ибо каждому пользователю это всё грузить… Отсюда и перегибы с DRY в виде left-pad и подобных штук.
А ещё безалаберность приводит к тому, что пакет где полезной нагрузки 15 строк тащит за собой в node_modules кучу тестов, криво указанные dev-зависимости, всякие ридми и документацию. В итоге node_modules под 400 MiB, а итоговый JS-bundle со всем этим добром меньше MiB до gzip.
Я к тому что везде есть свои нюансы.
Зачем и кому нужно? Одна из проблем — каждый последующий уровень вложенности это очередной последовательный запрос. Условно с latency в 1000ms и глубиной в 10, ваше приложение будет грузиться 10 секунд (вместо одной). Никакой HTTPS2 не спасёт. В первых имплементациях импортов доходило до того, что lodash грузился 21 секунду.
В лучшем случае вы сможете как-то заранее уведомить браузер о полном древе всех задействованных ресурсов… коих в большом проекте может быть много тысяч. Не помню завезли это уже или ещё нет. Так или иначе вам снова потребуется автоматизация. А заодно вы лишаетесь dead code elimination и прочих оптимизаций.
Импорты и экспорты удобны для разработки. Но come on, для чего они вам в production-е? По крайней мере в текущем виде.
Чтобы решить эту проблему сейчас разрабатывается сложная спецификация нового формата файлов — bundle-ов. Недавно что-то бегло читал про них. Но они ещё дальше от ваших идей. Это снова нужно натравливать софт на кодовую базу.
Который парсит ваши шаблоны прямо в браузере. Для небольших проектов ещё сгодится. Но прошу не тащите подобное в крупные. Ahead of time — наше всё.
Как человек который длительное время страдал такой фигнёй (вынужденно, не было возможности моментально перевести большую кодовую базу на TS), я торжественно заявляю — это адов изврат. Не делайте так без острой необходимости.
А ещё лучше для проверки гипотез и приложений среднего размера подойдёт единожды сделанный простой шаблон. Он же вам поможет и тестовые задания в разные компании проходить.
Но вы выше пишете:
Собственно это меня и удивило. Всего лишь добавить заголовок и ты в глобальном HSTS? Да ладно?!
Не я понимаю, что Chrome может шпионить за пользователями и собирать свою статистику по этому заголовку, и, по достижению некоего лимита, автоматически принудительно заносить домен в список HSTS… Но звучит диковато.
По ссылке выше указано что нужно маниуально отправлять заявку
в спортлото.