Изучите Node.js: руководство для начинающих

JavaScript, несомненно, является одним из самых популярных языков программирования сегодня, и не зря. Его можно легко запустить в браузере, на сервере, на рабочем столе или даже на телефоне в качестве приложения. Один из самых популярных и простых способов написания JavaScript - использование Node.js [https://nodejs.org/en/]. Существует довольно много ресурсов для изучения Node.js, но не многие из них действительно дают вам базовую информацию, инструменты и ресурсы, необходимые для действительно успешного написания кода Node.

JavaScript, несомненно, является одним из самых популярных языков программирования сегодня, и не зря. Его можно легко запустить в браузере, на сервере, на рабочем столе или даже на телефоне в качестве приложения. Один из самых популярных и простых способов написания JavaScript - использование Node.js.

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

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

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

Что такое Node

Node - это серверная кроссплатформенная среда выполнения, работающая на движке V8 JavaScript , который поддерживает браузер Google Chrome. Это действительно сердце Node и компонент, который фактически анализирует и выполняет код.

Движок V8 делает это, компилируя JavaScript в машинный код, что делает его намного быстрее, чем интерпретатор. Чтобы еще больше ускорить процесс, скомпилированный код оптимизируется (и повторно оптимизируется) динамически во время выполнения на основе эвристики профиля выполнения кода. Это означает, что во время выполнения программы движок фактически отслеживает ее производительность и ускоряет код на основе определенных отслеживаемых факторов.

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

Этот дизайн идеально подходит для оптимизации пропускной способности и масштабируемости вашего кода, что является большой причиной того, почему он стал таким популярным. Например, кто-то заставил его обрабатывать 600000 одновременных подключений к веб-сокетам , что безумие. Теперь ему пришлось немного изменить конфигурацию, но это не делает ее менее впечатляющей. Именно поэтому такие компании, как IBM, Microsoft и PayPal, используют Node для своих веб-сервисов.

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

логотипnpm{.ezlazyload}

Публичный репозиторий открыт для всех, кто может загрузить и опубликовать код. На момент написания этой статьи в npm размещено более 210 000 модулей, начиная от веб-сайтов и заканчивая инструментами командной строки и оболочками API.

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

Для чего хорош Node

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

Это также очень хорошо для создания интерфейса для веб-API (через REST). Это связано с тем, что он оптимизирован для ввода-вывода, управляемого событиями (о чем я уже говорил), и изначально обрабатывает JSON, поэтому синтаксический анализ практически не требуется.

Для чего Node не подходит

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

Node еще довольно молод, поэтому он все еще находится в стадии быстрого развития. За последние несколько месяцев мы перешли с v0.12.x на v5.1.x Так что, если вам нужно что-то более стабильное, это, вероятно, не для вас.

Что касается "проблемы" асинхронного программирования, я думаю, что первая часть этого ответа Quora хорошо ее объясняет:

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

Хотя в целом асинхронное программирование - это хорошо, оно действительно усложняет ваши программы.

Узел REPL

Хорошо, перейдем к коду. Мы собираемся начать довольно просто и просто запустим несколько команд в REPL (цикл чтения-оценки-печати), который представляет собой всего лишь приложение, позволяющее интерактивно запускать код узла в оболочке. Написанная здесь программа выполняется не сразу, а по частям.

Я предполагаю, что вы уже знакомы с JavaScript, поэтому в этой статье мы просто рассмотрим некоторые специфичные для Node вещи.

Давайте попробуем один из встроенных модулей, поставляемых с Node, например, модуль crypto

Предполагая, что у вас уже установлен Node, запустите команду node в своей оболочке и введите следующий код в строку за строкой:

 var crypto = require('crypto'); 
 
 crypto.createHash('md5').update('hello world').digest('hex'); 

После ввода последней строки в REPL (или нажав кнопку «запустить» выше) вы должны увидеть 5eb63bbbe01eeed093cb22bb8f5acdc3, распечатанный на консоли.

Модуль crypto загружается с помощью функции require() , которая обрабатывает разрешение и загрузку кода за вас. Подробнее о том, как это работает, можно узнать здесь.

После загрузки модуля вы можете использовать его функции, которые в данном случае мы используем createHash() . Поскольку REPL выполняют код по частям, они обычно распечатывают возвращаемое значение для каждой строки, как вы видели здесь.

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

Ваша первая программа

REPL - это весело и все такое, но пока они нам не дадут. Итак, давайте продолжим и напишем нашу первую настоящую программу Node. Мы пока не будем беспокоиться об использовании сторонних модулей (но не волнуйтесь, мы сделаем это позже), поэтому давайте сначала посмотрим, какой встроенный код нам доступен. Вам уже предоставлено большое количество кода, включая (но не ограничиваясь):

  • fs : простые оболочки, предоставляемые над стандартными функциями POSIX
  • http : HTTP-сервер и клиент нижнего уровня.
  • os : предоставляет несколько основных методов, чтобы рассказать вам о базовой операционной системе.
  • path : Утилиты для обработки и преобразования путей к файлам
  • url : Утилиты для разрешения и анализа URL
  • util : стандартные служебные функции, такие как отладка, форматирование и проверка.

Объем встроенного кода не соответствует уровню Python, но он справится со своей задачей. Настоящие преимущества приходят, когда вы начинаете пользоваться сторонними модулями.

Для нашей первой программы мы создадим простую утилиту, которая определяет ваше местоположение с помощью вашего IP-адреса (я знаю, это жутковато):

 var http = require('http'); 
 
 var options = { 
 hostname: 'ipinfo.io', 
 port: 80, 
 path: '/json', 
 method: 'GET' 
 }; 
 
 var req = http.request(options, function(res) { 
 var body = ''; 
 
 res.setEncoding('utf8'); 
 res.on('data', function(chunk) { 
 body += chunk; 
 }); 
 
 res.on('end', function() { 
 var json = JSON.parse(body); 
 console.log('Your location: ' + json.city + ', ' + json.region); 
 }); 
 }); 
 
 req.end(); 

Скопируйте приведенный выше код и вставьте его в файл с именем index.js. Затем в командной строке перейдите в каталог с только что созданным файлом и запустите его:

 $ node index.js 

Вы должны увидеть «Ваше местоположение: [ГОРОД], [РЕГИОН]», напечатанное в командной строке. Распечатанный город / регион, вероятно, будет вам довольно близок, но не точен. Кроме того, если город / регион не напечатан, это означает, что вашего IP-адреса не было в базе данных.

Поскольку этот код не использует никаких сторонних зависимостей, ему не нужен файл package.json node_modules , о которых мы подробнее расскажем в следующем разделе.

Ваш первый пакет

Обратите внимание, что в этой статье я использую «пакет» и «модуль» как синонимы.

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

Типичный модуль состоит из нескольких важных вещей:

  • package.json : файл JSON, содержащий всю информацию о модуле.
  • node_modules /: каталог, содержащий все зависимости
  • index.js: основной файл кода
  • README.md: Документация по модулю
  • test /: каталог тестов для модуля

Есть множество других вещей, которые вы можете добавить в модуль (например, файл .npmignore, каталог docs или файлы конфигурации редактора), но перечисленные выше вещи являются одними из самых распространенных, которые вы увидите.

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

Вместо того, чтобы просто сообщать вам ваше местоположение на основе вашего IP-адреса, мы будем использовать некоторые популярные пакеты Node для создания инструмента, который позволит вам найти местоположение любого сервера веб-сайта. Назовем его twenty ( посмотрим почему ).

Инициализация пакета

Сначала создайте новый каталог для своего проекта и перейдите в него:

 $ mkdir twenty 
 $ cd twenty 

Затем используйте npm для инициализации проекта:

 $ npm init 
 
 This utility will walk you through creating a package.json file. 
 It only covers the most common items, and tries to guess sane defaults. 
 
 See `npm help json` for definitive documentation on these fields 
 and exactly what they do. 
 
 Use `npm install <pkg> --save` afterwards to install a package and 
 save it as a dependency in the package.json file. 
 
 Press ^C at any time to quit. 
 name: (twenty) 
 version: (0.0.1) 
 description: Locates the city/region of a given URL/IP address 
 entry point: (index.js) 
 test command: 
 git repository: 
 keywords: 
 license: (MIT) 
 About to write to /Users/scott/projects/twenty/package.json: 
 
 { 
 "name": "twenty", 
 "version": "0.0.1", 
 "description": "Locates the city/region of a given URL/IP address", 
 "main": "index.js", 
 "scripts": { 
 "test": "echo \"Error: no test specified\" && exit 1" 
 }, 
 "author": "Scott Robinson < [email protected] > (http://stackabuse.com)", 
 "license": "MIT" 
 } 
 
 
 Is this ok? (yes) yes 

Заполните каждое приглашение (начиная с name: (twenty) ) или не вводите ничего и просто нажмите клавишу возврата, чтобы использовать настройки по умолчанию. Это создаст правильно настроенный package.json содержащий следующий JSON:

 { 
 "name": "twenty", 
 "version": "0.0.1", 
 "description": "Locates the city/region of a given URL/IP address", 
 "main": "index.js", 
 "scripts": { 
 "test": "echo \"Error: no test specified\" && exit 1" 
 }, 
 "author": "Scott Robinson < [email protected] > (http://stackabuse.com)", 
 "license": "MIT" 
 } 

Этот файл - ваша отправная точка, где сохраняется вся информация, относящаяся к проекту.

Установить зависимости

Чтобы добавить зависимости в свой проект, вы можете использовать команду npm install из командной строки. Например, чтобы добавить нашу первую зависимость, request , попробуйте запустить это:

 $ npm install --save request 

Команда install загрузит последний request из npm и сохранит его в каталоге node_modules Добавление --save сообщает npm, что необходимо сохранить детали пакета в package.json в разделе dependencies:

 "dependencies": { 
 "request": "2.67.0" 
 } 

Теперь вы сможете использовать request любом месте кода вашего проекта.

Улучшение кода

Модуль request дает вам функции, позволяющие легко выполнять все виды HTTP-запросов. Пример HTTP, который мы показали выше, не так уж и плох, но request делает код еще более компактным и легким для чтения. Эквивалентный код, использующий request будет выглядеть так:

 var request = require('request'); 
 
 request('http://ipinfo.io/json', function(error, response, body) { 
 var json = JSON.parse(body); 
 console.log('Your location: ' + json.city + ', ' + json.region); 
 }); 

Было бы более интересно, если бы мы могли найти местоположение любого IP-адреса, а не только нашего собственного, поэтому давайте позволим пользователю вводить IP-адрес в качестве аргумента командной строки. Как это:

 $ node index.js 8.8.8.8 

Чтобы получить доступ к этому аргументу в нашей программе, Node делает его доступным в глобальном объекте process process.argv , который представляет собой массив. Для команды, которую мы только что выполнили выше, process.argv будет ['node', 'index.js', '8.8.8.8'] .

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

Как и request , мы установим его с помощью:

 $ npm install --save yargs 

Изменяя код, чтобы использовать yargs для захвата аргумента (или по умолчанию на наш собственный IP, если аргумент не был указан), мы получаем следующее:

 var request = require('request'); 
 var argv = require('yargs').argv; 
 
 var path = 'json'; 
 
 path = argv._[0] || path; 
 
 request('http://ipinfo.io/' + path, function(error, response, body) { 
 var json = JSON.parse(body); 
 console.log('Server location: ' + json.city + ', ' + json.region); 
 }); 

Пока что этот инструмент отлично подходит для использования в командной строке, но что, если кто-то захочет использовать его как зависимость в своем собственном коде? На данный момент код не экспортирован, поэтому вы не сможете использовать его где-либо еще, кроме командной строки. Чтобы сообщить Node, какие функции / переменные сделать доступными, мы можем использовать module.exports .

 var request = require('request'); 
 var argv = require('yargs').argv; 
 
 var findLocation = function(ip, callback) { 
 var path; 
 if (typeof(ip) === 'function' || !ip) path = 'json'; 
 else path = ip; 
 
 request('http://ipinfo.io/' + path, function(error, response, body) { 
 var json = JSON.parse(body); 
 callback(null, json.city + ', ' + json.region); 
 }); 
 }; 
 
 module.exports = findLocation; 

Большой! Теперь любой, кто скачивает этот пакет, может потребовать его в любом месте своего кода и использовать findLocation() .

Но вы, возможно, заметили, что теперь мы больше не можем использовать его как инструмент командной строки. Однако мы не хотим помещать туда остальную часть старого кода вот так:

 var request = require('request'); 
 var argv = require('yargs').argv; 
 
 var findLocation = function(ip, callback) { 
 var path; 
 if (typeof(ip) === 'function' || !ip) path = 'json'; 
 else path = ip; 
 
 request('http://ipinfo.io/' + path, function(error, response, body) { 
 var json = JSON.parse(body); 
 callback(null, json.city + ', ' + json.region); 
 }); 
 }; 
 
 var arg = argv._[0] || path; 
 
 // This runs every time the file is loaded 
 findLocation(arg, function(err, location) { 
 console.log('Server location: ' + location); 
 }); 
 
 module.exports = findLocation; 

Это было бы плохо, потому что каждый раз, когда кто-то require() этот файл для использования функции findLocation() он выводит их собственное местоположение в командную строку. Нам нужен способ определить, был ли этот файл вызван напрямую с помощью node index.js а не с помощью require() , поэтому, если он был вызван напрямую, мы проверим командную строку на предмет аргументов. Это можно сделать, require.main с module , например: if (require.main === module) {...} , что оставляет нам:

 var request = require('request'); 
 var argv = require('yargs').argv; 
 
 var findLocation = function(ip, callback) { 
 var path; 
 if (typeof(ip) === 'function' || !ip) path = 'json'; 
 else path = ip; 
 
 request('http://ipinfo.io/' + path, function(error, response, body) { 
 var json = JSON.parse(body); 
 callback(null, json.city + ', ' + json.region); 
 }); 
 }; 
 
 if (require.main === module) { 
 findLocation(argv._[0], function(err, location) { 
 console.log('Server location: ' + location); 
 }); 
 } 
 
 module.exports = findLocation; 

Теперь мы можем использовать этот код как в командной строке, так и в качестве зависимости.

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

Публикация вашего пакета

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

 $ npm publish 

Вам будет предложено ввести имя пользователя и пароль, а затем код будет помещен в реестр.

Имейте в виду, что вам нужно либо расширить область действия вашего пакета, либо изменить его имя, поскольку имя «20» уже занято мной.

Куда пойти отсюда

С популярностью в Node на подъем, есть тонны ресурсов по всему интернету. Вот несколько из самых популярных книг и курсов, с которыми я столкнулся, которые научат вас гораздо большему, чем то, что я смог показать здесь:

Или, если вы хотите придерживаться более коротких руководств, вот несколько из Stack Abuse, которые могут быть полезны:

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

Заключение

Мы рассмотрели лишь небольшую часть того, что могут предложить Node и npm, поэтому ознакомьтесь с некоторыми ресурсами, на которые я ссылался выше, чтобы узнать больше.

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

Вы новичок в Node? Какие еще темы Node вы хотите узнать? Дайте нам знать об этом в комментариях!

comments powered by Disqus

Содержание