Экспресс-бой (2): основа Node.js

Node.js JavaScript Express

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

  • Установка узла
  • Как использовать экосистему сторонних модулей
  • Установка сторонних модулей
  • Несколько простых примеров использования
  • Несколько советов и хитростей во время разработки

До тех пор я предполагаю, что вы уже знакомы с основами JavaScript и знакомы с некоторыми основными операциями командной строки. Кроме того, не думайте, что эта глава даст вам полное представление о Node. Но если вы хотите, вы можете прочитатьNode.js в действии.

Установить узел

Одной из отличительных черт мира JavaScript является его избирательность, и установки Node не являются исключением.

можно скачать с официальногостраницаНайдите исходный код и файлы установочного пакета для различных версий. Для установки рекомендуется использовать установочный пакет, соответствующий вашей операционной системе. Конечно, вы также можете установить его с помощью менеджера пакетов, такого как apt-get, Homebrew и т. д., если он есть в вашей системе. Подробную информацию см. в разделе Установка официального инструмента управления пакетами.руководство.

Если вы используете Mac или Linux, я настоятельно рекомендую вам использоватьNVMустановить. Соответствующая программа в Windows-системахNVMW. Эти инструменты управления версиями позволяют свободно переключаться между разными версиями. Например, вы можете опробовать функции новой версии, сохраняя при этом стабильную версию в системе. Кроме того, NVM очень легко удалить без необходимости прав системного администратора. Процесс установки также требует только одной строки команды в терминале.

Теперь, пожалуйста, установите Node в вашей системе.

Запустите свой первый скрипт Node.

После завершения установки сначала напишите «Hello World», чтобы протестировать некоторые из них. недавно построенныйhelloworld.jsДобавьте этот код в:

console.log("Hello, World!");

Код в основном используетconsole.logЧтобы напечатать строку «Hello, world!», я думаю, это не будет незнакомо для фронтенд-программистов. Ниже мы используемnode helloworld.jsЗапустите код. Если все пойдет хорошо, появится следующий вывод:

02_01
02_01

Использование модулей

В большинстве языков программирования мы разделяем код и переносим в него эти файлы, когда используем его. Например, включить в C и C++, импортировать в Python, потребовать в Ruby и PHP. Другие языки, такие как C#, делают межфайловые ссылки во время компиляции.

Долгое время JavaScript официально не поддерживал модульный механизм. Итак, кто-то в сообществе написал инструмент вроде RequireJS для решения проблемы импорта зависимостей. Однако большую часть времени через\тег для импорта файлов. Node прекрасно решает проблему импорта модулей, реализуя стандартный модуль CommonJS.

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

Импорт встроенных модулей

В Node уже встроено много полезных модулей, например, модуль файловой системы.fs, функциональный модуль инструментаutil.

В веб-приложениях, написанных на Node, наиболее распространенной задачей является разбор URL-адресов. Браузер запрашивает соответствующий ресурс на сервере через определенный URL-адрес. Например, веб-запрос на посещение домашней страницы, посещение страницы «О нас». Все эти URL-адреса представлены в виде строк, и нам нужно проанализировать их, чтобы получить больше информации. Здесь мы расскажем, как вводить встроенные модули путем анализа URL-адреса.

ВстроенныйurlВ модуле представлено не так много методов, но один из нихparseФункции очень полезные. Он может извлекать полезную информацию, такую ​​как доменные имена и пути, из строк URL.

Здесь мы используемrequireДля реализации импорта модуля эта команда согласуется с функциями Include и Import, упомянутыми выше. Передав имя модуля в качестве параметра, команда может успешно вернуть соответствующий модуль. В большинстве случаев возвращаемый объект являетсяobjectОбъекты, но иногда строки, числа или функции. Ниже приведен пример кода для введения модифицированного модуля:

var url = require("url");   
var parsedURL = url.parse("http://www.example.com/profile?name=barry");  

console.log(parsedURL.protocol);  // "http:"
console.log(parsedURL.host);       // "www.example.com"
console.log(parsedURL.query);     // "name=barry

В приведенном выше коде с помощьюrequire("url")Возвращается объект модуля, и методы объекта могут быть вызваны так же, как и любой другой объект. Сохраните этот код вurl-test.jsв и бежатьnode url-test.jsкоманда, вы увидите имя протокола, имя домена и условия запроса.

Кроме того, в большинстве случаев, когда мы импортируем модуль, мы будем использовать переменную с тем же именем для получения возвращаемого объекта модуля. Например, приведенное выше использованиеurlпредставлятьrequire("url")Возвращаемое значение. Конечно, вам вовсе не обязательно следовать приведенным выше правилам. Вы также можете сделать это, если хотите:

var theURLModule = require("url");   
var parsedURL = theURLModule.parse("http://www.example.com/profile?name=barry");

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

Импортируйте сторонние модули с помощью npm и package.json.

Встроенные модули Node далеки от удовлетворения повседневных потребностей в разработке, поэтому внедрение сторонних модулей является обязательным навыком.

Во-первых, нам нужно понять файл package.json. Все Node-проекты хранятся в отдельной папке, и если в проекте используются сторонние модули, в ней должен быть файл package.json. Содержимое package.json очень простое, обычно оно определяет имя проекта, номер версии, автора и внешние зависимости проекта.

В только что созданной папке проекта Node скопируйте следующее содержимое в package.json.

{
  "name": "my-fun-project",   
  "author": "Evan Hahn",      
  "private": true,            
  "version": "0.2.0",         
  "dependencies": {}          
}

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

// Returns "Hello, Nicholas Cage!"
Mustache.render("Hello, {{first}} {{last}}!", {
  first: "Nicholas",
  last: "Cage"
});

// Returns "Hello, Sheryl Sandberg!"
Mustache.render("Hello, {{first}} {{last}}!", {
  first: "Sheryl",
  last: "Sandberg"
});

Теперь предположим, что вы хотите поприветствовать Николаса Кейджа, написав простое приложение Node с помощью модуля Mustache.

Сначала запустите в корневом каталоге папки проектаnpm install mustache --save. Эта команда создаст новыйnode_modulesпапку и сохраните Mustache в этой папке.--saveПараметр добавит модуль в файл pakage.json. На данный момент папка pakage.json выглядит примерно так, где Mustache будет использовать последнюю версию.

{
  "name": "my-fun-project",
  "author": "Evan Hahn",
  "private": true,
  "version": "0.2.0",
  "dependencies": {
    "mustache": "^2.0.0"  #A
  }
}

если вы не используете--saveвариант, хотя он также создастnode_modulesпапка сохранит модуль Mustache в подкаталог с тем же именем, но pakage.json не изменится. Причина, по которой эти зависимости сохраняются в package.json здесь, заключается в том, чтобы облегчить другим разработчикам использование сразу после получения проекта.npm installЗавершите установку всех зависимостей. Другая причина заключается в том, что проекты Node обычно игнорируют папку node_modules и сохраняют package.json только при управлении кодом.

После завершения установки следующим шагом будет использование:

var Mustache = require("mustache");  
var result = Mustache.render("Hi, {{first}} {{last}}!", {
  first: "Nicolas",
  last: "Cage"
});
console.log(result);

Сохраните код в mustache-test.js и выполнитеnode mustache-test.jsЗаказ. Тогда вы увидите Привет, Николас Кейдж!

Это так просто, как только эти зависимости установлены, вы можете вызывать их так же, как встроенные модули.node_modulesРабота, вносимая модулем в модуль, напрямую передается Node, и вам не нужно об этом беспокоиться.

Конечно, вы можете добавить зависимости проекта вручную, а также можете указать версию зависимостей.

npm init
Помимо установки зависимостей, npm может делать и другие вещи. Например, автоматически сгенерируйте package.json, а не редактируйте его вручную. В новую папку проекта можно попасть черезnpm initЧтобы настроить имя проекта, автора, версию и другую информацию, а затем npm автоматически сгенерирует соответствующий файл package.json. Этот автоматизированный процесс экономит время разработчиков.

Реализовать приватные модули

Сначала вы узнаете, как использовать модули, разработанные другими, а затем вы узнаете, как разработать собственный модуль. Теперь предположим, что вам нужно случайным образом вернуть целое число от 0 до 100. Без введения других модулей код примерно такой:

var MAX = 100;
function randomInteger()  {
    return Math.floor( (Math.random() * MAX) );
}

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

var MAX = 100;
function randomInteger()  {
    return Math.floor( (Math.random() * MAX) );
}

module.exports = randomInteger;

Последняя строка кода может показаться немного чуждой новичкам в Node. Для каждого модуля может быть открыта только одна переменная, и она должна быть установлена ​​через module.exports. В этом примере представлена ​​только одна функциональная переменная, поэтому другие файлы не могут получить доступ к MAX как к частной переменной модуля.

module.exports может отображать любую переменную, хотя в данном случае это функция, обычно это объект. Конечно, вы можете выставлять строки или массивы.

Далее мы будем использовать этот новый модуль. существуетrandom-integer.jsВ этом же каталоге создайте новыйprint-three-random-integers.jsи скопируйте код ниже:

var randomInt = require("./random-integer");  #A
console.log(randomInt());  // 12
console.log(randomInt());  // 77
console.log(randomInt());  // 8

Остальное почти то же самое, что и раньше, за исключением того, что вам нужно указать относительные пути через точечный синтаксис. пройти черезnode print-three-random-integers.jsКоманда, мы можем проверить эффект запуска программы. Если ничего другого, будут напечатаны три случайных числа от 0 до 100.

если вы попытаетесь бежатьnode random-integer.jsЕсли это так, вы также обнаружите, что ничего не происходит. Хотя мы предоставляем функцию в модуле, но изменение функции не будет выполнено и не будет выведено никакого вывода.

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

Приведенный выше раздел представляет собой простое введение в модульную систему Node.

Node: асинхронный мир

В главе 1 я кратко рассказал об асинхронной природе Node на примере «испечь кекс». Ключевым моментом здесь является то, что вы не можете делать два дела одновременно, даже если они происходят одновременно. Хотя я могу потренироваться в процессе выпечки, но ведь духовка — это всего лишь внешняя вещь.

02_02
02_02

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

В Express есть два основных внешних ресурса:

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

В коде Node эта асинхронность обрабатывается с помощью обратных вызовов. Это работает так же, как отправка запроса AJAX на веб-странице. При отправке запроса вы прикрепляете функцию обратного вызова, которая будет выполняться при обработке запроса.

Например, сейчас вы читаете файл на жестком дискеmyfile.txt. Когда чтение закончено, вы хотите иметь возможность распечатать, сколько раз появляется буква X. Код выглядит следующим образом:

var fs = require("fs");  

var options = { encoding: "utf-8" };                      
fs.readFile("myfile.txt", options, function(err, data) {  
  if (err) {                                
    console.error("Error reading file!");   
    return;                                 
  }                                        

  console.log(data.match(/x/gi).length + " letter X's");  
});

Ниже мы объясним код шаг за шагом:

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

Далее нам нужно установитьfs.readFileПараметры в методе, первый — это имя файла, а второй — функция обратного вызова. И функция обратного вызова выполняется после окончания чтения.

Большинство обратных вызовов в Node будут устанавливать сообщение об ошибкеerrorв качестве первого параметра. Обычно этот параметр равен null , в случае возникновения ошибки этот параметр сохранит сообщение об ошибке. Хотя иногда эти сообщения об ошибках не приводят к прекращению выполнения программы, в большинстве случаев нам необходимо отреагировать на ошибку, например, сгенерировав исключение и выпрыгнув из функции обратного вызова. Это также наиболее распространенная практика обратного вызова в Node.

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

Теперь проведем тест. Здесь мы добавляем абзац в конец приведенного выше кода, и что произойдет?

var fs = require("fs");  

var options = { encoding: "utf-8" };                      
fs.readFile("myfile.txt", options, function(err, data) {  
  if (err) {                                
    console.error("Error reading file!");   
    return;                                 
  }                                        

  console.log(data.match(/x/gi).length + " letter X's");  
});

console.log("Hello World!");

Асинхронная операция выполняется при чтении асинхронного файла, поэтому первое, что здесь печатается, это «Hello world!», а затем операция печати в асинхронной функции.

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

Примечание. Если вы хотите узнать больше об асинхронности JavaScript, вы можете проверить это на YouTube.видео. Инструкции в видео относятся как к среде Node, так и к среде браузера.

Создание веб-сервисов с помощью Node: модуль http

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

HTTP-модуль Node имеет множество функций (например, отправку сетевых запросов на другие серверы), но мы собираемся использовать одну из них, называемуюhttp.createServerМетоды. Этот метод обрабатывает каждый сетевой запрос через свою функцию обратного вызова и отвечает. В приведенном ниже коде мы устанавливаем все ответы на «hello world» (которые можно сохранить вmyserver.jsсередина).

var http = require("http");           

function requestHandler(request, response) {             
  console.log("In comes a request to: " + request.url);  
  response.end("Hello, world!");                         
}                                                        

var server = http.createServer(requestHandler);  
server.listen(3000);

Приведенный выше код состоит из 4 частей.

Сначала мы импортируем модуль HTTP и сохраняем его в переменной http. Это согласуется с предыдущей операцией модуля URL.

Затем определите функцию обработчика запросовrequestHandler. Почти весь код в руководстве является либо обработчиком запросов, либо обработчиком вызовов. Функция имеет два параметра,requestпредставляет объект запроса, аresponseпредставляет объект ответа.requestсодержит путь URL,user-agentи другая информация. и позвонивresponseМетоды объекта Node упакует ответ и отправит его запрашивающей стороне.

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

Для HTTPS мы можем использовать встроенный модуль HTTPS. Процесс тот же, за исключением того, что вам нужно настроить сертификат SSL. Если вы знаете HTTPS, то перейти с HTTP на HTTPS позже можно за две минуты. Даже если вы не понимаете, не беспокойтесь слишком сильно.

Если вы сохраните код вmyserver.jsи выполнитьnode myserver.jsПоднимитесь, чтобы служить. Итак, на данный момент вы посещаете в своем браузереhttp://localhost:3000, ты увидишь:

02_03
02_03

Возможно, вы также заметили, что консоль терминала выводит некоторую информацию каждый раз, когда вы делаете запрос. Когда вы пытаетесь получить доступ к разным URL-адресам, консоль выводит другую информацию, но ответ всегда «Привет, мир!». Консоль печатает что-то вроде:

02_04
02_04

Обратите внимание, что приведенная выше информация об URL-адресе не содержитlocalhost:3000. Хотя это может показаться нелогичным, верно и обратное. В конце концов, с относительными путями мы можем развертывать приложения Node на любом компьютере без изменений.

Код для разбора URL примерно такой:

function requestHandler(req, res) {
    if (req.url === "/") {
        res.end("Welcome to the homepage!");
    } else if (req.url === "/about") {
        res.end("Welcome to the about page!");
    } else {
        res.end("Error! File not found.");
    }
}

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

##Суммировать
Основное содержание этой статьи:

  • Установка узла
  • Использование модульной системы
  • Знакомство с файлом package.json
  • Установите зависимости модуля третьего места через package.json
  • Концепции асинхронного программирования в Node.
  • Создание простого приложения службы HTTP.

оригинальныйадрес