Доброго времени суток, друзья!
Представляю вашему вниманию подборку из десяти популярных npm-пакетов с примерами их использования и альтернативными решениями.
Предполагается, что вы хорошо знакомы с JavaScript и, в частности, с Node.js.
В данном части представлены следующие пакеты:
Еженедельные загрузки: 58 млн.
Назначение: форматирование сообщений, выводимых в терминал.
Пример использования.
Устанавливаем пакет: yarn add chalk или npm i chalk.
Создаем файл chalk.js:
Запускаем скрипт: node chalk.js.
Альтернатива: обратные последовательности (escape sequences):
Еженедельные загрузки: 13 млн.
Назначение: «терминальный» индикатор прогресса (ASCII-символы).
Пример использования.
Устанавливаем пакет: yarn add progress.
Создаем файл progress.js:
Запускаем скрипт: node progress.js
One more example:
Еженедельные загрузки: 35 млн.
Назначение: разбор аргументов, передаваемых через терминал.
Пример использования.
Устанавливаем пакет: yarn add minimist.
Создаем файл minimist.js:
Запускаем скрипт: node script.js foo bar baz -x 1 -y2 --z=3 -a
Еженедельные загрузки: 32 млн.
Назначение: дополнительные методы по работе с файловой системой (расширение fs).
Основные методы:
Приведенные методы являются асинхронными, существуют их синхронные аналоги (с приставкой «Sync»).
Методы могут использоваться с функциями обратного вызова, промисами и async/await. Я буду использовать промисы.
Еженедельные загрузки: 36 млн.
Назначение: генерация уникального идентификатора.
Пример использования.
Создадим сервер с помощью express, возвращающий идентификатор по запросу клиента.
Устанавливаем uuid, express и cors: yarn add uuid express cors.
Создаем файл uuid.js:
Запускаем сервер: node uuid.js.
Создаем файл index.html:
Открываем index.html в браузере.
В качестве альтернативы в простых приложениях можно использовать метод «Date.now()», возвращающий количество миллисекунд, прошедших с 1 января 1970 года:
Еженедельные загрузки: 14 млн.
Назначение: форматирование даты и времени.
Пример использования.
Альтернатива: конструкторы Date и Intl.DateTimeFormat.
Разработка moment в настоящее время прекращена.
Еженедельные загрузки: 12 млн.
Назначение: отправка HTTP-запросов. Работает как в Node.js, так и в браузере.
Пример использования.
Устанавливаем пакет: yarn add axios.
Создаем файл axios.js:
Запускаем файл: node axios.js.
Реализация GET-запроса на «чистом» Node.js:
В браузере можно использовать Fetch API:
В сети можно встретить упоминание другого пакета для отправки HTTP-запросов — request, однако в настоящее время он признан устаревшим.
Еженедельные загрузки: 31 млн.
Назначение: утилита для работы с асинхронным кодом. Работает как в Node.js, так и в браузере.
Пример использования.
Устанавливаем пакет: yarn add async.
Создаем 3 файла (название -> контент): file1.txt -> foo, file2.txt -> bar, file3.txt -> baz qux.
Создаем файл async.js:
Еженедельные загрузки: 12 млн.
Назначение: загрузка переменных окружения из файла ".env" в process.env.
Пример использования.
Имитируем подключение к MongoDB Cloud.
Устанавливаем пакет: yarn add dotenv.
Создаем файл ".env":
Создаем файл «dotenv.js»:
В качестве альтернативы можно использовать config.
Устанавливаем пакет: yarn add config.
Создаем файл config.json:
Создаем файл config.js:
Еженедельные загрузки: 4 млн.
Назначение: библиотека для валидации и обезвреживания данных, передаваемых в виде строк.
Пример использования.
Реализуем отправку формы и валидацию данных на сервере.
Устанавливаем пакет: yarn add validator.
Создаем файл index.html:
Создаем файл validator.js:
Запускаем сервер: node validator.js.
Открываем index.html и отправляем данные.
Получаем сообщение о том, что адрес электронной почты и номер кредитной карты невалидны.
Изменим значения email и card на myemail@example.com и 2222111111111111, соответственно.
Нажимаем «Send».
Получаем сообщение об успешной валидации данных.
На сегодня это все. Надеюсь, вы нашли для себя что-то полезное. Благодарю за внимание.
Представляю вашему вниманию подборку из десяти популярных 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».
Получаем сообщение об успешной валидации данных.
На сегодня это все. Надеюсь, вы нашли для себя что-то полезное. Благодарю за внимание.
empenoso
А для гугл таблиц есть варианты?