Comments 72
P.S. увидел, что перевод, исправил.
Даже, если из всей статьи оставить только пункт 2, то эта статья не потеряет ценности. Потому что это просто неописуемо круто, когда можно дебажить удаленный проект так просто. В браузере.
Вы серьезно? Как вообще можно разрабатывать под какую-нибудь платформу, не зная документации? Я считаю, что это статься не достойна главной, так как тут ничего нового для среднего разработчика Node.js не найти
Документация Node.js очень маленькая и простая, потому что Node.js по сути обретка над различными библиотеками, в отличии от PHP, Ruby, Python и других языков, где стандартные библиотеки богаты различными интересными штуками, о которых в документации если и есть что-то, то это нужно хорошенько поискать
потому что, платформа отличная, но низкий порог вхождения все испортил.
Вы убедили меня в том что некоторые — все таки ремесленники. Открыть мануал, повторить что написано, скомпоновать по своему — это обычный «кодинг», и даже в этом случае нет гарантий что вы давным давно прочитав описание неких методов — запомнили это и теперь используете. Вероятнее — вы помните что читали, и не читаете повторно, но забыли о чем и не используете.
Ведь согласитесь вы не перечитываете мануалы при апдейтах? А ведь алгоритм встроенных методом мог изменится, и тот что вы не использовали ранее из-за тормозов, стал оптимальнее текущих ваших приемов.
Буквально вчера читал даже не описание, а подсказку к настройке плагина Atlassian, где написано «в данной версии умеем присваивать только цифры и текст». Они не указали «списки выбора», и если бы я поверил — то не стал бы использовать для присвоения enumeration, которые внутри все таки цифры, но пойди их еще найди.
process.on('uncaughtException', console.error);
Не делайте так. Тем более для «предотвращения остановок сервера».
Ссылка на доку: https://nodejs.org/dist/latest-v7.x/docs/api/process.html#process_event_uncaughtexception
конечно, нахожусь в здравом уме, поэтому пользуюсь PM2
PM2 в вакууме тоже не является гарантией того, что всё это не упадёт. В продакшне надо использовать системные менеджеры для запуска всего, независимо от наличия PM2 (который может использоваться для других целей).
у объектов EventEmitter имеется и метод code
code
? Это ошибка?
В продакшне надо использовать системные менеджеры для запуска всего
Можно подробнее? Что это за менеджеры?
На совеременных Linux-дистрибутивах это systemd, см. http://0pointer.de/blog/projects/watchdog.html.
На более старой убунте и ещё нескольких дистрибутивах это upstart.
На чём-то ещё — другие системные средства, которые гарантируют работу сервисов.
Полагаться на то, что запущенный без какого-либо надсмотрщика pm2/forever/чтоещё сам не упадёт — довольно безумно в продакшне.
PM2 в последних релизах сделал интеграцию с systemd/upstart, так что теперь чуточку удобнее.
Ага, спасибо, я взгляну на это чуть позже, интересно, как это реализовано и поддерживают ли они watchdog.
Когда я последний раз смотрел, у pm2 была целая куча жалоб в issues где пользователи запускали его в отрыве от всего а потом ловили внезапный oom, который убивал pm2 и очень удивлялись.
По-хорошему, таким утилитам нужна не только опциональная поддержка интеграции, но ещё и активное напоминание о том, что её всё-таки стоит включить (если его там ещё нет).
Сейчас у меня довольно плохо всё со временем, но я себе записал в список дел посмотреть на то, как именно в pm2 организовали интеграцию с systemd/upstart и прокомментировать, если я замечу в этом косяки.
Если вы запускается скрипт из /~ или C:\ то все пути fs.readFile('./...') будут идти от этой директории, в то время как в require путь берётся от файла, где он вызван.
В смысле — пропадает? Покажите конкретную последовательность команд, пожалуйста.
Я помню как один раз у нас в документации <<<<<<< HEAD
нашёлся, вот это было неожиданно.
Но с тех пор добавилась проверка на них на этапе линта на CI.
NODE_PATH=. node app.js
и все модули ищутся относительно текущей директории. Соответсвенно в продакшне используется pm2 и для него создается список процессов processes.json, где также задается эта переменная окружения.
Не совсем понял, как это относится к моему комментарию выше, но ладно.
Так же я не понял, зачем вам нужен NODE_PATH, и почему вы не кладёте зависимости в папку приложения.
Лучше всего NODE_PATH не пользоваться вообще и забыть про него, он оставлен для совместимости.
Здравым смыслом подразумевается, что в переменной NODE_PATH хранится корень установленного NodeJS.
Здравым смыслом подразумевается, что в переменной NODE_PATH хранится корень установленного NodeJS.
Если честно, я не понял мысли. Можете показать на примере путей, что вы имеете ввиду?
К слову о «тру-практиках» — использование NODE_PATH
вообще не рекомендовано.
В любом случае, вопрос развертывания к сисадмину. Разрабатывать на локальной машине проекты можно так, как удобно разработчику.
Он даже создается таким образом, чтобы показать что тут память вылеляется, а не типичный объект создается
const buf1 = Buffer.alloc(10);
И нужно с понимать что вы делаете
Для всего остального все работает как и ожидается
let arr = [0, 1, 2, 3]
let arr2 = arr.slice(1)
// arr2 новый массив, изменяя который первый не будет изменен
let str = "abcdef"
let str2 = str.slice(1, -1)
// str2 новая строка, независимая от первой
//Если вам нужна просто копия всего, можно сделать
let copyArr = arr.slice()
Хотел бы спросить.
Может уже придумали решение чтобы не делать require('../../../../moduleA') внутри moduleB?
Ограничение «только относительные пути» ухудшает читабельность и рефакторинг.
Насчет упаковки включаемого кода в node_modules в курсе — не выход (неудобно).
Я что-то такое делал, сейчас поищу.
Вообще require поддерживает абсолютные пути, но относительно корня текущего диска.
Может быть стоит где-нить в main.js кроссплатформенно вычислить абсолютный путь до корня проекта.
Записать его в глоб. переменную (одна переменная — терпимо) и дальше везде тупо собирать полный путь…
Прокатит даже для клиентского js-кода где за require-кухню отвечает webpack.
Только придется поддержку __dirname ему в конфиге включить явно.
global.path = require('path');
global.root = __dirname;
инклуды в других файлах, было:
var module = require('../../../../moduleA');
стало:
var module = require(path.resolve(root, 'controller/net/moduleA'));
проверил на Win\Mac — нормально
Но допустим, этот moduleA.js включен много где в файлах расположенных разных по уровню каталогах.
Каждый раз приходится «спускаться» до корня проекта вручную, потом «подниматься» до модуля.
Либо задумываться о замене CommonJS-вского require на что-то более умное.
Либо делать костыли — заранее в main.js подключить всё и сделать глобальным (с неймспейсами если надо):
global.ModuleA = require('./moduleA.js')
var Module = module.constructor;
var m = new Module('');
handle(m.paths); //Внесли нужные правки
module.exports = m;
Использовать потом — m.require
Или можно покопаться в process.mainModule.paths, а потом использовать process.mainModule.require
UPD,
Да, почему бы не положить где-то в более удобном месте
module.exports = require('../../../../moduleA')?
2) Вариант если нет фреймворка или иерархии компонент в сочетании например с Redux
Впрочем, пока для себя определился.
можно начать собирать webpack-ом, там резолвинг настраивается. А можно начать использовать typescript — module resolution. В общем инстументы есть.
Модуль net вдвое быстрее модуля http
Спорное утверждение. Это как сравнивать теплое с мягким. Я бы утверждал что скорость их работы при заданных условиях работы приблизительно одинаковая.
В результате http.Server смог обработать примерно 3400 запросов в секунду, а net.Server – примерно 5500. К тому же, net.Server проще устроен.
Ваша статистическое утверждение никак не может быть объективным. Во-первых, вы пренебрегаете keep-alive-соединениями. Во-вторых, количеством одновременных соединений.
Конечно же, используя net можно написать реализацию любого протокола. Но, в большинстве случаев отладка своего протокола может превратиться в ад. Для большинства случаев подходит простенький и экстремально быстрый пакет ws, основанный на WebSocket. Удобно это прежде всего тем, что двухсторонний обмен данными происходит сообщениями из js-объектов. Это позволяет не заморочиваться с проектированием протокола обмена, можно добавлять и удалять параметры в сообщения и их обработку в любой момент разработки, что повысит гибкость работы с версиями API. Также, если не ошибаюсь, через объект этого сообщения можно передавать функции, содержащие произвольный js-код. Ну, и нельзя отметать возможность отлаживать взаимодействие с помощью браузера.
Внимательное изучение API-документации используемых средств разработки происходит далеко не в самом начале карьеры.
Следующий этап развития разработчика (назовем его, например, гуру разработчик) происходит, когда разработчик изучает используемые средства по исходным кодам этих средств.
Тут я серьезно! Когда все API-документации средств изучены, тяга к познаниям обязательно заставит изучать используемые в разработке средства по исходным кодам.
Внимательное изучение API-документации используемых средств разработки происходит далеко не в самом начале карьеры.
А я изучал на первом курсе справочную и методологическую часть API платформ по книгам, начиная со второго-третьего — с официальных документаций API, с третьего-четвертого — с исходных кодов.
С тех пор придерживаюсь этого стиля.
При изучении новых платформ/новых версий давно знаю, какие ключевые точки посмотреть для изучения — для быстрого входа в разработку, далее смотрю документацию итеративно, +ресурсы типа забра помогают.
И надо сказать, что зная точно, какую часть API для каких задач и как именно использовать, тяжело смотреть на код коллег, «кодящих» по подсказкам IntelliSense — такой подход часто приводит к использованию методов не так, как они предназначены для решения задачи (отличия могут быть в параметрах, обработке исключений), к использованию неподходящего метода, к использованию методов, ставших Obsolete N версий назад, или и вообще к своему велосипедному коду, в то время, когда в платформе с версии 1.0 есть стандартные методы для решения задачи.
А бывает и такое, что пропустив изучение платформы по книгам, документации (про исходники не говорю), в продукте много лет может не использоваться вообще не только тот или иной стандартный метод или класс, а целая технология.
В свое время столкнулся с реальным случаем, когда в продукте, развивавшимся 10 лет, разработчики сталкивались с падениями OutOfMemory exception, т.к. в своем велосипедном ORM кодировали запросах BLOB'ы в виде шестнадцатеричном текстовом виде.
Т.е., за 10 лет никто не открыл ни одной книжки, ни официальной справки (офлайновая в IDE, веб на официальном сайте), и не узнал, что параметризованные SQL запросы существовали в платформе с версии 1.0
(тем более не говорю про возможность потокового чтения-записи блоб'ов в БД).
NodeJS. как и многие другие инструментальные средства по Unix-традициям запускается тремя способами:
- путь к файлу скрипта предается параметром
node script.js
; - скрипт передается процессу node через стандартный поток ввода
cat script.js | node
; - или просто вручную запускаем node без параметров
node
.
Ручной запуск ноды без параметров инициализирует readline-интерфейс. Здесь нода будет выполнять скрипт по-строчно с теми же возможностями, как и в консоли браузера.
Главный файл проекта можно подключить параметром запуска
--require
или функцией require()
или даже import
. А после подключения главного модуля, сервер или что там подключали работает, а во время выполнения этого процесса можно его отлаживать, например, проверяя значения переменных или вручную вызывая различные функции, влияющие на состояние процесса.Возможно вы заметили, что в примерах я использую для строк одинарные кавычки.
Вообще-то «backticks» — это обратные кавычки. Одинарные — это «single quotes» ('
)
Ничего не имею против es6-шаблонов, определенных таким образом. Но использовать их вместо статических строк не рационально. Автору советую лучше протестировать производительность шаблонов и статических строк. Интересно, как помогает автору pm2 в отладке?! Автор, какие средства используете для борьбы с утечками?
<зануда mode>
Backticks — это все-таки апострофы, а не одинарные кавычки.
</зануда mode>
Странно сравнивать производительность net и http, учитывая, что второй должен не просто данные собрать, но и http распарсить.
Если я ничего не путают http использует net внутри для собственно работы с сетью.
И я так и не понял, почему 5500/3400 — это "вдвое быстрее".
let a = 10;
let b = 15;
console.log(`Сумма: ${a+b}`); // Выведет Сумма: 25
// Внутрь ${} можно подставлять любое js-выражение
var str = `Логарифм: ${Math.log(10)}`);
//str == 'Логарифм: 2.302585092994046'
Очень удобный способ форматирования строк, на мой взгляд.
__dirname не имеет отношение к cwd, __dirname — это путь к папке с файлом, в котором она написана.
scripts/test.js
console.log(__dirname)
$ node scripts/test.js
/path/to/your/project/scripts
Такие ошибки запутывают новичков и приучают работать с абсолютными путями)))))
require(`net`).isIP(`cats`)
Возможно вы заметили, что в примерах я использую для строк одинарные кавычки.
Мы заметили, что вы используете не одинарные кавычки, а обратные апострофы.
Было бы оправдано, если бы вы использовали шаблоны:
require('net').isIP(`${ myPet }s`)
но вы ведь нет, так что зачем?
19 неожиданных находок в документации Node.js