четверг, 25 июля 2013 г.

Grunt

Grunt - javascript task runner. Утилита сборки для джаваскрипта, ака ant для Java.

Разделена на три разных node модуля:
1. grunt - модуль, который нужно устанавливать локально в проект $ npm i grunt. Именно в нем содержится код и логика, которые запускают таски, загружают плагины.
2. grunt-cli - модуль, который устанавливается глобально $ npm i -g grunt, его задача состоит в том, чтобы мы могли выполнить таск в любом месте проекта - он просто подымается по каталогу вверх и находит установленный grunt в папке node_modules и запускает его.
3. grunt-init - модуль, который также нужно установить глобально $ npm i -g grunt-init / Это утилита "строительные леса", которая вынесла таск init гранта в отдельный модуль, и позволяет пользуясь шаблонами, которые размещаются ~/.grunt-init/*(они устанавливаются тоже модулями npm как плагины гранта, но как-то попадают туда), создавать разные заготовки заготовки. Этот модуль планируется быть замененным модулем Yo(http://yeoman.io/).

вторник, 23 июля 2013 г.

git бранчевание

Список поточных бранчей:
git branch
Или с указанием также на каждый бранеч хеша его последнего комита (HEAD)
git branch -v

Создать новый бранч, из HEAD поточного и переключиться на него:
git branch new_branch_name
git checkout new_branch_name

# или вариант в одну строку
git checkout -b new_branch_name 

Создать новый бранч из указанного, а не поточного
git checkout -b new_branch_name existed_local_branch_name
git checkout -b new_branch_name remote_name/existed_remote_branch_name

Удалить безопасно бранч, гит удалит его только в тому случае, если мы сделали мердж в master
git checkout -d existed_branch_name

Если же мы реально осознали, что работа в указанном бранче реально не должна попасть ни в историю, ни в проект, тогда удаляем силой:
git checkout -D existed_branch_name

Переименовать поточный бранч:
git checkout -m new_name_for_curbranch


Все это делается для того, чтобы мы в конце концов сомогли сделать:
$ git checkout master 
$ git merge already_tested_branch
$ git branch -d already_tested_branch

После этого возможны два варинта событий:
- master:HEAD еще не успел продвинуться дальше, поэтому происходит Fast forward мердж, что означает, что у нас будет ровная история master:HEAD - как буд-то разработка так и велась в master, а не в отдельной ветке.
- уже успели накомитить в master:HEAD, поэтому происходит 3-Way Merge, и при необходимости мы будем решать конфликты, после этого история будет бугристая.

Чтобы было видно бранчевание даже в случае когда не успели накомитить в master, мы можем смерджить со следующим ключом:
$ git merge --no-ff already_tested_branch
$ git branch -d already_tested_branch

Чтобы без сюрпризов и у нас точно не было ненужного ветвеления можем указать так(чаще всего это нужно если мы до этого уже делали --no-ff, или ставили ):
$ git merge --ff-only already_tested_branch

Есчли бранч был создан не только локально но и удаленно, то нужно его удалить удаленно тоже.
Нужно помнить, что когда мы пушим  мы неявно делаем следующее:
$ git push remote local_branch:remote_branch

Но если мы уже удалили локальную бранчу, то так мы сделать не можем потому что ее нет, поэтому мы удаляем удаленную таким образом:
$ git push remote_name :remote_branch
или же алиасом:
$ git push remote_name --delete remote_branch


Связать свою локальную бранчу с удаленной:
$ git branch --set-upstream mymaster origin/master

Варинаты undo

  • git checkout foo.txt
    • Undo local changes (like svn revert)
  • git reset HEAD foo.txt
    • Remove from staging area (local copy still modified).

воскресенье, 21 июля 2013 г.

media в каскадных таблицах стилей

@media - это css-правило, которое связывает группу вложенных выражений в блок, ограниченный скобками, применение в поточном устройстве которого определяется условием media query.

суббота, 20 июля 2013 г.

Принципиальная разница POST и GET запросов для NodeJs

На момент срабатывания колбека обратки запроса в http сервера, Get запрос полностью уже обработан, все  его данные полученные, потому что такой запрос приходит без тела, только с заголовками. А вот с Post другая история - когда колбек срабатывает, заголовки уже пришли, а вот боди, еще в пути, и обработать его в колбеке мы можем только подписавшись на событие потока Readable, который у нас представлен, его наследником http.InputMessage обьектом req.

Пример:
function(req, res) {
...........
 var body = '';
 req
    .on('readable', function() {
       body += req.read();

       if(body.length > 1e4) {
         res.statusCode = 413;
         res.end('Your messafe is too big for my little chat');
       }
     })
     .on('end', function() {
       try {
         body = JSON.parse(body);
       }catch(e) {
         res.statusCode = 400;
         res.end('Bad Request');
         return;
       }
         chat.publish(body.message);
         res.end('ok');
       });
}

пятница, 19 июля 2013 г.

Потоки записи в NodeJS

Потоки записи
Все потоки записи должны реализовывать абстрактный класс stream.Writable.
Данный класс имеет следующую событийную модель:


Можно заметить что stream.Writable имеет событие завершения finish, но stream.Readable имел end. Это для того чтобы обеспечить различие дуплексный поток, одновременный вывод и ввод.
Вот пример некоторых наследников данного класса

              stream.Writable
                 ^            ^
                  |             |
fs.WriteStream      http.ServerResponse
     
 Любой наследник гарантирует, что он предоставит событийную модель родителя. Можно заметить, что данная событийная модель не похожа на модель чтения.

Вот пояснение модели:
1. Мы пробуем записать часть наших данных, если данные записались из буфера сразу в место предназначения в ответ мы получаем тру, можем снова пытаться записать следующую часть.
2. Если же у нас данные из буфера не попали сразу в место предназначения, а стали ожидать своей очереди, то райт вернет фолс. Теперь мы подписуемся на событие потока drain(буфер отдренировался), вместо продолжать заполнять буфер, который рискует в таком случае переполниться, что означает для нас, что мы можем попытаться записать следующую часть, в момент когда, буфер слил все в место предназначения.
3. Когда мы заносим последний чанк данных это следует делать местодм end(...)


Дальше приведем пример, файлового сервера, проблемой для которого является считывание за один раз громадного файла в память, или обслуживание довольно большого количества клиентов с медленным соединением, который не очень быстро принимают передаваемые байты. Все эти варианты заставляют нас рисковать переполнить память нашего сервера.
Поэтому нужно поступать хитрее:
function sendFile(filePath, res) {
    var mime = require('mime').lookup(filePath); // npm install mime

    var file = new fs.ReadStream(filePath);
    file.on('readable', write);

    function write() {
        var fileContent = file.read();

        if (fileContent && !res.write(fileContent)) {//если буфер записи сливается на клинет быстро, мы не попадем в if, а будем и дальше записывать по мере прочтения чанков
            file.removeListener('readable', write); // пока не очищать буфер чтения, его ведь некуда сливать, будем захламлять только память

            res.once('drain', function() {
                file.on('readable', write);
                write();
            });
        }
    }
    file.on('end', function(){//дочитали
        res.end();//значит закрываем соединение с клиентом, мы отправили все что должны были
    });
}

Но в ноде уже есть более оптимизированная реализация данного алгоритма, поэтому выше написанный код, можно заменить на более короткий и оптимальный:
function sendFile(filePath, res) {
    var mime = require('mime').lookup(filePath); // npm install mime

    var file = new fs.ReadStream(filePath);
    file.pipe(res);//pipe есть у всех Readable потоков
    file.pipe(process.stdout);//кроме того пайпить мы можем в любое количество потоков одновременно
    file.on('error', function(err) {
       res.statusCode = 500;
       res.end('Server Error');
       console.log(err)  
    });
    //если оставить код без кода написанного ниже в этом блоке,
    //то в моменты когда клиент будет обрывать соединение,
    // не дождавщись всего файла, у нас закроется соединение записи,
    // но файл чтения останется открытым, держа буферы и замыкания в памяти.
    // при нормальном завершении соедиения, ответ сгенерирует finish, который
    // нам приносит класс stream.Writable.
    res.on('close', function(){//срабатывае, когда соединение обрывают
        file.destroy();//обеспечиваем закрытие файла чтения, и всех контекстов из замыкания  
    });

Потоки чтения в NodeJS

Потоки чтения
Все потоки чтения должны реализовывать абстрактный класс stream.Readable.
Данный класс имеет следующую событийную модель:

Вот пример некоторых наследников данного класса

              stream.Readable
                 ^            ^
                  |             |
fs.ReadStream      http.IncomingMessage
       
 Любой наследник гарантирует, что он предоставит событийную модель родителя.

Module fs

Главные моменты:
1) Всегда нужно в методы у которых есть колбеки, вставлять проверку на ошибку, потому что потом мы просто не сможем понять почему у нас что-то не работает. Н-р:
var fs = require('fs');

fs.writeFile('myfile.txt', 'my string for file', function(err){
  if(err) throw err; //без этого будет сложно понять почему у нас что-то не так 
  ...
})

2) Node всегда выводит кроссплатформенные коды ошибок, но мы не всегда можем понять по названию суть проблемы, а документации этого нет. Но за то у нас есть доступ в серце тоды, в исходники libuv, вот ссылка на хед-файл, где описаны все ошибки:
https://github.com/joyent/libuv/blob/master/include/uv.h

четверг, 18 июля 2013 г.

Логирование в nodejs

Модуль debug
Простейшее логирование, позволяет при запуске определять логи с помеченными метками.
Если все выводить console.log, то все у нас смешается и ничего не будет понятно по мере роста приложения. Кроме того, можно определить какие именно логи будут выводиться (с какими именно метками). 
var debug = require('debug')('my_debug');

...
debug(some_obj);//console.log
Чтобы вывести этот лог, мы должны в переменной окружения DEBUG установить метки, которые мы бы хотели вывести
$ DEBUG=my_debug,other_tag node script.js 

Модуль winston
Предназначен для более умудренного логирования.

var log = require('winston');

log.info(...);
log.debug(...);
log.error(...);
По-умолчанию винстон настроен так, чтобы выводить только инфо и еррор.

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

Логирование внутренних модулей node
Для этого нужно указать через запятую в переменной окружения NODE_DEBUG логи из каких внутренних модулей мы хотели бы выдеть.
$ NODE_DEBUG="cluster http module" node myscript.js

Способы отладки nodejs

Консольный встроенный
1) Вставляем в скрпите точки останова ключевым словом debugger;
2) Запускаем ноду в режиме отладки
$ node debug script.js

3) После этого получаем в терминале, вывод первых строк скрипта, подсветку первой строки, и подсказку того, что скрипт запущен в режиме отладки и остановлен на первой строке, ожидается ввода команд для управления отладки:
debug>

4) Можем нажать c - continue, что запустить скрипт в нормальном режиме, пока его выполнение не наткнется на ключевое слово debugger;. Дальше мы можем шагать по сприпту s(step), а также запускать repl, такой же командой, а там выводить переменные что нас интересуют и выполнять любой код, который мы введем.

среда, 17 июля 2013 г.

supervisor.js

Модуль для автоматического перезапуска ноды при креше процесса или, если внутри проекта поменялись файлы.
npm i -g supervisor


Теперь мы можем запустить наше приложение следующим образом:
supervisor myscript.js


Если нужно настроить в WebShtorm, то нужно не забыть обновить приложение для запуска и указать путь к supervisor

Чтобы в скрипт передать параметры(будут доступны через process.argv) мы должны перед именем скрипта поставить два минуса --:
supervisor -- server.js --port=3000

Подводные камни:
1) Новодобаленные файлы текущей версии supervisor не вызовут перезапуск ноды. Только если мы сошлемся на них напрямую в уже знакомых для supervisor файлах.
2) Когда папка node_modules проекта наполниться значительным количеством установленных модулей,  supervisor начнет кушать очень много процессорного времени. Чтобы этого избежать нужно modules устанавливать выше по иерархии директорий, либо указывать параметра игнорирования supervisor на папку node_modules.

вторник, 16 июля 2013 г.

underscore.js осмотр

Это библиотека утилит, которая предлагает набор функций, характерных для функционального программирования.
Создает родную атмосферу дла руби-разработчиков в браузере.
Как агитируют на сайте underscore.js - это галстук для смокинга jQuery и поддтяжек Backbone.js. 

понедельник, 15 июля 2013 г.

ssh тунель

Допустим у нас стоит задача посмотреть что творится в базе MySQL на продакшине, а там на удаленной машине порт 3306 закрыт наружу, только локальный сервер приложения имеет туда доступ. Для этого мы можем создать тунель:
$ ssh -f -N user@database.example.com -L 9906:127.0.0.1:3306
Чтобы сократить, можно воспользоваться алиасом, ~/.ssh/config:
Host tunnel
  HostName database.example.comm
  IdentityFile ~/.ssh/id_rsa_2
  LocalForward 9906 127.0.0.1:3306
  User user
$ ssh -f -N tunnel
Таким образом мы можем подключиться клиентом базы данных на локалке как-будто к localhost:9906, что на самом деле будет тунелем на удаленный database.example.comm, у которого закрыт наружу порт 3306, но у себя локально(127.0.0.1:3306) он же не закрыт, вот мы и пробрасываем с локального пората, по ssh порту на удаленный, а там ssh-сервер перекидывает пакеты на свой указанный локальных порт.

На стороне сервера /etc/ssh/sshd_config
AllowTcpForwarding yes
PermitTunnel yes
/etc/init.d/sshd restart

суббота, 13 июля 2013 г.

Ивентэмитер в NodeJs

events.EventEmitter
Класс который реализует событийную модель в ноде
var EventEmitter = require('events').EventEmitter; 
 
var ee = new EventEmitter;
 
ee.on('myevent', function(data) {});
ee.emit('myevent', {some: "data"});

//маленькая тонкость

ee.emit('error');//это свалит скрипт, если не будет подписки на событие с названием error, такая реализация только для события с этим названием

Есть несколько отличий между событийными моделями ноды и браузеров:

Как работает NodeJs в сравнении с другими серверами

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

четверг, 11 июля 2013 г.

Получение параметров в скрипты. optimist.js commander.js Module

1. Самый простой способ разбираться со стороковым значением process.argv.

cheerio Module

Серверная реализация Query Sizzle. Быстрее чем JSDOM
var cheerio = require('cheerio'),
    $ = cheerio.load('

Hello world

'); $('h2.title').text('Hello there!'); $('h2').addClass('welcome'); $.html(); //=>

Hello there!

вторник, 9 июля 2013 г.

Способы вывода строки по номеру из файла в linux


awk 'NR==123' NC_007779.ptt
sed -n '123p' NC_007779.ptt
cat NC_007779.ptt | head -123 | tail -1

lsof

LiSt Of opened Files. Выводит информацию о том, какие файлы используются указанными процессами.

lsof -i 4 -a -p 1234 #(просмотр всех соединений IPv4, открытых процессом с PID = 1234)
lsof -i tcp:80 #(просмотр информации о процессе, который прослушивает 80 TCP порт)
lsof /dev/hd4 #(Список открытых файлов на устройстве /dev/hd4)
lsof /dev/cdrom #(Список процессов, работающих с CD ROM)
lsof -c ssh #(Список подключений по ssh)

В базовой поставке NetBSD и FreeBSD есть аналоги: утилиты fstat и sockstat.

понедельник, 8 июля 2013 г.

Как вернуть процесс из фона

Походу кроме
fg <NUM>
, можно еще и
%proc_name

Например
$ %emacs

воскресенье, 7 июля 2013 г.

Основы работы с emacs

Это консольный текстовый редактор, который позволяет:
- читать и отправлять почту;
- компилировать код;
- открывать subshell в виде даба для кокой-нибудь итерпретации кода.

Запустисть емакс без X11(не создавать графический фрейм, если запускаем  emacs из xterm окна, емакс отображается в том же окне) (-nw, --no-window-system) и любой кастомизации (-Q):
emacs -nw -Q


^h, t - запустить туториал
^t, a - поиск по патерну комманды
^h, f - описывает указанную функцию лиспа
^h k - узнать информацию о конкретной комбинации клавиш 

^x ^c - quit
^x ^f - read a file into Emacs
^x ^s - save the file to disk
^x s - save all files

^v - прокрутить файл на высоту терминала вперед
alt+v - прокрутить файл на высоту терминала назад
^l - перерисовать терминал и курсор с строкой, на которой он стоял окажется по средине терминала, если мы еще раз нажмем, то курсор окажется в верху терминала со своей строкой, если еще раз - то вконце.

^p - переместить каретку на строку вверх
^n - переместить каретку на строку сниз
^f - переместить каретку на символ вперед
^b - на символ назад
alt+f - на слово вперед
alt+b - на слово назад
^a - в начало строки
^e - в конец строки
alt+a - в начало предложения
alt+b - в конец предложения

alt+<(shift+,) перейти в начало всего текста
alt+>(shift+.) перейти в конец всего текста

Передвижение с указанным повторением раз:
^u  
^u 3 alt+f- передвинуться на 3 слова вперед
^u 5 ^p- передвинуться на 5 строк вверх
также более быстры вариант, но который работает не на всех терминалах:
alt+

^g - выйти из доглоиграющей команды емакс; а также если мы начали вводить команду из состоящую из нескольких комбинаций, это способ отмены на полпути

Окна
Или табы.
^x 1 - уничтожить все окна и оставить только первое

Мульти-ввод
Таже идея что и с передвижением, но тут только в уствкой символов.
Чтобы получить например 12 звездочек подряд мы вводим:
^u 12 * - получаем ************

<ret> удалить символ до каретки
^d удалить символ после каретки
alt+<ret> удалить слово до каретки
alt+d удалить слово после каретки
^k кильнуть(вырезать) от каретки до конца строки
alt+k кильнуть(вырезать) от каретки до начала строки

^space начать выделять текст, выделяется он комбинациями премещения курсора(каретки)
^w удалить "убитый" текст
^y заянковать "убитый" текст(вставить вырезанный текст), самый последний вырезанный
^y alt+y вставить более ранне вырезанный текст. После того как мы заянкили кильнутый текст, нажимая альт-янк, мы будем менять вставленный текст на ранее вырезанный, так нажимая несколько раз мы вернемся к нужному вырезанному тексту.

^u NUM ^y - передвинуться сразу назад на NUM, и не нужно нажимать несколько раз alt+y

Когда мы вырезаем текст(^k) на его месте все еще остается пустая строка, если мы еще раз нажимаем ^k, то пропадает и пустая строка, но кроме этого это включает режим дополнения вырезанного текста -- если мы еще будем вырезать так строки, то они все вырезаны со своими пустыми строками будут считаться одним выризанием, и заянкуем мы все эти строки одним нажатием вставить.

^/ или ^_(shift+-) или ^x u - Undo, отмена редакции

Работа с файлами

^x ^f - найти(открыть) файл

Линия внизу емакс когда мы туда вводим имя файла для открытия, в этом контексте называется минибуффер(^g - отмена ввода).

Когда мы сохраняем файл ^x ^s, то файл сохранятся с именем оригинала, но с нашими изменениями, но при этом сам оригинал тоже не теряется он сохраняется после этого в файле с именем ~.

Последующее открытие файлов, не теряет текущий, все открытые файлы находятся в буферах(обьект buffer), и мы можем между ними переходить:
^x ^b - список буфферов
^x 1 - скрыть список буфферов, это вообще-то удаляет все кроме одного окна, которые разделяют табы на фреймы.
^x b - открыть нужный буффер, введя его имя(автозаполнение работает)
Кстати среди списка буферов, находятся не все которые представляют файлы. Например *Messages* представляют буфер, который хранит ссобщения, что нам выводились, а *Completions* списки для выбора автокомплита, которые нам выводились.

^x s - емакс выведет подтверждение для каждого файла, который мы изменили и мы можем выбрать какой файл сохранять, а какой нет.

Команды с короткими именами и команды с длинными именами
команды вида ^x ... ожидают введениее одного символа для выполнения команды. Это символьные.
alt+... - ожидают введение длинного имени. Это именные команды, для них действует автокомплит по табу.

alt+x replace-string - ожидает два аргумента, заменивает все строки после позиции каретки предложенными.

Автосохранение
Емакс делает автосохранение и рядом с оригиналами появляются файлы #original.txt#, если мы крешимся и не успеваем сохраниться, можно сосстановиться из автосохранения, либо вручную, либо в емаке, открыв файл и введя alt+x recover-file. После сохранения эти файлы автосейвов удаляются из диска и появляются через определенный период, потом снова удаляются, если мы сами сохраняемся.

Участки терминала
Место где появляются подсказки нажатых комбинаций и куда мы вводим именные команды называется echo area.
Mode line - участок терминала, где дается информация о редактируемом файле и режиме емакс.
-=--:**--F1  TUTORIAL       63% L730   (Fundamental) ----

1) ** - означают, что в файле есть несохраненные изменения
2) L730, что картка находится на 730 строке, и что это 63% от всего файла.
3) (Fundamental) - тут отображается режим редактирования, major-mode, Fundamental по-умолчанию, бывают также: Lisp mode, Text mode, etc.
Моды отличаются командами - в разных языках по разному коментируются строки кода, это команды тоже отличаются, переходить в мод тоже есть конкертные комманды. alt+x fundamental - способ перейти в дефолтный мод:)
alt+x text-mode - перейти в текстовый режим, отиличие, что апострофы и символы после них считаются одним словом с предыдущим текстом.
^h m - получить информацию о текущем моде
Кроме мажорных модов бывают еще и minor-mode, они откличаются маленькими правками и их можно подключать к мажорному моду, всегде может быть включен один мажорный мод и сколько угодно минорных.
Для текстового мода полезный alt+x auto-fill-mode, он делает перевод строки на новую, если она не помещается в терминале, в строку вставляется именно символ конца строки. Если ввести снова эту комманду, то мы отключим этот режим. Разрыв наступает после ввода 70 символов. Чтобы поменять количество символов до разрыва, ^x f <NUM>, можно ввести сразу ^u 20 ^x f. Факт того, что мы переключили количество символов в строке, не означает, что у нас переформатируется ввесь текст файла, все последующие да, или же мы можем стать кареткой на како-нибудь параграф и нажать alt+q.

Поиск
^s -  начать инкрементный поиск от каретки и вниз. В эхо ерии появиться "I-search:", потом когда мы вводим символы по мере подхождения отдельных слов, они будут выделяется в тексте, и вводя следующий символ, можно будет заметить как количвество выделенных уменьшается. Если мы еще нажимаем ^s, то мы будем двигаться по выделенным словам "поточным веделением". Если нажимать <Ret>, то мы будем возвращаться по словам. Если же мы еще не двигались вперед, или вернулись к первому в поиске слову, то нажимая  <Ret&gt, мы будем удалять последние символы слова поиска, и количество подошедших слов снова начнет расти.

^r - начать поиск от каретки и вверх. Все что касается ^s касается и ^r.


Множественные окна
^x 2 - разделить терминал на два горизонтальных окна.
^+alt+v - проскролить окно, которое в текущий момент без фокуса
^x o - переместить фокус на другое окно.
^x 1 - оставит только одно окно, в котором в момент нажатия находится курсор.
^x 4 ^f - начать искать файл для неактивного окна, если не вводить ничего в эхо строке, а нанажать <Enter>, то у нас появится списко файлов во втором окне и мы можем выбрать необходимый файл, выделить его имя и нажать <Enter>, так мы его откроем.


Множественные фреймы
Как я понял, фреймы это графические окна, в которых открывается терминал.
^x make-frame <Enter> - как я понял откроет новое графическое окно с терминалом, а в нем будет запущен емакс.
^x delete-frame <Enter> - закроет фрейм

Recursive editing level
Как  я понял это режим, когда мы вводим длинные команды. Его можно заметить по квадратным скобкам вокрут имени мажорного мода [(Fundamental)], я пока такого не замечал.
Чтобы из него выбраться нужно нажать <ESC> <ESC> <ESC>, или ^g.

Получение помощи
^h c [hot_keys_comb_OR_command] - краткое описание
^h k [hot_keys_comb_OR_command] - полное описание
^h f [function] - описывает значение по имени функции(лисп), которая привязана к какой-то комбинации
^h v [varibale_name] - описать значение переменной, такие переменные например используеются для настройки редактора.
^h a [keyword] - вводится ключевое слово, в ответ выводятся все команды, которые могут касаться этого слова.
^h i  это команда очень важная в хелпах, read included Manuals (a.k.a. Info). Мы переходим в специальный буфер *info*, где можно почитать мануалы для пакетов, установленных на нашей системе.
Когда мы попадаем в *info* там мир своих команд.
нажимаем "m" (menu) и можем ввести имя утилиты командной строки:)








суббота, 6 июля 2013 г.

DevOps

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

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

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

Цикл создания репозитория git

mkdir myrepo
cd myrepo
git config --global user.name "John Smith"
git config --global user.email "example@stanford.edu"
git init
# Initialized empty Git repository in /home/ubuntu/myrepo/.git/
git status
echo -e ’line1\nline2’ > file.txt
git status
git add file.txt
git status
git commit -m "Added first file"
git log
echo -e "line3" >> file.txt
git status
git diff file.txt
git add file.txt
git commit -m "Added a new line to the file."
git log
git log -p
git log -p --color


Интересная вещь, что хешки есть не только у комита и у каждого файла
myrepo$ git ls-tree 5c8c9efc99ad084af617ca38446a1d69ae38635d
100644 blob 83db48f84ec878fbfb30b46d16630e944e34f205 file.txt


И по этому хешки мы можем просмотреть из конкретного комита файл не перезаливая весь репозиторий
$ git cat-file -p 83db48f84ec878fbfb30b46d16630e944e34f205
line1
line2
line3

Теперь если мы хотим залить наш локальный репозиторий на удаленный, то мы должны определиться с гит-хостингом.
Например если мы остановились на гитхабе, то мы заходим к ним на сайт и создаем удаленный репозиторий, получаем на него там урл.
Теперь нам по этому урлу нужно добавить удаленный репозиторий на локальный сервер гит. У каждого ремоута есть имя, имя по-умолчанию origin, если мы явно не указываем на какой удаленный репозиторий мы хотим запушить данные, подразумевается origin.
Допустим мы решили залить наш новосозданный проект myrepo, заходим в него и делаем
$ git remote add origin git@github.com:startup-class/myrepo.git
$ git push -u origin master
Здесь мы явно указали ремоут и бранч которые так называются по-умолчанию, или они называются основными, но можно в таком случае и не указывать.

Но в этом конкретном случае, гитхаб не разрешить заливаться, потому что он хочет от вас ssh sha1 public ключ, чтобы быть уверенным что именно тот, кто зарегистрировал репозиторий или имеет к нему доступ, хочет на него что-то залить.

Поэтому 
cd $HOME
ssh-keygen -t  rsa -C "my@email.com"
cd .ssh/
cat id_rsa.pub
Результат копируем и вставляем в панель управления на гитхобе, регистрирую таким образом хост для работы с удаленным репозиторием.

Теперь чтобы проверить что у нас есть соединение делаем:
ssh -T git@github.com
Hi your_github_username! You are successfully authenticated, but GitHub does not provide shell access.

Все теперь снова
cd ~/myrepo
git push -u origin master # will work after Add Key

emacs c подключенным nodejs

Подключается он как-то через настройки емака. Это пока опустим и вернемся чуть позже.


Итак мы открываем некий файл нодджеес:
emacs -nw fibonacci.js


Разбиваем окно терминала емаком на два таба: ^x 3

^c, !   - открываем во втором табе node REPL.
alt+i (alt+o) - переход между табами.
^c, ^j - скопировать строку из файла слева, на которой сейчас находится курсор и вставить ее в REPL справа.
^space - включить режим выделения.
-----------------------------------------------------
выделяем стандартными емаковскими гарячими клавишами
^f - вперед на один символ
^b - назад на один символ
^n - на следующую строку
^p - на предыдущую
alt+<(shift+,) в начало файла
alt+>(shift+.) в конец файла
^m - вставить пустую строку перед поточной
====================================


Подключение jshint к emacs

Опять же это делается через настройки, к этому вернемся попозже, а пока как пользоваться подключенным.
Нужно чтобы был установлен npm install -g jshint. Этот модуль подключается как модуль для компиляции файлов js.

^x, ^s сохранить файл
^c, ^u идет сохранение файла после поддтверждения, и потом сразу происходит его компиляция jshint-ом, результаты мы видим в табе справа.

Если файл достаточно большой, то чтобы перейти на указанную строку.
Нужно
alt+g, g выведется подсказка что введите номер сроки, мы воодим и курсор становится на эту строку.

пятница, 5 июля 2013 г.

screen

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

xargs

Очень мощная утилита. Используется для порождения паралельных процессов для какого-то вычисления. Чаще всего используется в паре с find, ls.

Пример задачи найти файлы и заглянуть им в первые две строки:
find /etc -name ’*\.sh’ | xargs head -2


Или вот пример решения часто распространенной проблемы для очень больших приложений на серверах таких компаний как гугл или фейбук. Например, задача узнать типы файлов в конкретной директории. Если файлов в директории немного то пойдет и:
file /etc/profile.d/*
Но что если их там очень много? Мы получим ошибку Argument list too long.
А вот решение:
ls /etc/profile.d | xargs file
Статейка на тему этой проблемы http://www.linuxjournal.com/article/6060


Шоткаты Bash

Есть больше но, я не писал те которые делают бекспейс и подобное
Ctrl + C оборвать поточное работающее в терминале приложение
Ctrl + Z свернуть в фон поточное работающее приложение
Ctrl + L тоже самое что команда clear - чистка екрана
Ctrl + U удалить все что находится по левую сторону каретки
Ctrl + K удалить все что находится по правую сторону каретки
Ctrl + R поиск по уже введенным ранее командам в терминал
Ctrl + D работает как делит, но если в терминале не чего удалять, то закрывает поточный терминал
Ctrl + P предыдущая команда в истории
Ctrl + N следующая команда в истории
Ctrl + W вытирает слово до курсора
Ctrl + Y если мы удалили что-то одной из команд, то это вставит удаленное в место, где находится сейчас каретка
Ctrl + _(Ctrl+Shift + -) отметить предыдущее удаление или вставку удаленного
Ctrl + T поменять два символа что находятся по разные стороны каретки
Esc + T поменять два слова что находятся по разные стороны каретки
Alt + F передвинуть курсор на одно слово вперед
Alt + B передвинуть курсор на одно слово назад

Tab автозаполнить имя файла или директории если мы ввели начальные символы

ссылка на рецепты awk

Очень удобная утилита для скриптового языка, который идеально подходит для файлов с табовым разделителем.
Наглядный пример
$ tail -n+4 *ptt | head -2
190..255        +       21      388476124       thrL    Y75_p0001       -       -       thr operon leader peptide
337..2799       +       820     388476125       thrA    Y75_p0002       -       -       fused aspartokinase I and homoserine dehydrogenase I
$ tail -n+4 *ptt | awk -F"\t" '{print $2, $3, $3 + 5}' | head -2
+ 21 26
+ 820 825

Кстати с помошью awk можно вывести строку из файла по ее номеру:
awk 'NR==123' myfile.txt

Рецепты http://www.pement.org/awk/awk1line.txt

sed

Stream editor для фильтрирования и преобразования текста.

Следующий код возьмет первые 10 строк файла *ptt(если он один в каталоге) и найдет в них текст kinase и заменит его на STANFORD, этот результат будет выведен в стандартный поток выводу
head *ptt | sed ’s/kinase/STANFORD/g’

Пример решения проблемы файла с виндовсковским концом строки на линуксе
sed -i ’s/\r/\n/g’ windows-newline-file.csv
-i[SUFFIX](--in-place[=SUFFIX]) замену сделает прям в файле, а с указанием суфикса сделает бекап оригинального файл имя+суфикс

"Рецепты использования" http://www.catonmat.net/blog/wp-content/uploads/2008/09/sed1line.txt

-e script, --expression=script
              add the script to the commands to be executed
Не понятно немного назначение этого ключа, потому что вон выше вставлен скрипт без этого ключа, как я понял с примеров выше, благодаря этому ключу можно вставлять несколько ключей.

Мой пример использования в проекте:
После windows нужно заменить имена mysql таблиц, потому что в linux они кейссенсетив. Создаем файл для правок каждого имени таблицы:
sweden.tables.sed:
s%`account_`%`Account_`%
s%`address`%`Address`%
s%`announcementsdelivery`%`AnnouncementsDelivery`%
s%`announcementsentry`%`AnnouncementsEntry`%
s%`announcementsflag`%`AnnouncementsFlag`%
s%`assetcategory`%`AssetCategory`%
s%`assetcategoryproperty`%`AssetCategoryProperty`%
s%`assetentries_assetcategories`%`AssetEntries_AssetCategories`%
s%`assetentries_assettags`%`AssetEntries_AssetTags`%
s%`assetentry`%`AssetEntry`%
s%`assetlink`%`AssetLink`%
s%`assettag`%`AssetTag`%
s%`assettagproperty`%`AssetTagProperty`%
s%`assettagstats`%`AssetTagStats`%
s%`assetvocabulary`%`AssetVocabulary`%
s%`blogsentry`%`BlogsEntry`%
s%`blogsstatsuser`%`BlogsStatsUser`%
s%`bookmarksentry`%`BookmarksEntry`%
s%`bookmarksfolder`%`BookmarksFolder`%
s%`browsertracker`%`BrowserTracker`%
s%`calevent`%`CalEvent`%
...

sed -f sweden.tables.sed dump.sql > changed_result.sql

grep

grep -l 'what-to-search' *txt *ptt
-l(--files-with-matches) вывести все файлы подошедшие маскам, в которых был найден указанный фрагмент текста.

grep -B 5 -A 5 Metazoa *gbk выводятся блоки текста вокруг найденной фразы по 5 срок до строки с фразой и по 5 после.
-B NUM(--before-context=NUM)
-A NUM(--after-context=NUM)

grep ’JOURNAL.*’ *gbk | sort | uniq вот пример с самой главной фишкой утилиты - поиск с применением регулярного выражения.

Утилиты информации о дисках linux

df -Th отчет по использованию системного диска
-h(--human-readable) выводит размеры в удобочитаемом виде(1K, 23M, 2G)
-T(--print-type) выводит тип файловой системы.
-t TYPE(--type=TYPE) фильтрует и выводит только файловые системы указанного типа.


du --max-depth=1 -b | sort -k1 -rn оценить использование файловой системы директориями.
-a(--all) выводить оценки для всех файлов, а не только директорий
--apparent-size выводит видимые размеры, а не фактически занимаемые, обычно он меньше, но может быть больше, если файл фрагментирован, какие-то дырки в файле.
-B SIZE(--block-size=SIZE) размер единицы размера. SIZE=K,M,G
-b(--bytes) = `--aprent-size --block-size=1`
-k = --blocl-size=1K
-m = --block-size=1M






Утилиты поиска линукс

find /etc | nl неидексовый поиск, полезен для поиска в поддиректориях

locale filename найти файл в файловой системе, это индексовый поиск
sudo apt-get install -y locate
sudo updatedb # takes a little bit of time
locate fstab

четверг, 4 июля 2013 г.

less and more

more позволяет просматривать большие файлы постранично, двигаться можно только вперед(вниз). Продвигаеться нажатием Enter.

less тоже самое что и more, но также позволяет возвращаться к предыдущим страницам (листать вверх). Продвигается стрелками v ^.


commands head and tail, и другие что используются с ними


head [ -10/-n10] выводит по умолчанию 10 или указанное количество строк из входящего потока или указанного файла. Можно также N символов, а не строк: head -c10
-q не выводить имена файлов если мы указываем несколько файлов на вход: head -q f1 *.txt

tail [ -10/-n10] выводит последние 10 или указанное количество строк
-n+10 выводит начиная из указанной строки и до конца файла строки.
-n10 / -n 10 выводи последние 10 строк.
-f(--follow[=])[{name|descriptor}] по мере добавления строк в указанный файл или входящий поток, они выводятся в исходящий
--retry пытается еще и еще открыть файл если к нему нет доступа. Полезно в паре с --follow=name --retry
-F тоже самое что --follow=name --retry

пример:
yes | nl | head -n 10000000 > foo &
tail -F foo

cut для вытягивания колонок из файлов, полезно для работы с файлами, которые разбиты табами в некие колонки, например некие базы данных.
-f1,5 вывести 1-ю и 5-ю колонки
-f4 -d'.' вывести 4-ю колонку, но удалить в ней все, что находится после первой встретившейся точки
-c1-20 вырезасть с 1 по 20 символ из файла, тут колонки получаются просто не причем.
Вот примеры использования:
wget ftp://ftp.ncbi.nih.gov/genomes/Bacteria/Escherichia_coli_K_12_substr__W3110_uid161931/NC_007779.ptt
head *ptt
cut -f2 *ptt | head
cut -f2,5 *ptt | head
cut -f2,5 *ptt | head -30
cut -f1 *ptt | cut -f1 -d’.’ | head
cut -c1-20 *ptt | head

nl numerate lines. Берет файл и проставляет его строкам впереди нумерацию.
Чтобы узнать количество строк в файле можно произвести следующую манипуляцию:
nl file.txt | tail -1


paste соединить между собой данные представленные в виде колонок.
tail -n+3 *ptt | cut -f1 > locs
tail -n+3 *ptt | cut -f5 > genes
paste genes locs genes | head

sort соритирует строки файла или входного потока.
-r рекурсивная сортировка.
-R рандомная сортировка.
-n(--numeric-sort)  две строки будут сравниваться по по кодах их символов.
-k3,7(--key=3,7) означает что ключем для сравнение будет считаться подстрока от 3-го до 7-го символа включительно.

uniq - выводит только уникальные строки введенного.
-c count возвращает возле строк количество встретившихся
-d(--repeated) выводятся только строки, которые встретились несколько раз.

wc words count.
wc *ptt # lines, words, bytes
wc -l *ptt # only number of lines
wc -L *ptt # longest line length, useful for apps like style checking

split дробит большие файлы на мелкие, это чаще всего начальная операция перед каким-нибудь исчислением в параллельных джобах.
-d(--numeric-suffixes) исользовать числовые суфиксы в дробях-файлах вместо алфавитных
-l NUMBER(--linues=NUMBER) файлы-дроби получаются из NUMBER строк исходного файла.



interesting small commands and general keys

-i interective. Спрашивает подтверждения перед копированим, перемещение, удалением.

alias rm='rm -i'  создать алиас
alias вывести все созданные алиасы

ln -s file.txt softlink-to-file.txt создать мягкую ссылку на файл

rmdir dirname удалить папку
rm -rf dirname удалить каталог рекурсивно, со всем содержимым. Самая опасная команда командной строки

rsync -avp something.txt alias_from_dotssh_config:~/ быстрый и гибкий инструмент для копирования на удаленные сервера и в локальные директории
-a (--archive) сохранить время создания оригинала
-v (--verbose)
-p(--perm) preserve/сохранить права оригинала

cat file1.txt f2.txt f3.txt > f_big.txt соединить(concatenate) несколько файлов в один.

yes [string] выводит строку "yes"(по-умолчанию) или "string" в поток вывода пока процесс не будет убит.

sleep 60 & процесс засыпает в фоне на 60 секунд
Пример как убить запущенный фоновый слип
sleep 180 &
kill `ps xw | grep sleep | cut f1 -d ' ' | head -1`

ps xw | grep sleep | grep -v "grep" последний греп делает противоположную задачу из-за ключа -- мы выключаем строки, которые содержат "grep", так среди процессов мы не заметим только что вызванных gerp sleep.

top  выводит поточные работающие процессы.

tar -cvf archive.tar origin.txt инструмент для архивации.
-c create. Создать архив.
-v verbose. Сообщать стадии
-f ARCHIVE Создать архив на диск в указанный файл.

gzip archive.tar создает архив с именем archive.tar.gz и удаляет оригинал.

tar -xzvf genome.tar.gz розархивировать
-x(--extract, --get) розархивировать
-z(--gzip, --gunzip, --unzip) розархивировать или заархиваировать, в зависимости от ниличия соответсвующих ключа

ls | tee list.txt эта команда называется Т-джекшин. Потому что она пайп роспаралеливает на два выхода дублирую прошедшие через нее символы: 1) идет в страндартный вывод, а второй в файл.
Больше приколов http://linux.101hacks.com/unix/tee-command-examples/

time benchmark_command замеряет время выполнения команды. Кроме того команда позволяет очень круто анализировать выполнение приложения -- его максимальное потребление памяти и другие.

lpr (off print line)- добаввляются в очередь печати файлы, это утилита для подачи файлов на принтер, она также позволяет отправлять некиефайла, когда условия начинают соответсвовать указанным, как я понял из ман описания.

ldd - выводит разделяемые библиотеки для каждого приложения, или указанного. Так можно узнать зависимости приложения или библиотеки.

xz (unxz, xzcat, lzma, unlzma, lzcat) - сжимает или разжимает .xz и .lzma файлы.
Когда пишем скипты лучше не испльзовать алиасы, а писать имя утили с ключами
unxz = xz --decompress
xzcat = xz --decompress --stdout
lzma = xz --format=lzma
unlzma =  xz --format=lzma --decompress
lzcat = xz --format=lzma --decompress --stdout

arch = uname -m - вывести хадверное имя машины

lilnux command wget

wget -w 2 -r -np -k -p http://www.some.dom/some/resource/root не интерактивный сетевой "web-скачиватель"(http, https, ftp + through proxies)
-r скачивать рекурсивно, максимальная глубина по умолчанию 5. Поменять можно -l 6 (--level=6)
-w(--wait)=seconds чтобы не перегружать сервер устанавливается время паузы между рекурсивным скачиванием содержимого сайта
-p(--page-requisites) скачивать все, что нужно для коректного отбражения страницы - стили, картинки, звуки и т.д.
-np(--no-parent) никогда не скачивает то, что находится выше по уровню иерархии на странице, даже если туда ведет ссылка со скаченной страницы.
-k(--convert-links) после скачивание конвертирует линки на станицах из вебовских в соответсвующие файловой системе, куда мы скачали ресурс.
-O FILE(--output-document=FILE) запишет весь загруженный контант в указанный файл

interesting keys of cp command

cp -a f1.txt fcopy.txt


-a archival Что означает, скопировать как архив, тоесть создается клон со временем создания оригинала, а не момента создания копии.

lilnux command curl

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


-s(--silent). Ни прогресс ни ошибки не выводятся в аутпут.
-s -S(--show-error) Прогресс не выводится, но ошибки выводятся.
-i(--include) включает хттп-заголовки в вывод.

Можно испльзовать переменные стреды:
GHUSER="defunkt"
GHVAR="orgs"
curl -i https://api.github.com/users/$GHUSER/$GHVAR # with variables
Можно также эмулировать медленное соединение, вот пример, как принимать от сервера данные со скорость 1К/сек:
curl --limit-rate 1K http://some.url/some/uri

linux command echo

echo -e "String1\nString2\nString" > demo.txt


-e - переводы строки интерпретируются именно как переводы строки.


среда, 3 июля 2013 г.

Странные символы в коммандной строке. Перенаправление потоков в/в процессов

> Перенаправляет стандартный поток вывода процесса в файл по указанному пути, при этом содержание файла перезаписывается
ls > files_list.txt


1> Тоже самое что и предыдущий символ

2> Перенаправляет стандартный поток ошибок процесса в файл по указанному пути, содержимое файла переписывается
node script.js 1>ok.log 2>error.log

&> Перенаправляет оба потока вывода в один файл.
node script.js &> logs_and_errs.txt 

command N > &M Делает копию из первого указанного потока во второй, при этом байты клонируются и идут в оба потока. Например, для того, чтобы сообщения об ошибках дублировались на стандартный вывод, надо дать команду 2>&1, в то время как 1>&2 дублирует stdout в stderr. Это особенно полезно когда мы перенаправляем в файл - мы одноверменно пишем в файл и видим, что туда пишется. Для подобного эфекта между приложениями используется утилита tea.

>>Тоже самое что и первый символ только в файл дописываются стоки, а не переписывается файл
ls >> files_list.txt

< Перенаправление получения стандартного ввода из указанного файла
sort < files_list.txt > sorted_files_list.txt


Выше указанные ключи коммандной строки должны ставится после всех указанных ключей вызова комманды.

| - создание pipe, перенаправление стандартного потока вывода первого процесса во второй, так мы можем связывать кучу вызовов утилит, перенаправляя результаты предыдущей в следующую, что позволяет выполнить какую-то сложную операцию состоящую из вызовов приложений.
ls -l | less


& - выполнить вызванную команду в фоне консоли (консоль не блокируется на время выполнения).
tar -czf file.tar.gz dirname &
Как только мы ввели команду, в консоли сразу выведется порядковый номер в [...], который укажет порядковый номер новосозданной джобы, и рядом айди ее процесса. Увидеть поточные джобы jobs. Чтобы вывести из фона конкретную fg num, fg %- предпослднюю, fg %+ последнюю джобу.

&& - выполнить последующую команду только в случае нормального завершения работы предыдущей команды, но нормальным считается факт возвращение 0 (exit(0)), если приложение не возвращает ничего или не ноль, то последующая команда выполняться не будет. Нужно быть внимательным с diff - у него возвращается 0 - если два файла не отличаются и 1 - если отличаются
echo "Print this" && echo " and this"


|| - выполнить следующую команду только в случае, если первая выполнилась не нормально (возвратила не 0)
diff one.txt other.txt || echo "you will see this if one.txt and other.txt are different"

false || echo "you will see this

true || echo "you will not see this


; - не взирая на то, что предыдущая команда возвратит, выполнить все перечисленные команды
false ; echo "See this" ; false ; echo "and this"

\ - означает склеить поточный текс со стекстом в следующей строке, выкинув превод строки
$ wget ftp://ftp.ncbi.nih.gov/genomes/Bacteria/\
>  Escherichia_coli_K_12_substr__W3110_uid161931/NC_007779.ptt

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

понедельник, 1 июля 2013 г.

Node http-module

var http = require('http');

var server = new http.Server();//EventEmitter
server.listen(1337, '127.0.0.1');
server.on('request', function(req, res) {
 ...
 res.end("..");
});
req - объект класса http.IncomingMessage
res - объект класса http.ServerResponse

Можно заметить, что браузер обрабатывает два запроса по одному браузерному запросу, дело в том, что браузер еще обращается к favicon.ico.

nodejs util-модуль, console

Модуль unitl

util.inspect похож на java:toString.
Он трансформирует в строку представление обьекта, при этом его не пугают циклические ссылки на обьект. Если у обьекта есть метод inspect, то тогда выводится возвращаемое значение этого метода.
console.log(util.inspect(myobjs)); // == console.log(myobjs) - тоесть консоль внутри пользуется этим методом

util.format("string", varargs...)
%s - место под вставку строки
%d - место под вставку числа
%j - место под вставку обьекта представленного в формате json(это именно перевод в json, а не вызов util.inspect).
console.log пользуется этой функцией неявно если console.log("string", varargs...), при этом если аргументов больше чем меток в строке, то первые отформатируются , а остальные выведутся util.inspect методом.

util.inherit(Rabbit, Animal) - прототипное наследование

npm глобальные модули

Такие модули устанавливаются не в каталог проекта, а папку модулей нода. Но это не означает, что такой модуль теперь будет доступен в любом сприпте по require('modulename'), это не так.
Такой модуль стает скорее всего системной утилитой, которую можно вызывать в любом месте файловой системы. Тоесть мы получаем системную утилиту просто написанную на ssjs.
Вот пример:


$ sudo npm -g i uglify-js

Теперь в любом месте мы можем сжимать наш js:
$ uglifyjs my.js

npm install более подробно

package.json:
  "version": "MAJOR.MINOR.PATCH"
Правила ведения версий в npm соответсвуют semver.org.
- Если у нас модуль еще не стабилен то мы ведем разарботку под версиями 0.x.x
- Если мы заливаем какие-то багфиксы текущего функционала то мы увеличиваем цифру участка PATCH.
- Если мы добавляем новый функционал апи, который вообще не затрагивает существующий, то обновляем MINOR
- Если же мы внесли изменения которые затрагивают текущее апи, то тогда - MAJOR

Чтобы установить конкретную версию модуля:
npm i express@3.0.15


Установить незапаблишенную версию, но которая есть в VC-repo, например на гитхабе:
npm i git://github.com/.../epress.git


Или скаченную на диск:
npm i /path/to/downloaded


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

Мы не обязаны таскать со своим модулем его зависимости, достаточно в папке с нашим модулем вызвать
npm i

И все зависимости будет подтянуты, которые указаны в package.json, но кроме зависимостей для работы модуля будут подтянуты и зависимости для разработки модуля, которые находятся в поле package.json:devDependencies, если модуль устанавливается как зависимость другого модуля, то эти зависимости не устанавливаются.

package.json:main обычно это "index.js", но мы можем поменять на что-то специфическое для нашего модуля - /sub/app.js