Популярные npm-пакеты. Volume 1

от автора

Доброго времени суток, друзья!

Представляю вашему вниманию подборку из десяти популярных 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *