Представляю вашему вниманию подборку из десяти популярных npm-пакетов с примерами их использования и альтернативными решениями.
Предполагается, что вы хорошо знакомы с JavaScript и, в частности, с Node.js.
В данном части представлены следующие пакеты:
chalk
Еженедельные загрузки: 58 млн.
Назначение: форматирование сообщений, выводимых в терминал.
Пример использования.
Устанавливаем пакет: yarn add chalk или npm i chalk.
Создаем файл chalk.js:
const chalk = require("chalk"); const log = console.log; log( chalk.red("Строка красного цвета\n") + chalk.green("Строка зеленого цвета\n") + chalk.blue("Строка синего цвета") ); // шаблонные литералы const os = require("os"); log(` Total memory: ${chalk.blue(os.totalmem())} bytes Free memory: ${chalk.green(os.freemem())} bytes Memory used: ${chalk.red(os.totalmem() - os.freemem())} bytes `); // тегированные шаблонные литералы const v8 = require("v8"); const { total_heap_size: total, used_heap_size: used, heap_size_limit: limit, } = v8.getHeapStatistics(); log(chalk` Heap Size Limit: {rgb(0, 0, 255) ${limit}} Total Heap Size: {hex('#008000') ${total}} Used Heap Size: {red ${used}} `);
Запускаем скрипт: node chalk.js.

Альтернатива: обратные последовательности (escape sequences):
console.log( "[31m%s[0m[32m%s[0m[34m%s[0m", "Строка красного цвета\n", "Строка зеленого цвета\n", "Строка синего цвета" );
progress
Еженедельные загрузки: 13 млн.
Назначение: «терминальный» индикатор прогресса (ASCII-символы).
Пример использования.
Устанавливаем пакет: yarn add progress.
Создаем файл progress.js:
const ProgressBar = require("progress"); const bar = new ProgressBar(":bar", { total: 10 }); const timer = setInterval(() => { bar.tick(); if (bar.complete) { console.log("\nПотрачено"); clearInterval(timer); } }, 200);
Запускаем скрипт: node progress.js

One more example:
const ProgressBar = require("progress"); const https = require("https"); const req = https.request({ host: "example.com", port: 443, path: "/filename.ext", }); req.on("response", (res) => { const len = parseInt(res.headers["content-length"], 10); console.log(); const bar = new ProgressBar( " загрузка [:bar] :rate/bps :percent :etas", { complete: "=", incomplete: " ", width: 20, total: len, } ); res.on("data", (chunk) => { bar.tick(chunk.length); }); res.on("end", () => { console.log("\nПотрачено"); }); }); req.end();
minimist
Еженедельные загрузки: 35 млн.
Назначение: разбор аргументов, передаваемых через терминал.
Пример использования.
Устанавливаем пакет: yarn add minimist.
Создаем файл minimist.js:
const args = require("minimist")(process.argv.slice(2)); console.log(args); console.log(args._); console.log(args.a);
Запускаем скрипт: node script.js foo bar baz -x 1 -y2 —z=3 -a

fs-extra
Еженедельные загрузки: 32 млн.
Назначение: дополнительные методы по работе с файловой системой (расширение fs).
Основные методы:
- copy — копирование файлов
- emptyDir — очистка директории. Если директории не существует, она создается
- ensureFile — определение наличия файла. Если выполняется запрос на создание файла в директориях, которых не существует, они создаются
- ensureDir — тоже самое применительно к директории. Алиасы — mkdirs, mkdirp
- move — перемещение файла или директории
- outputFile — аналогично fs.writeFile, за исключением того, что при отсутствии создается родительская директория
- outputJson — аналогично fs.writeJson, за исключением того, что при отсутствии создается родительская директория
- readJson — чтение JSON-файла и его преобразование в объект
- remove — удаление файла или директории
- writeJson — запись объекта в JSON-файл
Приведенные методы являются асинхронными, существуют их синхронные аналоги (с приставкой «Sync»).
Методы могут использоваться с функциями обратного вызова, промисами и async/await. Я буду использовать промисы.
const fs = require("fs-extra"); // copy fs.copy("/old-file", "/dir/new-file") .then(() => { console.log("получилось!"); }) .catch((err) => { console.error(err); }); // emptyDir fs.emptyDir("/some/empty/dir") .then(() => { console.log("получилось!"); }) .catch((err) => { console.error(err); }); // ensureFile const file = "/this/path/does/not/exist/file.txt"; fs.ensureFile(file) .then(() => { console.log("получилось!"); }) .catch((err) => { console.error(err); }); // move const src = "/dir/file.txt"; const dest = "/dir/this/path/does/not/exist/file.txt"; fs.move(src, dest) .then(() => { console.log("получилось!"); }) .catch((err) => { console.error(err); }); // outputFile const file = "/this/path/does/not/exist/file.txt"; fs.outputFile(file, "привет!") .then(() => fs.readFile(file, "utf8")) .then((data) => { console.log(data); // => привет! }) .catch((err) => { console.error(err); }); // readJson fs.readJson("/data.json") .then((obj) => { console.log(obj.someKey); // => some value }) .catch((err) => { console.error(err); }); // remove fs.remove("/dir/file") .then(() => { console.log("получилось!"); }) .catch((err) => { console.error(err); }); // writeJson fs.writeJson("/data.json", { someKey: "some value" }) .then(() => { console.log("получилось!"); }) .catch((err) => { console.error(err); });
uuid
Еженедельные загрузки: 36 млн.
Назначение: генерация уникального идентификатора.
Пример использования.
Создадим сервер с помощью express, возвращающий идентификатор по запросу клиента.
Устанавливаем uuid, express и cors: yarn add uuid express cors.
Создаем файл uuid.js:
const express = require("express"); const cors = require("cors"); const { v4: uuidv4 } = require("uuid"); const app = express(); app.use(cors()); app.use("/getId", (_, res) => { // генерируем идентификатор const id = uuidv4(); // отправляем его клиенту res.json(id); }); app.listen(process.env.PORT || 3000, () => console.log("server ready"));
Запускаем сервер: node uuid.js.
Создаем файл index.html:
<body> <input type="text" /> <button>add</button> <ul></ul> <script> const button = document.querySelector("button"); const input = document.querySelector("input"); const list = document.querySelector("ul"); button.addEventListener("click", async () => { // запрашиваем идентификатор const res = await fetch("http://localhost:3000/getId"); const id = await res.json(); const value = input.value; if (value.trim() !== "") { list.insertAdjacentHTML( "beforeend", // используем идентификатор `<li data-id=${id}>${value}</li>` ); } }); input.value = "аптека, улица, фонарь..."; button.click(); </script> </body>
Открываем index.html в браузере.

В качестве альтернативы в простых приложениях можно использовать метод «Date.now()», возвращающий количество миллисекунд, прошедших с 1 января 1970 года:
const id1 = Date.now(); console.log(id1); // 1601905165758 console.log(typeof id1); // number const id2 = Date.now().toString().slice(-4); console.log(id2); // 5758
moment
Еженедельные загрузки: 14 млн.
Назначение: форматирование даты и времени.
Пример использования.
const moment = require("moment"); console.log( ` ${moment().format()} ${moment().format("DD.MM.YYYY H:m")} ` ); /* 2020-10-05T19:16:38+05:00 05.10.2020 19:16 */ moment.locale("ru"); console.log(moment().format("dddd, Do MMMM Y")); // понедельник, 5-го октября 2020
Альтернатива: конструкторы Date и Intl.DateTimeFormat.
const date = new Date(); const options = { day: "numeric", month: "long", year: "numeric", }; console.log(date.toLocaleString("ru", options)); // 5 октября 2020 г. options.weekday = "long"; options.hour = "numeric"; options.minute = "numeric"; console.log( new Intl.DateTimeFormat("ru", options).format(date) ); // понедельник, 5 октября 2020 г., 19:42
Разработка moment в настоящее время прекращена.
axios
Еженедельные загрузки: 12 млн.
Назначение: отправка HTTP-запросов. Работает как в Node.js, так и в браузере.
Пример использования.
Устанавливаем пакет: yarn add axios.
Создаем файл axios.js:
// GET const axios = require("axios"); (async () => { try { const res = await axios.get( "https://jsonplaceholder.typicode.com/users" ); console.table(res.data); } catch (er) { console.error(er); } })();
Запускаем файл: node axios.js.

// POST axios .post("/user", { firstName: "Harry", lastName: "Heman", }) .then((res) => { console.log(res); }) .catch((er) => { console.error(er); });
Реализация GET-запроса на «чистом» Node.js:
const https = require("https"); https .get("https://jsonplaceholder.typicode.com/users", (res) => { let data = ""; res.on("data", (chunk) => { data += chunk; }); res.on("end", () => { console.table(JSON.parse(data)); }); }) .on("error", (er) => { console.error(er.message); });
В браузере можно использовать Fetch API:
;(async () => { await fetch("http://example.com/user", { method: "POST", mode: "no-cors", body: JSON.stringify({ firstName: "Harry", lastName: "Heman", }), }); })();
В сети можно встретить упоминание другого пакета для отправки HTTP-запросов — request, однако в настоящее время он признан устаревшим.
async
Еженедельные загрузки: 31 млн.
Назначение: утилита для работы с асинхронным кодом. Работает как в Node.js, так и в браузере.
Пример использования.
Устанавливаем пакет: yarn add async.
Создаем 3 файла (название -> контент): file1.txt -> foo, file2.txt -> bar, file3.txt -> baz qux.
Создаем файл async.js:
const async = require("async"); const fs = require("fs"); const ext = "txt"; const file = (name) => `${__dirname}/${name}.${ext}`; // определяем размеры файлов async.map( [file("file1"), file("file2"), file("file3")], fs.stat, (er, results) => { if (er) console.error(er); console.log(results.map((item) => item.size)); } ); // [ 3, 3, 7 ] // определяем содержимое файлов async.map( [file("file1"), file("file2"), file("file3")], fs.readFile, (er, results) => { if (er) console.error(er); console.log(results.map((item) => item.toString())); } ); // [ 'foo', 'bar', 'baz qux' ] // параллельное выполнение асинхронных функций const timer1 = () => setTimeout(() => console.log("foo"), 300); const timer2 = () => setTimeout(() => console.log("bar"), 100); const timer3 = () => setTimeout(() => console.log("baz"), 200); const asyncFuntions = [timer1, timer2, timer3]; async.parallel(asyncFuntions, (er, res) => { console.log(res); }); // bar baz foo // выполнение последней асинхронной функции async.series(asyncFuntions, (_, res) => console.log(res)); // foo // композиция из асинхронных функций const add1 = (n, cb) => setTimeout(() => cb(null, n + 1), 100); const sub2 = (n, cb) => setTimeout(() => cb(null, n - 2), 200); const mult3 = (n, cb) => setTimeout(() => cb(null, n * 3), 300); const composed = async.compose(add1, sub2, mult3); // mult3 -> sub2 -> add1 composed(4, (_, res) => console.log(res)); // 11
dotenv
Еженедельные загрузки: 12 млн.
Назначение: загрузка переменных окружения из файла ".env" в process.env.
Пример использования.
Имитируем подключение к MongoDB Cloud.
Устанавливаем пакет: yarn add dotenv.
Создаем файл ".env":
// <usename>, <password> и <dbname> подлежат замене MONGODB=mongodb+srv://<username>:<password>@cluster0.p7jbn.mongodb.net/<dbname>?retryWrites=true&w=majority
Создаем файл «dotenv.js»:
// подключаем dotenv require("dotenv/config"); // подключаем mongoose const mongoose = require("mongoose"); // process.env.MONGODB - загрузка переменной "MONGODB" из файла ".env" mongoose.connect(process.env.MONGODB, { useNewUrlParser: true, useUnifiedTopology: true, });
В качестве альтернативы можно использовать config.
Устанавливаем пакет: yarn add config.
Создаем файл config.json:
{ "mongoDB": "mongodb+srv://<username>:<password>@cluster0.p7jbn.mongodb.net/<dbname>?retryWrites=true&w=majority" }
Создаем файл config.js:
// подключаем config const config = require("config"); // подключаем mongoose const mongoose = require("mongoose"); // config.get("mongoDB") - получение значения свойства "mongoDB" объекта "config" из файла "config.json" mongoose.connect(config.get("mongoDB"), { useNewUrlParser: true, useUnifiedTopology: true, }, () => console.log("Connected to database"));
validator
Еженедельные загрузки: 4 млн.
Назначение: библиотека для валидации и обезвреживания данных, передаваемых в виде строк.
Пример использования.
Реализуем отправку формы и валидацию данных на сервере.
Устанавливаем пакет: yarn add validator.
Создаем файл index.html:
<head> <title>Form Validation</title> <style> label, span { display: block; margin: .5rem; } </style> </head> <body> <form> <label>Name: <input type="text" value="Igor" data-name="name" /></label> <label>Age: <input type="number" value="30" data-name="age" /></label> <label >Email: <input type="email" value="myemail.example.com" data-name="email" /></label> <label >Site: <input type="url" value="myblog.org" data-name="url" /></label> <label >Card: <input type="text" value="1111222233334444" data-name="card" /></label> <button>Send</button> <p></p> </form> <script> const form = document.querySelector("form"); // кнопка для отправки формы const btn = form.querySelector("button"); // контейнер для вывода сообщения const log = form.querySelector("p"); // вспомогательная функция для получения значения указанного инпута const getValue = (name) => form.querySelector(`[data-name=${name}]`).value; btn.addEventListener("click", (e) => { e.preventDefault(); // формируем данные для отправки const data = { name: getValue("name"), age: getValue("age"), email: getValue("email"), url: getValue("url"), card: getValue("card"), }; // функция отправки данных const sendData = async (url) => { const req = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }); // ответ от сервера в виде массива const res = await req.json(); console.log(res); // вывод сообщения о результате if (res.length !== 0) { let html = ""; for (const msg of res) { html += `<span>${msg}</span>`; log.innerHTML = html; } } else { log.textContent = 'Success' } }; sendData("http://localhost:3000/users"); }); </script>
Создаем файл validator.js:
const express = require("express"); const cors = require("cors"); // извлекаем функции, необходимые для валидации // escape - функция обезвреживания данных const { isAlpha, isNumeric, isEmail, isURL, isCreditCard, escape, } = require("validator"); // собираем валидаторы в массив const validators = [isAlpha, isNumeric, isEmail, isURL, isCreditCard]; const app = express(); app.use(cors()); app.use(express.json()); // обрабатываем получение данных app.use("/users", (req, res) => { // извлекаем необходимые данные const data = ({ name, age, email, url, card } = req.body); console.log(data); // массив с ошибками const errors = []; // проводим валидацию for (let i = 0; i < validators.length; i++) { // обезвреживаем данные escape(Object.values(data)[i]); // если данные не прошли валидацию // добавляем соответствующее сообщение в массив с ошибками if (!validators[i](Object.values(data)[i])) { errors.push(`Wrong ${Object.keys(data)[i]}`); } } console.log(errors); // отправляем ошибки клиенту res.json(errors); }); app.listen(process.env.PORT || 3000, () => console.log("Server ready"));
Запускаем сервер: node validator.js.
Открываем index.html и отправляем данные.


Получаем сообщение о том, что адрес электронной почты и номер кредитной карты невалидны.
Изменим значения email и card на myemail@example.com и 2222111111111111, соответственно.
Нажимаем «Send».


Получаем сообщение об успешной валидации данных.
На сегодня это все. Надеюсь, вы нашли для себя что-то полезное. Благодарю за внимание.
ссылка на оригинал статьи https://habr.com/ru/post/522700/
Добавить комментарий