<!DOCTYPE html>
<html class="h-100" data-bs-theme="light" data-mantine-color-scheme="light" lang="ru" prefix="og: https://ogp.me/ns#">
<head>
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<link crossorigin="true" href="https://cdn.hexlet.io" rel="preconnect">
<link href="https://mc.yandex.ru" rel="preconnect">
<meta content="aa2vrdtq64dub8knuf83lwywit311w" name="facebook-domain-verification">
<link href="/favicon.ico" rel="icon" sizes="any">
<link href="/favicon.svg" rel="icon" type="image/svg+xml">
<link href="/apple-touch-icon.png" rel="apple-touch-icon">
<link href="/manifest.webmanifest" rel="manifest">
<script>
//<![CDATA[
window.gon={};gon.ym_counter="25559621";gon.is_bot=true;gon.applications={};gon.current_user={"id":null,"last_viewed_notification_id":null,"email":null,"state":null,"first_name":"","last_name":"","created_at":"2026-02-26 17:11:12 UTC","current_program":null,"current_team":null,"full_name":"","guest":true,"can_use_paid_features":false,"is_hexlet_employee":false,"sanitized_phone_number":"","can_subscribe":true,"can_renew_education":false};gon.token="6khjNXTWfdrdYp4rKYRFi1dkLUzKLoodqfcQNhvNFWoFmagChqjQumshurMli7X8l20A5sIZdL8UF4piScryBA";gon.locale="ru";gon.language="ru";gon.theme="light";gon.rails_env="production";gon.mobile=false;gon.google={"analytics_key":"UA-1360700-51","optimize_key":"GTM-5QDVFPF"};gon.captcha={"google_v3_site_key":"6LenGbgZAAAAAM7HbrDbn5JlizCSzPcS767c9vaY","yandex_site_key":"ysc1_Vyob5ZPPUdPBsu0ykt8bVFdzsfpoVjQChLGl2b4g19647a89","verification_failed":null};gon.social_signin=false;gon.typoreporter_google_form_id="1FAIpQLSeibfGq-KvWQ2Fyru-zkFFRVTLBuzXAHAoEyN1p49FtDmNoNA";
//]]>
</script>
<meta charset="utf-8">
<title>Зависимости для разработки | JS: Настройка окружения</title>
<meta name="description" content="Зависимости для разработки / JS: Настройка окружения: Изучаем среды разработки и знакомимся с разными типами зависимостей">
<link rel="canonical" href="https://ru.hexlet.io/courses/js-setup-environment/lessons/dev-dependencies/theory_unit">
<meta name="robots" content="noarchive">
<meta property="og:title" content="Зависимости для разработки">
<meta property="og:title" content="JS: Настройка окружения">
<meta property="og:description" content="Зависимости для разработки / JS: Настройка окружения: Изучаем среды разработки и знакомимся с разными типами зависимостей">
<meta property="og:url" content="https://ru.hexlet.io/courses/js-setup-environment/lessons/dev-dependencies/theory_unit">
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="EMG0i1eDBMI8v2VHdJf0B5Yg7Mb8ENZdu1UR0HA1wrn_EH-8pf2poor8Qd94mARwVinBbPQnKP8GtYuEIjIl1w" />
<script src="/vite/assets/inertia-INZxX8jp.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/preload-helper-BJ4cLWpC.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/init-nkZBEvfU.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ahoy-DrlRQ-1D.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/analytics-6pOtQ3OW.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ErrorFallbackBlock-naDSYSy9.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Surface-DL2bpZA-.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/gon-D3e4yh1x.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/mantine-CGMYrt2Y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/utils-DRqSHbQE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/extends-C-EagtpE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/inheritsLoose-BBd-DCVI.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/objectWithoutPropertiesLoose-DRHXDhjp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/index.esm-DAqKOkZ0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Button-CGPUux8l.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/CloseButton-D1euiPao.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Group-BX48WcuU.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Loader-BQEY8g6v.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Modal-Cy3HByv7.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/OptionalPortal-1Hza5P2w.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Stack-CtjJzfw4.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Textarea-Ck64llAy.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Box-B5-OOzBf.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/DirectionProvider-Dc9zdUke.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/events-DJQOhap0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-reduced-motion-D2owz4wa.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-disclosure-zKtK5W1r.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-hotkeys-Cnc_Rwkb.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/random-id-DOQyszCZ.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/notifications.store-C-3AFSMn.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/exports-C_MrNx_T.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/axios-BEvgo0ym.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dayjs.min-BkKovM-s.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/i18next-BlSq9s7B.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/client-U9M77rxp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-dom-DaLxUz_h.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useTranslation-Bx1Cdrkz.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/compiler-runtime-6XxiPFnt.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/jsx-runtime-CwjcCKJi.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-CkL4ZRHB.js" as="script" crossorigin="anonymous">
<link rel="stylesheet" href="/vite/assets/application-BqhCP46M.js" />
<script src="/vite/assets/application-Df9RExpe.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/autocomplete-VMNbxKGl.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/createPopper-C3aM9r1M.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/js.cookie-D1-O8zkX.js" as="script" crossorigin="anonymous"><link rel="stylesheet" href="/vite/assets/application-C8HjmMaq.css" media="screen" />
<script>
window.ym = function(){(ym.a=ym.a||[]).push(arguments)};
window.addEventListener('load', function() {
setTimeout(function() {
ym.l = 1*new Date();
ym(window.gon.ym_counter, "init", {
clickmap: true,
trackLinks: true,
accurateTrackBounce: true,
webvisor: true
});
// Загружаем скрипт
var k = document.createElement('script');
k.async = 1;
k.src = 'https://mc.yandex.ru/metrika/tag.js';
document.head.appendChild(k);
ym(window.gon.ym_counter, 'getClientID', function(clientID) {
window.ymClientId = clientID;
});
}, 1500);
});
</script>
<!-- Google Tag Manager - deferred -->
<script>
// dataLayer stub сразу — пуши работают до загрузки скрипта
window.dataLayer = window.dataLayer || [];
// Сам скрипт — отложенно после load
window.addEventListener('load', function() {
setTimeout(function() {
dataLayer.push({'gtm.start': new Date().getTime(), event: 'gtm.js'});
var j = document.createElement('script');
j.async = true;
j.src = 'https://www.googletagmanager.com/gtm.js?id=GTM-WK88TH';
document.head.appendChild(j);
}, 1500);
});
</script>
<!-- End Google Tag Manager -->
</head>
<body>
<noscript>
<div>
<img alt="" src="https://mc.yandex.ru/watch/25559621" style="position:absolute; left:-9999px;">
</div>
</noscript>
<header class="sticky-top bg-body">
<nav class="navbar navbar-expand-lg">
<div class="container-xxl">
<a class="navbar-brand" href="/"><img alt="Логотип Хекслета" height="24" src="https://ru.hexlet.io/vite/assets/logo_ru_light-BpiEA1LT.svg" width="96">
</a><button aria-controls="collapsable" aria-expanded="false" aria-label="Меню" class="navbar-toggler border-0 mb-0 mt-1" data-bs-target="#collapsable" data-bs-toggle="collapse">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsable">
<ul class="navbar-nav mb-lg-0 mt-lg-1">
<li class="nav-item dropdown">
<button aria-haspopup class="btn nav-link" data-bs-toggle="dropdown" type="button">
Все курсы
<span class="bi bi-chevron-down align-middle ms-1"></span>
</button>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item d-flex py-2" href="/courses"><div class="fw-bold me-auto">Все что есть</div>
<div class="text-muted">117</div>
</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li class="dropdown-item">
<b>Популярные категории</b>
</li>
<li>
<a class="dropdown-item py-2" href="/courses_devops">Курсы по DevOps
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_data_analytics">Курсы по аналитике данных
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_programming">Курсы по программированию
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_testing">Курсы по тестированию
</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li class="dropdown-item">
<b>Популярные курсы</b>
</li>
<li>
<a class="dropdown-item py-2" href="/programs/devops-engineer-from-scratch">DevOps-инженер с нуля
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/go">Go-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/java">Java-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/python">Python-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/qa-auto-engineer-java">Автоматизатор тестирования на Java
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/data-analytics">Аналитик данных
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/frontend">Фронтенд-разработчик
</a></li>
</ul>
</li>
<li class="nav-item dropdown">
<button aria-haspopup class="btn nav-link" data-bs-toggle="dropdown" type="button">
О Хекслете
<span class="bi bi-chevron-down align-middle"></span>
</button>
<ul class="dropdown-menu bg-body">
<li>
<a class="dropdown-item py-2" href="/pages/about">О нас
</a></li>
<li>
<a class="dropdown-item py-2" href="/blog">Блог
</a></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/hse-research" role="button">Результаты (Исследование)
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://career.hexlet.io" role="button">Хекслет Карьера
</span></li>
<li>
<a class="dropdown-item py-2" href="/testimonials">Отзывы студентов
</a></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://t.me/hexlet_help_bot" role="button">Поддержка (В ТГ)
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/referal-program/?promo_creative=priglasite-druzei&promo_name=referal-program&promo_position=promo_position&promo_start=010724&promo_type=link" role="button">Реферальная программа
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/certificate" role="button">Подарочные сертификаты
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://hh.ru/employer/4307094" role="button">Вакансии
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://b2b.hexlet.io" data-target="_blank" role="button">Компаниям
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://hexly.ru/" data-target="_blank" role="button">Колледж
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://hexlyschool.ru/" data-target="_blank" role="button">Частная школа
</span></li>
</ul>
</li>
<li><a class="nav-link" href="/subscription/new">Подписка</a></li>
</ul>
<ul class="navbar-nav flex-lg-row align-items-lg-center gap-2 ms-auto">
<li>
<a class="nav-link" aria-label="Переключить тему" href="/theme/switch?new_theme=dark"><span aria-hidden="true" class="bi bi-moon"></span>
</a></li>
<li>
<span data-target="_self" class="nav-link external-link" data-href="/u/new" role="button"><span>Регистрация</span>
</span></li>
<li>
<span data-target="_self" class="nav-link external-link" data-href="https://ru.hexlet.io/session/new" role="button"><span>Вход</span>
</span></li>
</ul>
</div>
</div>
</nav>
</header>
<div class="x-container-xxxl">
</div>
<main class="mb-6 min-vh-100 h-100">
<link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzcyNywicHVyIjoiYmxvYl9pZCJ9fQ==--2d5cbbf5c3b4a73ae4b2c50632305d78f5872e4d/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Programmer-rafiki.png"/><link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzcyNSwicHVyIjoiYmxvYl9pZCJ9fQ==--2e84f5f94140ee4e22019ac479c290ef48c3fac8/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Static%20website-cuate.png"/><link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDAzNCwicHVyIjoiYmxvYl9pZCJ9fQ==--ba516ea9573bdfcd1d21e2aa0fff8818561828f2/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Typing-bro.png"/><link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDA0MCwicHVyIjoiYmxvYl9pZCJ9fQ==--137ae65fe79f41b3d5270b8a3b65b38b1621c65b/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Code%20typing-bro.png"/><link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDA0MywicHVyIjoiYmxvYl9pZCJ9fQ==--e2c6c0775e2308e42fbc5dc592ba2db0470632ca/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Programmer-rafiki.png"/><link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzk0MSwicHVyIjoiYmxvYl9pZCJ9fQ==--9a9cd0863661374e7c92ea27b1270ac3299c0979/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Usability%20testing-pana.png"/><link rel="preload" as="image" href="/vite/assets/development-BVihs_d5.png"/><div id="app" data-page="{"component":"web/courses/lessons/theory_unit","props":{"errors":{},"locale":"ru","language":"ru","httpsHost":"https://ru.hexlet.io","host":"ru.hexlet.io","colorScheme":"light","auth":{"user":{"id":null,"last_viewed_notification_id":null,"email":null,"state":null,"first_name":"","last_name":"","created_at":"2026-02-26T17:11:12.099Z","current_program":null,"current_team":null,"full_name":"","guest":true,"can_use_paid_features":false,"is_hexlet_employee":false,"sanitized_phone_number":"","can_subscribe":true,"can_renew_education":false}},"cloudflareTurnstileSiteKey":"0x4AAAAAAA15KmeFXzd2H0Xo","vkIdClientId":"51586979","yandexIdClientId":"88d071f1d3384eb4bd1deb37910235c7","formAuthToken":"ROu4tNQ7opH4bnLGOvtwYLn2k8PbBHafiummktujESOrOnODJkUP8U4tVl429IAXef--adMziD03CTzGiaT2TQ","topics":[{"id":50088,"title":"Здравствуйте! Не могу в задании запустить код bin/nodejs-package.js 10. Не пойму - 10 это что?\nвыдает ошибку \n\n/home/aleksey/hexlet-js/nodejs-package/bin/nodejs-package.js:3\nimport half from '../index.js';\n ^^^^\n\nSyntaxError: Unexpected identifier\n at Module._compile (internal/modules/cjs/loader.js:723:23)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)\n at Module.load (internal/modules/cjs/loader.js:653:32)\n at tryModuleLoad (internal/modules/cjs/loader.js:593:12)\n at Function.Module._load (internal/modules/cjs/loader.js:585:3)\n at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)\n at startup (internal/bootstrap/node.js:283:19)\n at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)\n","plain_title":"Здравствуйте! Немогу в задании заупстить код bin/nodejs-package.js 10. Не поймуб 10 это что? выдает ошибку /home/aleksey/hexlet-js/nodejs-package/bin/nodejs-package.js:3 import half from '../index.js'; ^^^^ SyntaxError: Unexpected identifier at Module.compile (internal/modules/cjs/loader.js:723:23) at Object.Module.extensions..js (internal/modules/cjs/loader.js:789:10) at Module.load (internal/modules/cjs/loader.js:653:32) at tryModuleLoad (internal/modules/cjs/loader.js:593:12) at Function.Module._load (internal/modules/cjs/loader.js:585:3) at Function.Module.runMain (internal/modules/cjs/loader.js:831:12) at startup (internal/bootstrap/node.js:283:19) at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3) ","creator":{"public_name":"Алексей Дяченко","id":310766,"is_tutor":false},"comments":[{"creator":{"public_name":"Алексей Дяченко","id":310766,"is_tutor":false},"id":107332,"body":"Решил попробовать все заново, теперь выдает вот это -\n\ninternal/modules/cjs/loader.js:638\n throw err;\n ^\nError: Cannot find module '/home/aleksey/nodejs-package/bin/nodejs-packaeg.js'\n at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)\n at Function.Module._load (internal/modules/cjs/loader.js:562:25)\n","topic_id":50088}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Зависимости для разработки","entity_url":null,"active":true}},{"id":60100,"title":"Добрый день! Верно ли я поняла, что для установки зависимостей в самостоятельной работе нужно использовать npm ci т.к. мы клонируем существующий проект ? ","plain_title":"Добрый день! Верно ли я поняла, что для установки зависимостей в самостоятельной работе нужно использовать npm ci т.к. мы клонируем существующий проект ? ","creator":{"public_name":"Marina Zinchenko","id":176140,"is_tutor":false},"comments":[{"creator":{"public_name":"Maksim Litvinov","id":198906,"is_tutor":true},"id":126945,"body":"Добрый день, Марина! Да, вы все верно поняли","topic_id":60100}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Зависимости для разработки","entity_url":null,"active":true}},{"id":48827,"title":"Здравствуйте! Что-то у меня тупик. Когда запускаю `npm test`, то выводится в консоль следующее\n\n```\nDetails:\n\n /home/maksim/Programming/Hexlet/Practice/nodejs-package/__tests__/half.test.js:1\n import { test, expect } from '@jest/globals';\n ^^^^^^\n\n SyntaxError: Cannot use import statement outside a module\n\n at compileFunction (node:vm:355:18)\n```\n\n ОС - Ubuntu, запускаю в корне проекта, Node 15.0.1\n\nЧто это может быть?","plain_title":"Здравствуйте! Что-то у меня тупик. Когда запускаю npm test, то выводится в консоль следующее Details: /home/maksim/Programming/Hexlet/Practice/nodejs-package/__tests__/half.test.js:1 import { test, expect } from '@jest/globals'; ^^^^^^ SyntaxError: Cannot use import statement outside a module at compileFunction (node:vm:355:18) ОС - Ubuntu, запускаю в корне проекта, Node 15.0.1 Что это может быть? ","creator":{"public_name":"Максим Гурьянов","id":206528,"is_tutor":false},"comments":[{"creator":{"public_name":"Stanislav Dzisiak","id":212236,"is_tutor":true},"id":104819,"body":"Для того чтобы работали тесты без babel, необходимо прописать ещё правильную строку запуска. Посмотрите тут https://github.com/hexlet-boilerplates/nodejs-package/blob/master/package.json#L12","topic_id":48827},{"creator":{"public_name":"Максим Гурьянов","id":206528,"is_tutor":false},"id":105495,"body":"Здравствуйте, Станислав! \n\nПодскажите, каким способом Вы запустили тесты на node 15? У меня без \"[танцев](https://hexlet-ru.slack.com/archives/C07H3KRPY/p1604518404293100?thread_ts=1604518404.293100&cid=C07H3KRPY)\" не получилось","topic_id":48827},{"creator":{"public_name":"Di Pen","id":256692,"is_tutor":false},"id":105492,"body":"**Станислав Дзисяк**, Здаров! Помогите, Станислав. У меня та же проблема, вообще не решается...всё перепробовал, все в package.json написано, команда bin/nodejs-package.js 10 работать изнутри директории nodejs-package...находясь в ней npm test не проходит...выхожу из неё в мой hexlet-js пробую, тоже не получается","topic_id":48827},{"creator":{"public_name":"Stanislav Dzisiak","id":212236,"is_tutor":true},"id":105017,"body":"Приветствую, Максим!\n\nВижу версии у вас свежие и с ними всё в порядке. По правде говоря ошибка возникающая у вас, при том что всё правильно выглядит странной. Порекомендую вам склонировать наш [эталонный репозиторий](https://github.com/hexlet-boilerplates/nodejs-package), выполнить в нём установку зависимостей и запустить тесты, чтобы убедиться, что проблема не в исходниках вашего репозитория. Также порекомендую вам присоединиться к нашему сообществу в [slack](https://slack-ru.hexlet.io/), там вы сможете также задавать вопросы связанные с особенностями настройки и использования локального окружения. ","topic_id":48827},{"creator":{"public_name":"Di Pen","id":256692,"is_tutor":false},"id":105498,"body":"**Максим Гурьянов**, Да, ваши решения и смотрел, спасибо, помог! ","topic_id":48827},{"creator":{"public_name":"Максим Гурьянов","id":206528,"is_tutor":false},"id":104936,"body":"Здравствуйте, Станислав! \n\nСделал, как вы сказали, получил следующее:\n\n~$ node -v\n\nv15.0.1\n\n~$ npx -v\n\n7.0.3\n","topic_id":48827},{"creator":{"public_name":"Максим Гурьянов","id":206528,"is_tutor":false},"id":105494,"body":"Добрый день, Adilet Abdurasulov! По крайней мере я их смог запустить одним способом, потом мне подсказали ещё способы. Вот здесь можете почитать подробнее [slack](https://hexlet-ru.slack.com/archives/C07H3KRPY/p1604518404293100?thread_ts=1604518404.293100&cid=C07H3KRPY)","topic_id":48827},{"creator":{"public_name":"Максим Гурьянов","id":206528,"is_tutor":false},"id":104824,"body":"Это тоже прописано, я запускаю тесты именно в проекте nodejs-package, а у него в package.json есть все необходимое, но тесты не запскаются. Никак не пойму, что я делаю не так. ","topic_id":48827},{"creator":{"public_name":"Stanislav Dzisiak","id":212236,"is_tutor":true},"id":104816,"body":"Приветствую, Максим!\n\nЭто связано с тем, что без babel использовать импорты можно, если использовать нативные модули. Порекомендую вам вернутся к уроку \"[NPM](https://ru.hexlet.io/courses/js-setup-environment/lessons/npm/theory_unit)\" и посмотреть в примере package.json на ключ \"type\": \"module\". Также при необходимости вы можете подсматривать примеры в нашем эталонном репозитории https://github.com/hexlet-boilerplates/nodejs-package","topic_id":48827},{"creator":{"public_name":"Максим Гурьянов","id":206528,"is_tutor":false},"id":105043,"body":"Понял, спасибо","topic_id":48827},{"creator":{"public_name":"Di Pen","id":256692,"is_tutor":false},"id":105491,"body":"**Максим Гурьянов**, Здаров! Разобрались с тестом? У меня та же проблема, никак не получается","topic_id":48827},{"creator":{"public_name":"Максим Гурьянов","id":206528,"is_tutor":false},"id":104818,"body":"Загвоздка именно в том, что в package.json есть ключ `\"type\": \"module\"`. Но когда запускаю тесты, то получаю вышеописанный результат. \nЯ склонировал проект nodejs-package, установил зависимости (использовал `npm install` в корне проекта), запустил код на выполнение (получил в консоли число 5), а вот с тестами беда. Что делать не знаю, подскажите, пожалуйста.","topic_id":48827},{"creator":{"public_name":"Максим Гурьянов","id":206528,"is_tutor":false},"id":104832,"body":"Вот ссылка на [гитхаб](https://github.com/Guryanov-Maksim/nodejs-package.git)\n\nБудет прекрасно, если Вы мне поможете, сам пока не могу.","topic_id":48827},{"creator":{"public_name":"Di Pen","id":256692,"is_tutor":false},"id":105497,"body":"\"scripts\": {\n \"test\": \"node --experimental-vm-modules node_modules/.bin/jest\"\n },\n\nпосле этого получилось","topic_id":48827},{"creator":{"public_name":"Stanislav Dzisiak","id":212236,"is_tutor":true},"id":104829,"body":"Максим, что бы подсказать более конкретно в чём у вас проблема, нужно взглянуть на ваши исходники. Можете выложить их на гитхаб, а в сообщение вложите ссылку на ваш репозиторий. Я посмотрю и помогу вам разобраться с вашей проблемой.","topic_id":48827},{"creator":{"public_name":"Максим Гурьянов","id":206528,"is_tutor":false},"id":105499,"body":"**Adilet Abdurasulov**, не за что, рад, что помогло. Мне советовали, и я в свою очередь советую, что для тренировки попробовать запустить тесты через переменные окружения. Однозначно хорошая тренировка!)\n","topic_id":48827},{"creator":{"public_name":"Stanislav Dzisiak","id":212236,"is_tutor":true},"id":104933,"body":"Приветствую, Максим!\n\nЯ проверил ваш проект используя последние версии node 12, 14, 15. Всё работает, в том числе и запуск тестов. Попрошу вас выполнить в консоли несколько команд и убедиться в правильности используемых версий. Выполните `node -v`, `npx -v`. Напишите потом какие результаты вы получили. ","topic_id":48827}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Зависимости для разработки","entity_url":null,"active":true}},{"id":59831,"title":"Вот что было непонятно. \n1) Нужно ли было клонировать в отдельной папке или в той же, что мы делали на предыдущих уроках? В итоге склонировал в hexlet-js с последующей неосознанной установкой всех зависимостей. тесты прошли , пятерку в результате выдало. \n\n2) насколько я понимаю в директории hexlet-js : мы должны вбить npm ci --production? так как имеется файл package-lock.json?\n\n3) далее вы пишите \n\n> Изучите размер и содержимое node_modules, затем удалите её, установите зависимости с флагом --production, и посмотрите новый размер. \n\n удалить node_modules. Зачем? из этого проекта? или из предыдущих уроков?\nа дальше что? просто оставляем у себя на машине склонированный проект? зачем?\nзачем повторно устанавливать зависимость для nodejs-package? или ее устанавливаем себе в hexlet-js? вообще что-нибудь из урока нужно применять в hexlet-js? \n\n\n\n\n\n","plain_title":"Неочевидно было что все эти шаги нужно выполнить вне проекта , который в предыдущих уроках настраивали. В итоге склонировал nodejs-package в директорию hexlet-js установил все зависимости вне проекта nodejs-package непонятно в какой последовательности устанавливать их и как теперь в дальнейшем все перенастроить правильно/ это все моменты , которые из урока непонятны и неочевидны, так как устанавливается паттерн до этого момента , что каждый урок - это действие для настройки окружения предстоящего проекта. в общем, что делать и как быть?) ","creator":{"public_name":"Kh","id":393243,"is_tutor":false},"comments":[{"creator":{"public_name":"Сергей К.","id":5174,"is_tutor":false},"id":126534,"body":"1. Клонировать репозиторий можно в любое место операционной системы. \n2. Запускать команды из задания нужно из директории проекта _nodejs-package_. Он никак не связан с проектом _hexlet-js_ из предыдущих уроков.\n\nЗадача этой самостоятельной работы разобраться, какие зависимости `npm` устанавливает для различных сред разработки.\n","topic_id":59831}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Зависимости для разработки","entity_url":null,"active":true}},{"id":47044,"title":"Здравствуйте! \nРезультат после npm test показывает ошибки: \nnpx: installed 505 in 35.481s\n FAIL __tests__/half.test.js\n ● Test suite failed to run\n\n Details:\n\n /home/nomadkyr/folder_forNode/nodejs-package/__tests__/half.test.js:1\n import { test, expect } from '@jest/globals';\n ^\n\n SyntaxError: Unexpected token {\n\n at Runtime._execModule (../node_modules/jest-runtime/build/index.js:1179:56)\n\nТак и должно быть или нет?\n\n","plain_title":"Здравствуйте! Результат после npm test показывает ошибки: npx: installed 505 in 35.481s FAIL tests/half.test.js ● Test suite failed to run Details: /home/nomadkyr/folder_forNode/nodejs-package/__tests__/half.test.js:1 import { test, expect } from '@jest/globals'; ^ SyntaxError: Unexpected token { at Runtime._execModule (../node_modules/jest-runtime/build/index.js:1179:56) Так и должно быть или нет? ","creator":{"public_name":"Daria Sidorenko","id":271695,"is_tutor":false},"comments":[{"creator":{"public_name":"Daria Sidorenko","id":271695,"is_tutor":false},"id":102131,"body":"**Роман Ашиков**, спасибо, Роман! Ваши ответы всегда понятные и очень поддерживающие! )\n","topic_id":47044},{"creator":{"public_name":"Roman Ashikov","id":226258,"is_tutor":true},"id":102142,"body":"На за что. Пишите, если что. :)","topic_id":47044},{"creator":{"public_name":"Daria Sidorenko","id":271695,"is_tutor":false},"id":101956,"body":"**Роман Ашиков**, нашла решение на англоязычном форуме такое: \n\n```\nasdf plugin-update nodejs\nbash ~/.asdf/plugins/nodejs/bin/import-release-team-keyring\n```\n\nТеперь работает! Тогда другой вопрос. Это нормально, что появляются вопросы, которые нужно вот так гуглить? И должен ли фронтендер знать и понимать, какие изменения он вносит (то есть, понимать, например, вот эту скопированную с форума команду)? Или глубоко понимают только разработчики Node.js, а остальные просто пользуются существующей информацией? ","topic_id":47044},{"creator":{"public_name":"Roman Ashikov","id":226258,"is_tutor":true},"id":101334,"body":"Добрый день, Дарья!\n\nВам нужно обновить nodejs, так как ваша версия не понимает синтаксис импортов без Babel. Для обновления можно воспользоваться менеджером версий asdf. Вот гайд на эту тему — [Что такое \"Менеджер версий\"](https://guides.hexlet.io/version_managers/), там как раз разбирается установка последней версии ноды.","topic_id":47044},{"creator":{"public_name":"Daria Sidorenko","id":271695,"is_tutor":false},"id":101954,"body":"**Роман Ашиков**, спасибо! Внесла изменения в .bashrc, теперь asdf запускается, но последняя нода всё равно не ставится: \n\n```\n~$ asdf install nodejs 14.1\n % Total % Received % Xferd Average Speed Time Time Time Current\n Dload Upload Total Spent Left Speed\n100 10858 0 10858 0 0 24621 0 --:--:-- --:--:-- --:--:-- 24621\nBinaries were not found. Full version must be specified, not just major version.\n```\n\nПолноценную ОС постараюсь поставить, но хотелось бы решить этот вопрос сейчас в Ubuntu - вдруг там как-то просто это сделать). И еще такой вопрос: я уже начала делать первый проект, можно ли его сделать через Ubuntu на Windows или могут возникнуть проблемы? Просто пока не понимаю, будут ли там дальше какие-то сложные взаимодействия с окружением... Или достаточно добиться того, что будет установлена последняя версия ноды? ","topic_id":47044},{"creator":{"public_name":"Daria Sidorenko","id":271695,"is_tutor":false},"id":101895,"body":"У меня Ubuntu, установленная в Win10 через Windows Store.","topic_id":47044},{"creator":{"public_name":"Daria Sidorenko","id":271695,"is_tutor":false},"id":101282,"body":"\"Посмотрите импорты в директориях src и tests\"\nВ директориях файлы half.js и half.test.js, соответственно. Вдруг это важно в данном случае. \n","topic_id":47044},{"creator":{"public_name":"Daria Sidorenko","id":271695,"is_tutor":false},"id":101894,"body":"**Роман Ашиков**, установила asdf, перехожу к команде $ asdf plugin add nodejs и получаю ответ: \n\nCommand 'asdf' not found, did you mean:\n\n command 'asdfg' from deb aoeui (1.7+20160302.git4e5dee9-2)\n command 'adsf' from deb ruby-adsf (1.4.3+dfsg1-1)\n command 'sdf' from deb sdf (2.001+1-7)\n command 'sadf' from deb sysstat (12.2.0-2)\n\nTry: sudo apt install <deb name>\n\nНагуглить решение пока не смогла. Как еще можно nodejs обновить? ","topic_id":47044},{"creator":{"public_name":"Roman Ashikov","id":226258,"is_tutor":true},"id":101911,"body":"Насколько я понял, вы выполнили команду:\n\n git clone https://github.com/asdf-vm/asdf.git ~/.asdf\n\nВ документации asdf в разделе \"установка\" сказано о том, что нужно добавить исполняемый файл в переменную $PATH. О том, как изменить $PATH рассказывается в уроке [Выполнение программ](https://ru.hexlet.io/courses/cli-basics/lessons/execution/theory_unit) в курсе Основы командной строки.\n\nА вот [тут в документации asdf](https://asdf-vm.com/#/core-manage-asdf-vm?id=add-to-your-shell) сказано какие директории нужно добавить в $PATH, чтобы программа корректно запускалась и работало автодополнение. Только не забудьте сделать резервную копию файла ~/.bashrc, на всякий случай. \n\n $ cp ~/.bashrc ~/.bashrc.backup\n\nПодгрузить изменённый _.bashrc_ можно командой:\n\n $ source ~/.bashrc\n\nТаким образом можно не закрывать окно терминала, каждый раз после редактирования файла.\n\nДля более оперативной помощи можно попробовать написать ребятам в нашем Слаке. О том как подключиться можно узнать тут — [Слак Хекслета](https://help.hexlet.io/article/66-slack). В Ubuntu на Windows могут возникнуть неожиданные проблемы. Я бы порекомендовал всё же установить полноценную ОС рядом с Windows или хотя бы на виртуальную машину. ","topic_id":47044},{"creator":{"public_name":"Roman Ashikov","id":226258,"is_tutor":true},"id":101982,"body":"Отлично! Здорово, что получилось решить проблему.\n\nДля решения конкретно этой задачи, не нужно понимать сам Node.js, а нужно уметь работать с инструментом для его обновления и иметь общее представление о устройстве операционной системы (в данном контексте я имею в виду понимание, что такое, например, $PATH в Linux). У asdf, как видите, есть свои особенности.\n\nУметь гуглить и читать документацию должен любой разработчик, не важно фронт или бек. Для того, чтобы настроить окружение даже для разработки фронтенда, не достаточно просто копировать найденные команды, нужно понимать, что вы делаете. Не говоря о том, что бездумное копирование может запросто сломать операционную систему.","topic_id":47044}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Зависимости для разработки","entity_url":null,"active":true}},{"id":47679,"title":"Здравствуйте! Склонировал проект с гитхаба. Попытался установить зависимости командой npm install, появилось данное сообщение:\n```\nnpm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\\fsevents):\nnpm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {\"os\":\"darwin\",\"arch\":\"any\"} (current: {\"os\":\"win32\",\"arch\":\"x64\"})\n\nadded 631 packages from 382 contributors and audited 633 packages in 6.964s\n\n42 packages are looking for funding\n run `npm fund` for details\n\nfound 0 vulnerabilities\n\n```\nВыполнение node bin/nodejs-package.js 10 выводит число 5.\nНо тесты при этом не проходят:\n```\n$ npm test\n\n> @hexlet/nodejs-package@0.0.3 test C:\\GitReposes\\nodejs-package\n> npx -n --experimental-vm-modules jest\n\nERROR: --node-arg/-n can only be used on packages with node scripts.\nnpm ERR! Test failed. See above for more details.\n\n```\nПодскажите, пожалуйста, в чем проблема?","plain_title":"Здравствуйте! Склонировал проект с гитхаба. Попытался установить зависимости командой npm install, появилось данное сообщение: ``` npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {\"os\":\"darwin\",\"arch\":\"any\"} (current: {\"os\":\"win32\",\"arch\":\"x64\"}) added 631 packages from 382 contributors and audited 633 packages in 6.964s 42 packages are looking for funding run npm fund for details found 0 vulnerabilities Выполнение node bin/nodejs-package.js 10 выводит число 5. Но тесты при этом не проходят: $ npm test @hexlet/nodejs-package@0.0.3 test C:\\GitReposes\\nodejs-package npx -n --experimental-vm-modules jest ERROR: --node-arg/-n can only be used on packages with node scripts. npm ERR! Test failed. See above for more details. Подскажите, пожалуйста, в чем проблема? ","creator":{"public_name":"Alexander","id":306788,"is_tutor":false},"comments":[{"creator":{"public_name":"Stanislav Dzisiak","id":212236,"is_tutor":true},"id":102697,"body":"Александр, приветствую!\n\n> Попытался установить зависимости командой npm install, появилось данное сообщение:\n\nТакой вывод при установке это нормально. Тут никакой ошибки нет, а есть только предупреждения, что при установке пакета была пропущена установка опциональных зависимостей.\n\n> Но тесты при этом не проходят:\n\nТут вероятнее всего будет проблема в использовании ОС Windows. Если у вас Windows 10, то порекомендую вам для разработки использовать WSL https://docs.microsoft.com/ru-ru/windows/wsl/install-win10. Таким образом вам и ОС менять не нужно будет и вы сможете воспользоваться преимуществами разработки на *nix подобных системах.","topic_id":47679}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Зависимости для разработки","entity_url":null,"active":true}},{"id":51865,"title":"Зравствуйте!\nСклонировал репозиторий, выполнил команду npm ci\nЗапустил файл nodejs-package.js и получил вот такую вот ошибку...\n\nimport half from '../index.js';\n ^^^^\n\nSyntaxError: Unexpected identifier\n\nС чем это может быть связано?","plain_title":"Зравствуйте! Склонировал репозиторий, выполнил команду npm ci Запустил файл nodejs-package.js и получил вот такую вот ошибку... import half from '../index.js'; ^^^^ SyntaxError: Unexpected identifier С чем это может быть связано? ","creator":{"public_name":"Александр Можаев","id":323951,"is_tutor":false},"comments":[{"creator":{"public_name":"Maksim Litvinov","id":198906,"is_tutor":true},"id":110833,"body":"Рад, что у вас все получилось!","topic_id":51865},{"creator":{"public_name":"Maksim Litvinov","id":198906,"is_tutor":true},"id":110807,"body":"Скопируйте, пожалуйста, в сообщение все, что происходит в терминале - запуск команды и полный вывод","topic_id":51865},{"creator":{"public_name":"Александр Можаев","id":323951,"is_tutor":false},"id":110808,"body":"**Максим Литвинов**, \nnodejs nodejs-package.js \n\n```\n/home/alexander/nodejs-package/bin/nodejs-package.js:3\nimport half from '../index.js';\n ^^^^\n\n\n\nSyntaxError: Unexpected identifier\n at Module._compile (internal/modules/cjs/loader.js:723:23)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)\n at Module.load (internal/modules/cjs/loader.js:653:32)\n at tryModuleLoad (internal/modules/cjs/loader.js:593:12)\n at Function.Module._load (internal/modules/cjs/loader.js:585:3)\n at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)\n at startup (internal/bootstrap/node.js:283:19)\n at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)\n\n```","topic_id":51865},{"creator":{"public_name":"Maksim Litvinov","id":198906,"is_tutor":true},"id":110826,"body":"Попробуйте запустить код командой `bin/nodejs-package.js 10` из корня проекта nodejs-package","topic_id":51865},{"creator":{"public_name":"Александр Можаев","id":323951,"is_tutor":false},"id":110832,"body":"**Максим Литвинов**, Получилось, спасибо! Я думал что запустится и из директории /bin через команду nodejs nodejs-package.js, ошибался","topic_id":51865},{"creator":{"public_name":"Maksim Litvinov","id":198906,"is_tutor":true},"id":110780,"body":"Добрый день, Александр! Скажите пожалуйста, какую версию Node.js вы используете? ","topic_id":51865},{"creator":{"public_name":"Александр Можаев","id":323951,"is_tutor":false},"id":110782,"body":"**Максим Литвинов**, v15.7.0\nПочитал вчера обсуждения, видел что были у людей подобные проблемы и помогло обновление. Я обновил, перезагрузился, но вопрос не решился, вот до сих пор думаю в чем причина.","topic_id":51865}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Зависимости для разработки","entity_url":null,"active":true}},{"id":60605,"title":"Здравствуйте. Если в среде разработки мы работаем с кодом проекта, а из среды продакшена нам нужно отдавать готовый проект (без лишних файлов и папок), то как происходит процесс работы с обеими средами в реальной разработке? Создаются две разные папки проекта (одна для разработки, вторая для продакшена), в которых используется разный install, или как-то по-другому? Разъясните пожалуйста.","plain_title":"Здравствуйте. Если в среде разработки мы работаем с кодом проекта, а из среды продакшена нам нужно отдавать готовый проект (без лишних файлов и папок), то как происходит процесс работы с обеими средами в реальной разработке? Создаются две разные папки проекта (одна для разработки, вторая для продакшена), в которых используется разный install, или как-то по-другому? Разъясните пожалуйста. ","creator":{"public_name":"Александр Н.","id":409477,"is_tutor":false},"comments":[{"creator":{"public_name":"Maksim Litvinov","id":198906,"is_tutor":true},"id":127902,"body":"Вспомните из курса по гиту, что существует файл .gitignore, в который мы заносим все файлы и директории, которые не должны отслеживаться гитом. Директория node_modules, в которой хранятся все установленные зависимости проекта, обязательно должна находиться в этом файле. То есть эта директория существует только локально, в удалённый репозиторий она не выгружается. Посмотрите на эталонный репозиторий, этой папки в ней нет https://github.com/hexlet-boilerplates/nodejs-package. То есть вы стянули проект к себе, установили все зависимости, внесли какие то изменения и отправили их в удалённый репозиторий. Сама директория с зависимостями не отправляется в репозиторий, только файл package.json, где прописаны все эти зависимости. А дальше на сервере присходит разворачивание этого проекта, вновь устанавливаются зависимости, но уже только те, которые нужны для работы проекта","topic_id":60605},{"creator":{"public_name":"Александр Н.","id":409477,"is_tutor":false},"id":127947,"body":"Ага, теперь понятно - продакшен разворачивается на сервере, а не локально. Спасибо, Максим!","topic_id":60605},{"creator":{"public_name":"Александр Н.","id":409477,"is_tutor":false},"id":127874,"body":"Наверное я неправильно задал вопрос... К примеру, мы начинаем работать с проектом: запускаем `npm install` - все пакеты из dependencies и devDependencies устанавливаются в node_modules, мы работаем, все здорово. Но когда мы заканчиваем работу и нам нужно ***пересобрать*** проект для деплоя, то что должно происходить в этот момент? Мы же находимся в среде разработки и как я понимаю, если мы запустим `npm ci --production`, то пакеты из dependencies просто повторно установятся в node_modules (не удаляя из нее пакеты, оставшиеся от devDependencies), т.е. состояние проекта останется в таком же виде, как и при разработке (папка тестов, к примеру, тоже наверное никуда не денется, хотя в продакшене она вроде бы не нужна). \n\nИными словами, непонятно **как папка проекта, в которой мы только что работали в среде разработки, очищается перед деплоем и принимает состояние продакшена**? Или м.б. файлы для продакшена будут выгружены в какую-то отдельную папку (типа, dist) или что-то вроде того?","topic_id":60605},{"creator":{"public_name":"Maksim Litvinov","id":198906,"is_tutor":true},"id":127863,"body":"Приветствую, Александр! Нет, для разных сред используется один проект, но зависимости устанавливаются разные. Когда проект собирается для деплоя на боевой сервер, как раз запускается установка зависимостей с флагом --production: `npm ci --production`. Таким образом на сервер попадают только те зависимости, которые нужны чисто для работы приложения. А те зависимости, которые не нужны при работе, например тестовый фреймворк или линтер, не устанавливаются. Когда же вы хотите поработать с проектом у себя локально (среда разработки), вам нужны и зависимости для работы и те зависимости, которые используются только при разработке (те же тесты ведь нужно запустить и линтером проверит). Вы запускаете просто `npm install` и устанавливаются все зависимости.","topic_id":60605}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Зависимости для разработки","entity_url":null,"active":true}},{"id":48223,"title":"Здравствуйте! Все получилось, кроме npm test. Выдает ошибку `ERROR: --node-arg/-n can only be used on packages with node scripts.\nnpm ERR! Test failed. See above for more details.`\nOC Windows, но стоит WSL, работал через bash.","plain_title":"Здравствуйте! Все получилось, кроме npm test. Выдает ошибку ERROR: --node-arg/-n can only be used on packages with node scripts. npm ERR! Test failed. See above for more details. OC Windows, но стоит WSL, работал через bash. ","creator":{"public_name":"Maksim surimov Суримов","id":291624,"is_tutor":false},"comments":[{"creator":{"public_name":"Maksim surimov Суримов","id":291624,"is_tutor":false},"id":104523,"body":"Склонировал снова, но уже в файловую систему WSL, заработало. Вероятно ошибка была из-за того, что хоть в VS Code была запущена WSL, сам проект находился в файловой системе Windows.","topic_id":48223},{"creator":{"public_name":"Sergei Melodyn","id":162475,"is_tutor":true},"id":103699,"body":"**maxxlorge**, приветствую.\n\nВы команду тестов запускали в корне проекта? Node.js какой версии? Меняли что-то в package.json?","topic_id":48223}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Зависимости для разработки","entity_url":null,"active":true}},{"id":58604,"title":"Добрый день! Возникла следующая проблема. Размер содержимого node_modules не меняется, хотя содержимое node_modules сильно уменьшилось при установке --production . Подскажите пожалуйста, в чём может быть причина [такого поведения](https://ibb.co/SmSySDG)? ","plain_title":"Добрый день! Возникла следующая проблема. Размер содержимого nodemodules не меняется, хотя содержимое nodemodules сильно уменьшилось при установке --production . Подскажите пожалуйста, в чём может быть причина такого поведения (https://ibb.co/SmSySDG)? ","creator":{"public_name":"Maxim Kalinchuk","id":288392,"is_tutor":false},"comments":[{"creator":{"public_name":"Maksim Litvinov","id":198906,"is_tutor":true},"id":124199,"body":"Команда `npm ci` предназначена для работы в автоматизированном окружении, например для непрерывной интеграции. Вы правы, она устанавливает зависимости из package-lock.json. Проверил, команды `npm ci --production` и `npm ci` тоже устанавливают разное количество пакетов и размер директории значительно отличается. Попробуйте выполнить установку еще раз","topic_id":58604},{"creator":{"public_name":"Maksim Litvinov","id":198906,"is_tutor":true},"id":124143,"body":"Добрый день, Максим! Попробуйте установить зависимости командой `npm install --production`\n\n```\n# Вот теперь зависимости из devDependencies устанавливаться не будут\n$ npm install --production\n```","topic_id":58604},{"creator":{"public_name":"John Epishkin","id":393306,"is_tutor":false},"id":126510,"body":"**Maxim Kalinchuk**, а ты под размером содержимого имеешь ввиду объем папки node_modules, что она в двух вариантах на скрине = 12кб?\n\n- Если да, то это просто так отображает команда `ls -lh`\n\n- Попробуй например `du -sh node_modules/` - покажет вес директории со всем содержимым\n\n- Там разница между пакетом для разработки и продакшена около 100мб)","topic_id":58604},{"creator":{"public_name":"Maxim Kalinchuk","id":288392,"is_tutor":false},"id":124147,"body":"**Максим Литвинов**, Спасибо! Теперь размер стал меньше) Но я всё же не понял, чем тогда отличаются команды именно с этим флагом `npm install --production` и `npm ci --production`?\nОни разве не должны работать идентично, за исключением версий? То есть `npm ci ` устанавливает точные версии в соответствии с package-lock.json . Но почему тогда размер не меняется, мы же используем флаг `--production`?","topic_id":58604}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Зависимости для разработки","entity_url":null,"active":true}}],"lesson":{"exercise":null,"units":[{"id":3977,"name":"theory","url":"/courses/js-setup-environment/lessons/dev-dependencies/theory_unit"},{"id":4031,"name":"quiz","url":"/courses/js-setup-environment/lessons/dev-dependencies/quiz_unit"}],"links":[],"ordered_units":[{"id":3977,"name":"theory","url":"/courses/js-setup-environment/lessons/dev-dependencies/theory_unit"},{"id":4031,"name":"quiz","url":"/courses/js-setup-environment/lessons/dev-dependencies/quiz_unit"}],"id":1812,"slug":"dev-dependencies","state":"approved","name":"Зависимости для разработки","course_order":430,"goal":"Изучаем среды разработки и знакомимся с разными типами зависимостей","self_study":"1. Склонируйте проект [nodejs-package](https://github.com/hexlet-boilerplates/nodejs-package)\n1. Установите его зависимости\n1. Из корневой директории проекта запустите код на выполнение `bin/nodejs-package.js 10`. На экран должно вывестись число\n1. Запустите тесты `npm test`. Они должны завершиться успехом\n1. Посмотрите какие зависимости есть в проекте, и в директориях _src_ и *\\_\\_tests\\_\\_* как они импортируются\n1. Изучите размер и содержимое *node_modules*, затем удалите ее, установите зависимости с флагом `--production`, и посмотрите новый размер и содержимое.\n","theory_video_provider":null,"theory_video_uid":null,"theory":"У любого проекта есть как минимум два режима использования. Их обычно называют средами. Например, когда разработчик работает над проектом у себя на компьютере, то он запускает его в среде разработки. Когда же проект попадает в то место, где им пользуются, то тогда среду называют продакшеном (production).\n\nС одной стороны, эти среды всегда стараются делать похожими, чтобы избежать ошибок, связанных с особенностями конкретной среды, с другой, к ним, все же, предъявляются разные требования. Например, для разработки часто бывают нужны дополнительные пакеты, которые помогают самому процессу разработки, например, пакеты для автоматизированного тестирования кода. В продакшен среде эти пакеты ни к чему, но вот место на диске они занимают. А это мешает, так как для продакшен среды важно не тянуть за собой ненужных вещей. Это сильно влияет на скорость доставки кода на продакшен.\n\nДля решения этой задачи в проектах на JavaScript добавили возможность явно указывать зависимости, которые нужны только во время разработки. Делается это с помощью специального флага во время установки:\n\n```bash\n# jest – тестовый фреймворк,\n# с помощью которого пишутся автоматизированные тесты кода\nnpm install --save-dev jest\n```\n\nПроцедура установки здесь практически не отличается от установки обычных пакетов. Разница только в том, что описание зависимости появится не в _dependencies_, а в _devDependencies_.\n\n```json\n\"devDependencies\": {\n \"jest\": \"^26.4.1\"\n}\n```\n\nС точки зрения использования, эти пакеты ничем не отличаются от пакетов, устанавливаемых в _dependencies_. Разница только в том, где их импортируют. Как правило, для тестирования кода создается отдельная директория, внутри которой находится код тестов, которые запускаются только в среде разработки. Поэтому импорты этого кода не пересекаются с импортами кода самого проекта.\n\nВсе это можно своими глазами увидеть в специальном [пакете](https://github.com/hexlet-boilerplates/nodejs-package), созданном Хекслетом как пример эталонного проекта.\n\n## Флаг --production\n\nЗависимости для разработки всегда устанавливаются при запуске `npm install`. Здесь разработчики исходили из того, что чаще всего эта команда вызывается во время разработки, поэтому самый короткий вариант был оставлен для среды разработки. Для продакшена нужно добавлять специальный флаг:\n\n```bash\n# Вот теперь зависимости из devDependencies устанавливаться не будут\nnpm install --production\n\n# Продакшен режим можно задать и с помощью переменной окружения\nNODE_ENV=production npm install\n```\n\nКогда же проект собирается для деплоя на сервер (например, через Github Actions), то флаг нужно применять с `npm ci`:\n\n```bash\nnpm ci --production\n```\n\nНесмотря на то, что с продакшеном вы познакомитесь чуть позже, знать про _devDependencies_ нужно сразу, так как они встречаются в исходных файлах подавляющего большинства проектов и это не должно быть сюрпризом.\n\n[](https://asciinema.org/a/V0UNcKotfis5sjGvEvAtD8ghR)\n"},"lessonMember":null,"courseMember":null,"course":{"start_lesson":{"exercise":null,"units":[{"id":2089,"name":"theory","url":"/courses/js-setup-environment/lessons/intro/theory_unit"}],"links":[{"id":423481,"name":"Установка Ubuntu на Windows","url":"https://docs.microsoft.com/ru-ru/windows/wsl/install-win10\n"},{"id":423482,"name":"Установка GIT на Windows","url":"https://docs.microsoft.com/ru-ru/windows/wsl/tutorials/wsl-git\n"},{"id":423483,"name":"Менеджер версий языков","url":"https://guides.hexlet.io/ru/version-managers/\n"}],"ordered_units":[{"id":2089,"name":"theory","url":"/courses/js-setup-environment/lessons/intro/theory_unit"}],"id":1007,"slug":"intro","state":"approved","name":"Введение","course_order":100,"goal":"Знакомимся с курсом и его целями","self_study":null,"theory_video_provider":null,"theory_video_uid":null,"theory":"Хекслет построен таким образом, что все задания выполняются прямо в браузере (не считая проектов, в которых как раз отрабатываются навыки реальной работы в настоящем окружении). Такой подход позволяет сосредоточиться на самой задаче, но, к сожалению, рождает ложное ощущение понимания происходящего. Изучение программирования во многом связано с настройкой среды, и для немалого числа людей процесс установки и конфигурирования сложнее, чем написание кода. Чем быстрее вы начнете возиться с кодом у себя на компьютере, тем быстрее пойдет прогресс, и вы сможете писать реальные приложения, решать тестовые задания! Кстати, о заданиях. На Хекслете мы поддерживаем [список тестовых заданий](https://github.com/Hexlet/ru-test-assignments) от разных компаний. Рекомендуем им пользоваться как ориентиром. Идеально, если в процессе обучения вы сможете реализовать хотя бы одно-два у себя на GitHub. Во-первых, это придаст уверенности, и вы увидите, что уже кое-что можете, во-вторых, работодатели смогут оценить ваш GitHub-аккаунт и посмотреть на код.\n\nВ этом курсе мы не только установим и настроим JavaScript, но также познакомимся с пакетным менеджером _npm_ и научимся подключать сторонние библиотеки.\n\n## Окружение\n\nОб этом мало говорят, но работа с командной строкой, настройка окружения (установка языка, библиотек), взаимодействие с операционной системой – это значительная часть работы любого программиста на любом языке, на бекенде и даже на фронтенде. От этого зависит эффективность отладки, способность самостоятельно справляться с проблемами и даже качество кода.\n\nКогда программист только приходит на свою первую работу, то первое время он пытается запустить проект у себя локально на компьютере. Чем больше и сложнее проект, тем больше разных знаний для этого может понадобиться. Начиная от сетей (порты, ip-адреса) и виртуализации (докер), заканчивая сборщиками (webpack). В некоторых компаниях подобная настройка может занимать дни, а в особо запущенных случаях и всю неделю. И это при условии достаточной квалификации программиста.\n\nИзучение экосистемы своего языка — процесс непрерывный и очень непредсказуемый. Постоянно возникающие непонятные ошибки — это норма. Постоянное часовое гугление — это тоже норма. Через это проходили все, и это необходимое зло. Почему такое происходит? В отличие от языков программирования, где все подчиняется определенным правилам, экосистема — это зоопарк из огромного количества программ, операционных систем и особенностей железа, которые очень хитрым образом переплетаются друг с другом. Настолько индивидуально, что практически у каждого программиста своя собственная уникальная ситуация.\n\nИменно поэтому существуют тысячи статей по установке Node.js и постоянно появляются новые. А по комментариям к этим статьям можно заметить, что далеко не всем они помогли и пользователи сталкиваются с ошибками на каждом шагу.\n\nСо временем, когда вы разберетесь, все это окажется не таким уж и страшным. Единственное важное условие – не пытайтесь решать проблемы методом тыка, старайтесь разобраться в их причинах. Только так вы вырастете как разработчик.\n"},"id":154,"slug":"js-setup-environment","challenges_count":1,"name":"JS: Настройка окружения","allow_indexing":true,"state":"approved","course_state":"finished","pricing_type":"paid","description":"На этом курсе вы изучите процесс настройки окружения для JS. Вы узнаете о зависимостях и утилите npm. В итоге научитесь создавать собственный пакет, который можно будет использовать как программу. Знания из этого курса помогут грамотно организовать локальное окружение и использовать хорошие практики по управлению кодом.","kind":"additional","updated_at":"2026-01-20T11:43:16.494Z","language":"javascript","duration_cache":12060,"skills":["Настраивать локальное окружение для запуска JavaScript-кода","Устанавливать библиотеки и подключать их в коде","Использовать программы, улучшающие качество кода"],"keywords":["eslint","prettier","зависимости","npx"],"lessons_count":11,"cover":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Njc4MiwicHVyIjoiYmxvYl9pZCJ9fQ==--a1abc1ea03f525571164987dbfdad30c2f83313f/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJqcGciLCJyZXNpemVfdG9fZmlsbCI6WzYwMCw0MDBdfSwicHVyIjoidmFyaWF0aW9uIn19--39ba06fa99226096df9fc6bb31f84e1d29ea98e9/image.png"},"recommendedLandings":[{"stack":{"id":12,"slug":"frontend","title":"Фронтенд-разработчик","audience":"for_beginners","start_type":"weekly","pricing_model":"purchase","priority":"high","kind":"profession","state":"published","stack_state":"finished","order":20,"duration_in_months":10},"id":17,"slug":"frontend","title":"Фронтенд-разработчик","subtitle":"Изучите HTML, CSS, JavaScript и React","subtitle_for_lists":"Изучите HTML, CSS, JavaScript и React","locale":"ru","current":true,"duration_in_months_text":"10 месяцев","stack_slug":"frontend","price_text":"от 6 792 ₽","duration_text":"10 месяцев","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzcyNywicHVyIjoiYmxvYl9pZCJ9fQ==--2d5cbbf5c3b4a73ae4b2c50632305d78f5872e4d/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Programmer-rafiki.png"},{"stack":{"id":13,"slug":"backend","title":"Node.js-разработчик","audience":"for_beginners","start_type":"weekly","pricing_model":"purchase","priority":"high","kind":"profession","state":"published","stack_state":"finished","order":130,"duration_in_months":10},"id":19,"slug":"backend","title":"Node.js-разработчик","subtitle":"Изучите JavaScript, Node.js, Fastify и REST API","subtitle_for_lists":"Изучите JavaScript, Node.js, Fastify и REST API","locale":"ru","current":true,"duration_in_months_text":"10 месяцев","stack_slug":"backend","price_text":"от 4 755 ₽","duration_text":"10 месяцев","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzcyNSwicHVyIjoiYmxvYl9pZCJ9fQ==--2e84f5f94140ee4e22019ac479c290ef48c3fac8/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Static%20website-cuate.png"},{"stack":{"id":19,"slug":"layout-designer","title":"Профессиональная верстка","audience":"for_beginners","start_type":"anytime","pricing_model":"purchase","priority":"medium","kind":"track","state":"published","stack_state":"finished","order":1700,"duration_in_months":5},"id":26,"slug":"professional-layout","title":"Профессиональная верстка","subtitle":"Навык адаптивной вёрстки с современными подходами для корректного отображения сайтов на любых устройствах и разрешениях","subtitle_for_lists":"Адаптивная вёрстка для отображения на любых устройствах ","locale":"ru","current":true,"duration_in_months_text":"5 месяцев","stack_slug":"layout-designer","price_text":"от 3 900 ₽","duration_text":"5 месяцев","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDAzNCwicHVyIjoiYmxvYl9pZCJ9fQ==--ba516ea9573bdfcd1d21e2aa0fff8818561828f2/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Typing-bro.png"},{"stack":{"id":42,"slug":"layout-designer-bootstrap","title":"Bootstrap","audience":"for_programmers","start_type":"anytime","pricing_model":"subscription","priority":"medium","kind":"track","state":"published","stack_state":"finished","order":400,"duration_in_months":2},"id":72,"slug":"layout-designer-bootstrap","title":"Bootstrap","subtitle":"Навык работы с SASS, Bootstrap 5 и Gulp для ускорения, упрощения и оптимизации процесса вёрстки и разработки сайтов","subtitle_for_lists":"Изучите навык для работы с Bootstrap 5, SASS и Gulp для быстрой вёрстки","locale":"ru","current":true,"duration_in_months_text":"2 месяца","stack_slug":"layout-designer-bootstrap","price_text":"от 3 900 ₽","duration_text":"2 месяца","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDA0MCwicHVyIjoiYmxvYl9pZCJ9fQ==--137ae65fe79f41b3d5270b8a3b65b38b1621c65b/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Code%20typing-bro.png"},{"stack":{"id":43,"slug":"fullstack-javascript","title":"Fullstack-разработчик на Node.js","audience":"for_beginners","start_type":"weekly","pricing_model":"purchase","priority":"high","kind":"profession","state":"published","stack_state":"finished","order":140,"duration_in_months":12},"id":74,"slug":"fullstack-javascript","title":"Fullstack-разработчик на Node.js","subtitle":"Освоите JavaScript, Node.js, Fastify и React для фронтенда и бэкенда.","subtitle_for_lists":"Освоите JavaScript, Node.js, Fastify и React для фронтенда и бэкенда.","locale":"ru","current":true,"duration_in_months_text":"12 месяцев","stack_slug":"fullstack-javascript","price_text":"от 7 934 ₽","duration_text":"12 месяцев","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDA0MywicHVyIjoiYmxvYl9pZCJ9fQ==--e2c6c0775e2308e42fbc5dc592ba2db0470632ca/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Programmer-rafiki.png"},{"stack":{"id":47,"slug":"qa-auto-engineer-javascript","title":"Автоматизатор тестирования на JavaScript","audience":"for_programmers","start_type":"weekly","pricing_model":"purchase","priority":"high","kind":"profession","state":"published","stack_state":"finished","order":90,"duration_in_months":6},"id":82,"slug":"qa-auto-engineer-javascript","title":"Автоматизатор тестирования на JavaScript","subtitle":"Изучите: Git, JavaScript, Playwright, юнит-, API- и UI-тесты, Docker и SQL","subtitle_for_lists":"Изучите: Git, JavaScript, Playwright, юнит-, API- и UI-тесты, Docker и SQL","locale":"ru","current":true,"duration_in_months_text":"6 месяцев","stack_slug":"qa-auto-engineer-javascript","price_text":"от 4 281 ₽","duration_text":"6 месяцев","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzk0MSwicHVyIjoiYmxvYl9pZCJ9fQ==--9a9cd0863661374e7c92ea27b1270ac3299c0979/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Usability%20testing-pana.png"}],"lessonMemberUnit":null,"accessToLearnUnitExists":false,"accessToCourseExists":false},"url":"/courses/js-setup-environment/lessons/dev-dependencies/theory_unit","version":"0b0c6d4ebbd40fd58630a0dd89cc25544ccdf24e","encryptHistory":false,"clearHistory":false}"><style data-mantine-styles="true">:root, :host{--mantine-font-family: Arial, sans-serif;--mantine-font-family-headings: Arial, sans-serif;--mantine-heading-font-weight: normal;--mantine-radius-default: 0rem;--mantine-primary-color-filled: var(--mantine-color-indigo-filled);--mantine-primary-color-filled-hover: var(--mantine-color-indigo-filled-hover);--mantine-primary-color-light: var(--mantine-color-indigo-light);--mantine-primary-color-light-hover: var(--mantine-color-indigo-light-hover);--mantine-primary-color-light-color: var(--mantine-color-indigo-light-color);--mantine-spacing-xxl: calc(4rem * var(--mantine-scale));--mantine-font-size-xs: 12px;--mantine-font-size-sm: 14px;--mantine-font-size-md: 16px;--mantine-font-size-lg: clamp(16.0000px, calc(15.2727px + 0.2273vw), 18.0000px);--mantine-font-size-xl: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-font-size-display-3: clamp(32.0000px, calc(26.1818px + 1.8182vw), 48.0000px);--mantine-font-size-display-2: clamp(36.0000px, calc(25.8182px + 3.1818vw), 64.0000px);--mantine-font-size-display-1: clamp(40.0000px, calc(25.4545px + 4.5455vw), 80.0000px);--mantine-font-size-h1: clamp(28.0000px, calc(23.6364px + 1.3636vw), 40.0000px);--mantine-font-size-h2: clamp(24.0000px, calc(21.0909px + 0.9091vw), 32.0000px);--mantine-font-size-h3: clamp(20.0000px, calc(17.0909px + 0.9091vw), 28.0000px);--mantine-font-size-h4: clamp(16.0000px, calc(13.0909px + 0.9091vw), 24.0000px);--mantine-font-size-h5: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-font-size-h6: 1rem;--mantine-primary-color-0: var(--mantine-color-indigo-0);--mantine-primary-color-1: var(--mantine-color-indigo-1);--mantine-primary-color-2: var(--mantine-color-indigo-2);--mantine-primary-color-3: var(--mantine-color-indigo-3);--mantine-primary-color-4: var(--mantine-color-indigo-4);--mantine-primary-color-5: var(--mantine-color-indigo-5);--mantine-primary-color-6: var(--mantine-color-indigo-6);--mantine-primary-color-7: var(--mantine-color-indigo-7);--mantine-primary-color-8: var(--mantine-color-indigo-8);--mantine-primary-color-9: var(--mantine-color-indigo-9);--mantine-color-red-0: #ffeaea;--mantine-color-red-1: #fed4d4;--mantine-color-red-2: #f4a7a8;--mantine-color-red-3: #ec7878;--mantine-color-red-4: #e55050;--mantine-color-red-5: #e03131;--mantine-color-red-6: #e02829;--mantine-color-red-7: #c71a1c;--mantine-color-red-8: #b21218;--mantine-color-red-9: #9c0411;--mantine-color-violet-0: #fce9ff;--mantine-color-violet-1: #f1cfff;--mantine-color-violet-2: #e09bff;--mantine-color-violet-3: #d16fff;--mantine-color-violet-4: #be37fe;--mantine-color-violet-5: #b51afe;--mantine-color-violet-6: #b009ff;--mantine-color-violet-7: #9b00e4;--mantine-color-violet-8: #8a00cc;--mantine-color-violet-9: #7800b3;--mantine-color-indigo-0: #edecff;--mantine-color-indigo-1: #d6d5fe;--mantine-color-indigo-2: #aaa9f4;--mantine-color-indigo-3: #7b79eb;--mantine-color-indigo-4: #5451e4;--mantine-color-indigo-5: #3b37e0;--mantine-color-indigo-6: #2d2adf;--mantine-color-indigo-7: #1f1ec7;--mantine-color-indigo-8: #1819b2;--mantine-color-indigo-9: #0c149e;--mantine-color-cyan-0: #dffdff;--mantine-color-cyan-1: #caf5ff;--mantine-color-cyan-2: #99e8ff;--mantine-color-cyan-3: #64daff;--mantine-color-cyan-4: #3ccffe;--mantine-color-cyan-5: #24c8fe;--mantine-color-cyan-6: #00c2ff;--mantine-color-cyan-7: #00ade4;--mantine-color-cyan-8: #009acd;--mantine-color-cyan-9: #0085b5;--mantine-color-green-0: #e9fdec;--mantine-color-green-1: #d7f6dc;--mantine-color-green-2: #b0eab9;--mantine-color-green-3: #86df94;--mantine-color-green-4: #62d574;--mantine-color-green-5: #4ccf5f;--mantine-color-green-6: #3fcc54;--mantine-color-green-7: #2fb344;--mantine-color-green-8: #25a03b;--mantine-color-green-9: #138a2e;--mantine-color-yellow-0: #fff7e2;--mantine-color-yellow-1: #ffeecd;--mantine-color-yellow-2: #ffdc9c;--mantine-color-yellow-3: #ffc966;--mantine-color-yellow-4: #feb93a;--mantine-color-yellow-5: #feae1e;--mantine-color-yellow-6: #ffa90f;--mantine-color-yellow-8: #ca8200;--mantine-color-yellow-9: #af7000;--mantine-h1-font-size: clamp(28.0000px, calc(23.6364px + 1.3636vw), 40.0000px);--mantine-h1-font-weight: normal;--mantine-h2-font-size: clamp(24.0000px, calc(21.0909px + 0.9091vw), 32.0000px);--mantine-h2-font-weight: normal;--mantine-h3-font-size: clamp(20.0000px, calc(17.0909px + 0.9091vw), 28.0000px);--mantine-h3-font-weight: normal;--mantine-h4-font-size: clamp(16.0000px, calc(13.0909px + 0.9091vw), 24.0000px);--mantine-h4-font-weight: normal;--mantine-h5-font-size: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-h5-font-weight: normal;--mantine-h6-font-size: 1rem;--mantine-h6-font-weight: normal;}
:root[data-mantine-color-scheme="dark"], :host([data-mantine-color-scheme="dark"]){--mantine-color-anchor: var(--mantine-color-text);--mantine-color-dimmed: #495057;--mantine-color-dark-filled: var(--mantine-color-dark-5);--mantine-color-dark-filled-hover: var(--mantine-color-dark-6);--mantine-color-dark-light: rgba(105, 105, 105, 0.15);--mantine-color-dark-light-hover: rgba(105, 105, 105, 0.2);--mantine-color-dark-light-color: var(--mantine-color-dark-0);--mantine-color-dark-outline: var(--mantine-color-dark-1);--mantine-color-dark-outline-hover: rgba(184, 184, 184, 0.05);--mantine-color-gray-filled: var(--mantine-color-gray-5);--mantine-color-gray-filled-hover: var(--mantine-color-gray-6);--mantine-color-gray-light: rgba(222, 226, 230, 0.15);--mantine-color-gray-light-hover: rgba(222, 226, 230, 0.2);--mantine-color-gray-light-color: var(--mantine-color-gray-0);--mantine-color-gray-outline: var(--mantine-color-gray-1);--mantine-color-gray-outline-hover: rgba(241, 243, 245, 0.05);--mantine-color-red-filled: var(--mantine-color-red-5);--mantine-color-red-filled-hover: var(--mantine-color-red-6);--mantine-color-red-light: rgba(236, 120, 120, 0.15);--mantine-color-red-light-hover: rgba(236, 120, 120, 0.2);--mantine-color-red-light-color: var(--mantine-color-red-0);--mantine-color-red-outline: var(--mantine-color-red-1);--mantine-color-red-outline-hover: rgba(254, 212, 212, 0.05);--mantine-color-pink-filled: var(--mantine-color-pink-5);--mantine-color-pink-filled-hover: var(--mantine-color-pink-6);--mantine-color-pink-light: rgba(250, 162, 193, 0.15);--mantine-color-pink-light-hover: rgba(250, 162, 193, 0.2);--mantine-color-pink-light-color: var(--mantine-color-pink-0);--mantine-color-pink-outline: var(--mantine-color-pink-1);--mantine-color-pink-outline-hover: rgba(255, 222, 235, 0.05);--mantine-color-grape-filled: var(--mantine-color-grape-5);--mantine-color-grape-filled-hover: var(--mantine-color-grape-6);--mantine-color-grape-light: rgba(229, 153, 247, 0.15);--mantine-color-grape-light-hover: rgba(229, 153, 247, 0.2);--mantine-color-grape-light-color: var(--mantine-color-grape-0);--mantine-color-grape-outline: var(--mantine-color-grape-1);--mantine-color-grape-outline-hover: rgba(243, 217, 250, 0.05);--mantine-color-violet-filled: var(--mantine-color-violet-5);--mantine-color-violet-filled-hover: var(--mantine-color-violet-6);--mantine-color-violet-light: rgba(209, 111, 255, 0.15);--mantine-color-violet-light-hover: rgba(209, 111, 255, 0.2);--mantine-color-violet-light-color: var(--mantine-color-violet-0);--mantine-color-violet-outline: var(--mantine-color-violet-1);--mantine-color-violet-outline-hover: rgba(241, 207, 255, 0.05);--mantine-color-indigo-filled: var(--mantine-color-indigo-5);--mantine-color-indigo-filled-hover: var(--mantine-color-indigo-6);--mantine-color-indigo-light: rgba(123, 121, 235, 0.15);--mantine-color-indigo-light-hover: rgba(123, 121, 235, 0.2);--mantine-color-indigo-light-color: var(--mantine-color-indigo-0);--mantine-color-indigo-outline: var(--mantine-color-indigo-1);--mantine-color-indigo-outline-hover: rgba(214, 213, 254, 0.05);--mantine-color-blue-filled: var(--mantine-color-blue-5);--mantine-color-blue-filled-hover: var(--mantine-color-blue-6);--mantine-color-blue-light: rgba(116, 192, 252, 0.15);--mantine-color-blue-light-hover: rgba(116, 192, 252, 0.2);--mantine-color-blue-light-color: var(--mantine-color-blue-0);--mantine-color-blue-outline: var(--mantine-color-blue-1);--mantine-color-blue-outline-hover: rgba(208, 235, 255, 0.05);--mantine-color-cyan-filled: var(--mantine-color-cyan-5);--mantine-color-cyan-filled-hover: var(--mantine-color-cyan-6);--mantine-color-cyan-light: rgba(100, 218, 255, 0.15);--mantine-color-cyan-light-hover: rgba(100, 218, 255, 0.2);--mantine-color-cyan-light-color: var(--mantine-color-cyan-0);--mantine-color-cyan-outline: var(--mantine-color-cyan-1);--mantine-color-cyan-outline-hover: rgba(202, 245, 255, 0.05);--mantine-color-teal-filled: var(--mantine-color-teal-5);--mantine-color-teal-filled-hover: var(--mantine-color-teal-6);--mantine-color-teal-light: rgba(99, 230, 190, 0.15);--mantine-color-teal-light-hover: rgba(99, 230, 190, 0.2);--mantine-color-teal-light-color: var(--mantine-color-teal-0);--mantine-color-teal-outline: var(--mantine-color-teal-1);--mantine-color-teal-outline-hover: rgba(195, 250, 232, 0.05);--mantine-color-green-filled: var(--mantine-color-green-5);--mantine-color-green-filled-hover: var(--mantine-color-green-6);--mantine-color-green-light: rgba(134, 223, 148, 0.15);--mantine-color-green-light-hover: rgba(134, 223, 148, 0.2);--mantine-color-green-light-color: var(--mantine-color-green-0);--mantine-color-green-outline: var(--mantine-color-green-1);--mantine-color-green-outline-hover: rgba(215, 246, 220, 0.05);--mantine-color-lime-filled: var(--mantine-color-lime-5);--mantine-color-lime-filled-hover: var(--mantine-color-lime-6);--mantine-color-lime-light: rgba(192, 235, 117, 0.15);--mantine-color-lime-light-hover: rgba(192, 235, 117, 0.2);--mantine-color-lime-light-color: var(--mantine-color-lime-0);--mantine-color-lime-outline: var(--mantine-color-lime-1);--mantine-color-lime-outline-hover: rgba(233, 250, 200, 0.05);--mantine-color-yellow-filled: var(--mantine-color-yellow-5);--mantine-color-yellow-filled-hover: var(--mantine-color-yellow-6);--mantine-color-yellow-light: rgba(255, 201, 102, 0.15);--mantine-color-yellow-light-hover: rgba(255, 201, 102, 0.2);--mantine-color-yellow-light-color: var(--mantine-color-yellow-0);--mantine-color-yellow-outline: var(--mantine-color-yellow-1);--mantine-color-yellow-outline-hover: rgba(255, 238, 205, 0.05);--mantine-color-orange-filled: var(--mantine-color-orange-5);--mantine-color-orange-filled-hover: var(--mantine-color-orange-6);--mantine-color-orange-light: rgba(255, 192, 120, 0.15);--mantine-color-orange-light-hover: rgba(255, 192, 120, 0.2);--mantine-color-orange-light-color: var(--mantine-color-orange-0);--mantine-color-orange-outline: var(--mantine-color-orange-1);--mantine-color-orange-outline-hover: rgba(255, 232, 204, 0.05);--app-cta-gradient: linear-gradient(90deg, var(--mantine-color-blue-9) 0%, var(--mantine-color-cyan-7) 100%);--app-color-surface: #2e2e2e;}
:root[data-mantine-color-scheme="light"], :host([data-mantine-color-scheme="light"]){--mantine-color-anchor: var(--mantine-color-text);--mantine-color-dimmed: #495057;--mantine-color-red-light: rgba(224, 40, 41, 0.1);--mantine-color-red-light-hover: rgba(224, 40, 41, 0.12);--mantine-color-red-outline-hover: rgba(224, 40, 41, 0.05);--mantine-color-violet-light: rgba(176, 9, 255, 0.1);--mantine-color-violet-light-hover: rgba(176, 9, 255, 0.12);--mantine-color-violet-outline-hover: rgba(176, 9, 255, 0.05);--mantine-color-indigo-light: rgba(45, 42, 223, 0.1);--mantine-color-indigo-light-hover: rgba(45, 42, 223, 0.12);--mantine-color-indigo-outline-hover: rgba(45, 42, 223, 0.05);--mantine-color-cyan-light: rgba(0, 194, 255, 0.1);--mantine-color-cyan-light-hover: rgba(0, 194, 255, 0.12);--mantine-color-cyan-outline-hover: rgba(0, 194, 255, 0.05);--mantine-color-green-light: rgba(63, 204, 84, 0.1);--mantine-color-green-light-hover: rgba(63, 204, 84, 0.12);--mantine-color-green-outline-hover: rgba(63, 204, 84, 0.05);--mantine-color-yellow-light: rgba(255, 169, 15, 0.1);--mantine-color-yellow-light-hover: rgba(255, 169, 15, 0.12);--mantine-color-yellow-outline-hover: rgba(255, 169, 15, 0.05);--app-color-surface: #f1f3f5;--app-cta-gradient: linear-gradient(90deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-5) 100%);}</style><style data-mantine-styles="classes">@media (max-width: 35.99375em) {.mantine-visible-from-xs {display: none !important;}}@media (min-width: 36em) {.mantine-hidden-from-xs {display: none !important;}}@media (max-width: 47.99375em) {.mantine-visible-from-sm {display: none !important;}}@media (min-width: 48em) {.mantine-hidden-from-sm {display: none !important;}}@media (max-width: 61.99375em) {.mantine-visible-from-md {display: none !important;}}@media (min-width: 62em) {.mantine-hidden-from-md {display: none !important;}}@media (max-width: 74.99375em) {.mantine-visible-from-lg {display: none !important;}}@media (min-width: 75em) {.mantine-hidden-from-lg {display: none !important;}}@media (max-width: 87.99375em) {.mantine-visible-from-xl {display: none !important;}}@media (min-width: 88em) {.mantine-hidden-from-xl {display: none !important;}}</style><div style="position:absolute;top:0rem" class=""></div><div style="max-width:var(--container-size-xl);height:100%;min-height:0rem" class=""><style data-mantine-styles="inline">.__m__-_R_5ub_{--grid-gutter:0rem;}</style><div style="height:100%;min-height:0rem" class="m_410352e9 mantine-Grid-root __m__-_R_5ub_"><div class="m_dee7bd2f mantine-Grid-inner" style="height:100%"><style data-mantine-styles="inline">.__m__-_R_rdub_{--col-flex-grow:auto;--col-flex-basis:91.66666666666667%;--col-max-width:91.66666666666667%;}@media(min-width: 48em){.__m__-_R_rdub_{--col-flex-grow:auto;--col-flex-basis:83.33333333333334%;--col-max-width:83.33333333333334%;}}</style><div style="min-width:0rem;height:100%;min-height:0rem;display:flex" class="m_96bdd299 mantine-Grid-col __m__-_R_rdub_"><style data-mantine-styles="inline">.__m__-_R_6qrdub_{margin-top:0rem;padding-inline:var(--mantine-spacing-xs);width:100%;}@media(min-width: 48em){.__m__-_R_6qrdub_{margin-top:var(--mantine-spacing-xl);width:80%;}}@media(min-width: 62em){.__m__-_R_6qrdub_{padding-inline:var(--mantine-spacing-xl);}}</style><div style="margin-inline:auto;max-width:var(--mantine-breakpoint-xl)" class="__m__-_R_6qrdub_"><div style="color:var(--mantine-color-dimmed)" class="m_4451eb3a mantine-Center-root" data-inline="true"><div style="--ti-size:var(--ti-size-xs);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;margin-inline-end:calc(0.125rem * var(--mantine-scale));color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="xs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-lock "><path d="M5 13a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v6a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-6"></path><path d="M11 16a1 1 0 1 0 2 0a1 1 0 0 0 -2 0"></path><path d="M8 11v-4a4 4 0 1 1 8 0v4"></path></svg></div><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">JS: Настройка окружения</p></div><h1 style="--title-fw:var(--mantine-h1-font-weight);--title-lh:var(--mantine-h1-line-height);--title-fz:var(--mantine-h1-font-size);margin-bottom:var(--mantine-spacing-xl)" class="m_8a5d1357 mantine-Title-root" data-order="1">Теория: Зависимости для разработки</h1><script type="application/ld+json">{"@context":"https://schema.org","@type":"LearningResource","name":"Зависимости для разработки","inLanguage":"ru","isPartOf":{"@type":"LearningResource","name":"JS: Настройка окружения"},"isAccessibleForFree":"False","hasPart":{"@type":"WebPageElement","isAccessibleForFree":"False","cssSelector":".paywalled"}}</script><div class=""><div style="--alert-color:var(--mantine-color-indigo-light-color);margin-bottom:var(--mantine-spacing-lg);font-size:var(--mantine-font-size-lg)" class="m_66836ed3 mantine-Alert-root" id="mantine-_R_remqrdub_" role="alert" aria-describedby="mantine-_R_remqrdub_-body" aria-labelledby="mantine-_R_remqrdub_-title"><div class="m_a5d60502 mantine-Alert-wrapper"><div class="m_667f2a6a mantine-Alert-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-rocket "><path d="M4 13a8 8 0 0 1 7 7a6 6 0 0 0 3 -5a9 9 0 0 0 6 -8a3 3 0 0 0 -3 -3a9 9 0 0 0 -8 6a6 6 0 0 0 -5 3"></path><path d="M7 14a6 6 0 0 0 -3 6a6 6 0 0 0 6 -3"></path><path d="M14 9a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path></svg></div><div class="m_667c2793 mantine-Alert-body"><div class="m_6a03f287 mantine-Alert-title"><span id="mantine-_R_remqrdub_-title" class="m_698f4f23 mantine-Alert-label">Полный доступ к материалам</span></div><div id="mantine-_R_remqrdub_-body" class="m_7fa78076 mantine-Alert-message"><div style="--group-gap:var(--mantine-spacing-md);--group-align:center;--group-justify:space-between;--group-wrap:wrap" class="m_4081bf90 mantine-Group-root"><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Зарегистрируйтесь и получите доступ к этому и десяткам других курсов</p><a style="--button-height:var(--button-height-xs);--button-padding-x:var(--button-padding-x-xs);--button-fz:var(--mantine-font-size-xs);--button-bg:linear-gradient(45deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-filled) 100%);--button-hover:linear-gradient(45deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-filled) 100%);--button-color:var(--mantine-color-white);--button-bd:none" class="mantine-focus-auto mantine-active m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root" data-variant="gradient" data-size="xs" href="/u/new"><span class="m_80f1301b mantine-Button-inner"><span class="m_811560b9 mantine-Button-label">Зарегистрироваться</span></span></a></div></div></div></div></div><div class="paywalled m_d08caa0 mantine-Typography-root"><p>У любого проекта есть как минимум два режима использования. Их обычно называют средами. Например, когда разработчик работает над проектом у себя на компьютере, то он запускает его в среде разработки. Когда же проект попадает в то место, где им пользуются, то тогда среду называют продакшеном (production).</p>
<p>С одной стороны, эти среды всегда стараются делать похожими, чтобы избежать ошибок, связанных с особенностями конкретной среды, с другой, к ним, все же, предъявляются разные требования. Например, для разработки часто бывают нужны дополнительные пакеты, которые помогают самому процессу разработки, например, пакеты для автоматизированного тестирования кода. В продакшен среде эти пакеты ни к чему, но вот место на диске они занимают. А это мешает, так как для продакшен среды важно не тянуть за собой ненужных вещей. Это сильно влияет на скорость доставки кода на продакшен.</p>
<p>Для решения этой задачи в проектах на JavaScript добавили возможность явно указывать зависимости, которые нужны только во время разработки. Делается это с помощью специального флага во время установки:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code"># jest – тестовый фреймворк,
# с помощью которого пишутся автоматизированные тесты кода
npm install --save-dev jest</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Процедура установки здесь практически не отличается от установки обычных пакетов. Разница только в том, что описание зависимости появится не в <em>dependencies</em>, а в <em>devDependencies</em>.</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">"devDependencies": {
"jest": "^26.4.1"
}</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>С точки зрения использования, эти пакеты ничем не отличаются от пакетов, устанавливаемых в <em>dependencies</em>. Разница только в том, где их импортируют. Как правило, для тестирования кода создается отдельная директория, внутри которой находится код тестов, которые запускаются только в среде разработки. Поэтому импорты этого кода не пересекаются с импортами кода самого проекта.</p>
<p>Все это можно своими глазами увидеть в специальном <a style="text-decoration:underline" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="https://github.com/hexlet-boilerplates/nodejs-package" rel="noopener noreferrer" target="_blank">пакете</a>, созданном Хекслетом как пример эталонного проекта.</p>
<h2 id="heading-2-1">Флаг --production</h2>
<p>Зависимости для разработки всегда устанавливаются при запуске <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">npm install</code>. Здесь разработчики исходили из того, что чаще всего эта команда вызывается во время разработки, поэтому самый короткий вариант был оставлен для среды разработки. Для продакшена нужно добавлять специальный флаг:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code"># Вот теперь зависимости из devDependencies устанавливаться не будут
npm install --production
# Продакшен режим можно задать и с помощью переменной окружения
NODE_ENV=production npm install</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Когда же проект собирается для деплоя на сервер (например, через Github Actions), то флаг нужно применять с <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">npm ci</code>:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">npm ci --production</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Несмотря на то, что с продакшеном вы познакомитесь чуть позже, знать про <em>devDependencies</em> нужно сразу, так как они встречаются в исходных файлах подавляющего большинства проектов и это не должно быть сюрпризом.</p>
<p><a style="text-decoration:underline" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="https://asciinema.org/a/V0UNcKotfis5sjGvEvAtD8ghR" rel="noopener noreferrer" target="_blank"><img style="--image-object-fit:contain;width:auto" class="m_9e117634 mantine-Image-root" src="/rails/active_storage/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Njc5MiwicHVyIjoiYmxvYl9pZCJ9fQ==--b8c552a5ba3f225bbc08d134d5c6b10402ee53ad/V0UNcKotfis5sjGvEvAtD8ghR.gif" alt="asciicast" loading="lazy"/></a></p></div><div style="margin-block:var(--mantine-spacing-xl)" class=""><h2 style="--title-fw:var(--mantine-h2-font-weight);--title-lh:var(--mantine-h2-line-height);--title-fz:var(--mantine-h2-font-size);margin-bottom:var(--mantine-spacing-md)" class="m_8a5d1357 mantine-Title-root" data-order="2">Рекомендуемые программы</h2><style data-mantine-styles="inline">.__m__-_R_2mremqrdub_{--carousel-slide-gap:var(--mantine-spacing-xs);--carousel-slide-size:70%;}@media(min-width: 36em){.__m__-_R_2mremqrdub_{--carousel-slide-gap:var(--mantine-spacing-xl);--carousel-slide-size:50%;}}</style><div style="--carousel-control-size:calc(2.5rem * var(--mantine-scale));--carousel-controls-offset:var(--mantine-spacing-sm);margin-bottom:var(--mantine-spacing-lg);padding-block:var(--mantine-spacing-sm);background:var(--app-color-surface)" class="m_17884d0f mantine-Carousel-root responsiveClassName" data-orientation="horizontal" data-include-gap-in-size="true"><div class="m_39bc3463 mantine-Carousel-controls" data-orientation="horizontal"><button class="mantine-focus-auto m_64f58e10 mantine-Carousel-control m_87cf2631 mantine-UnstyledButton-root" type="button" data-inactive="true" data-type="previous" tabindex="-1"><svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" style="transform:rotate(90deg);width:calc(1rem * var(--mantine-scale));height:calc(1rem * var(--mantine-scale));display:block"><path d="M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg></button><button class="mantine-focus-auto m_64f58e10 mantine-Carousel-control m_87cf2631 mantine-UnstyledButton-root" type="button" data-inactive="true" data-type="next" tabindex="-1"><svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" style="transform:rotate(-90deg);width:calc(1rem * var(--mantine-scale));height:calc(1rem * var(--mantine-scale));display:block"><path d="M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg></button></div><div class="m_a2dae653 mantine-Carousel-viewport" data-type="media"><div class="m_fcd81474 mantine-Carousel-container __m__-_R_2mremqrdub_" data-orientation="horizontal"><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/frontend?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">10 месяцев</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">С нуля</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Фронтенд-разработчик</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Изучите HTML, CSS, JavaScript и React</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzcyNywicHVyIjoiYmxvYl9pZCJ9fQ==--2d5cbbf5c3b4a73ae4b2c50632305d78f5872e4d/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Programmer-rafiki.png" alt="Фронтенд-разработчик" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 6 792 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/backend?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">10 месяцев</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">С нуля</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Node.js-разработчик</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Изучите JavaScript, Node.js, Fastify и REST API</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzcyNSwicHVyIjoiYmxvYl9pZCJ9fQ==--2e84f5f94140ee4e22019ac479c290ef48c3fac8/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Static%20website-cuate.png" alt="Node.js-разработчик" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 4 755 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/professional-layout?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">5 месяцев</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">С нуля</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Профессиональная верстка</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Адаптивная вёрстка для отображения на любых устройствах </p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDAzNCwicHVyIjoiYmxvYl9pZCJ9fQ==--ba516ea9573bdfcd1d21e2aa0fff8818561828f2/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Typing-bro.png" alt="Профессиональная верстка" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 3 900 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/layout-designer-bootstrap?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">2 месяца</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Для продвинутых</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Bootstrap</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Изучите навык для работы с Bootstrap 5, SASS и Gulp для быстрой вёрстки</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDA0MCwicHVyIjoiYmxvYl9pZCJ9fQ==--137ae65fe79f41b3d5270b8a3b65b38b1621c65b/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Code%20typing-bro.png" alt="Bootstrap" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 3 900 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/fullstack-javascript?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">12 месяцев</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">С нуля</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Fullstack-разработчик на Node.js</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Освоите JavaScript, Node.js, Fastify и React для фронтенда и бэкенда.</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDA0MywicHVyIjoiYmxvYl9pZCJ9fQ==--e2c6c0775e2308e42fbc5dc592ba2db0470632ca/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Programmer-rafiki.png" alt="Fullstack-разработчик на Node.js" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 7 934 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/qa-auto-engineer-javascript?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">6 месяцев</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Для продвинутых</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Автоматизатор тестирования на JavaScript</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Изучите: Git, JavaScript, Playwright, юнит-, API- и UI-тесты, Docker и SQL</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzk0MSwicHVyIjoiYmxvYl9pZCJ9fQ==--9a9cd0863661374e7c92ea27b1270ac3299c0979/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Usability%20testing-pana.png" alt="Автоматизатор тестирования на JavaScript" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 4 281 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><h2 style="--title-fw:var(--mantine-h2-font-weight);--title-lh:var(--mantine-h2-line-height);--title-fz:var(--mantine-h2-font-size);margin-bottom:var(--mantine-spacing-md);font-size:var(--mantine-font-size-h3)" class="m_8a5d1357 mantine-Title-root" data-order="2" data-responsive="true">Каталог</h2><p style="margin-bottom:auto" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Полный список доступных курсов по разным направлениям</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="/vite/assets/development-BVihs_d5.png" alt="Orientation"/></div></div></div></a></div></div></div></div></div></div></div></div></div><style data-mantine-styles="inline">.__m__-_R_1bdub_{--col-flex-grow:auto;--col-flex-basis:8.333333333333334%;--col-max-width:8.333333333333334%;}@media(min-width: 48em){.__m__-_R_1bdub_{--col-flex-grow:auto;--col-flex-basis:16.666666666666668%;--col-max-width:16.666666666666668%;}}</style><div style="min-width:0rem;height:100%;min-height:0rem" class="m_96bdd299 mantine-Grid-col __m__-_R_1bdub_"><div style="margin-inline:var(--mantine-spacing-xs)" class="mantine-visible-from-sm"><a style="--button-color:var(--mantine-color-white);margin-bottom:var(--mantine-spacing-lg);text-decoration:none" class="mantine-focus-auto m_849cf0da mantine-focus-auto m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses/js-setup-environment/lessons/dev-dependencies/finish_unit?unit=theory" data-disabled="true" data-block="true" disabled=""><span class="m_80f1301b mantine-Button-inner"><span class="m_811560b9 mantine-Button-label"><span style="margin-inline-end:var(--mantine-spacing-xs)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Дальше</span>→</span></span></a><a style="padding-inline:0rem" class="mantine-focus-auto m_f0824112 mantine-NavLink-root m_87cf2631 mantine-UnstyledButton-root"><span class="m_690090b5 mantine-NavLink-section" data-position="left"><div style="--ti-size:var(--ti-size-sm);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="sm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-list-numbers "><path d="M11 6h9"></path><path d="M11 12h9"></path><path d="M12 18h8"></path><path d="M4 16a2 2 0 1 1 4 0c0 .591 -.5 1 -1 1.5l-3 2.5h4"></path><path d="M6 10v-6l-2 2"></path></svg></div></span><div class="m_f07af9d2 mantine-NavLink-body"><span class="m_1f6ac4c4 mantine-NavLink-label">Навигация по теме</span><span class="m_57492dcc mantine-NavLink-description">Теория</span></div><span class="m_690090b5 mantine-NavLink-section" data-position="right"></span></a><div style="margin-block:var(--mantine-spacing-lg)" class="m_3eebeb36 mantine-Divider-root" data-orientation="horizontal" role="separator"></div><div style="margin-block:var(--mantine-spacing-lg)" class=""><div style="justify-content:space-between;margin-bottom:calc(0.1875rem * var(--mantine-scale));color:var(--mantine-color-dimmed);font-size:var(--mantine-font-size-xs)" class="m_8bffd616 mantine-Flex-root __m__-_R_qimrbdub_"><p style="font-size:var(--mantine-font-size-xs)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Завершено</p><p style="font-size:var(--mantine-font-size-xs)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">0 / 11</p></div><div style="--progress-size:var(--progress-size-sm)" class="m_db6d6462 mantine-Progress-root" data-size="sm"><div style="--progress-section-size:0%;--progress-section-color:var(--mantine-color-gray-filled)" class="m_2242eb65 mantine-Progress-section" role="progressbar" aria-valuemax="100" aria-valuemin="0" aria-valuenow="0" aria-valuetext="0%"></div></div></div><button style="padding-inline:0rem" class="mantine-focus-auto m_f0824112 mantine-NavLink-root m_87cf2631 mantine-UnstyledButton-root" type="button"><span class="m_690090b5 mantine-NavLink-section" data-position="left"><div style="--ti-size:var(--ti-size-sm);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="sm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-message "><path d="M8 9h8"></path><path d="M8 13h6"></path><path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12"></path></svg></div></span><div class="m_f07af9d2 mantine-NavLink-body"><span class="m_1f6ac4c4 mantine-NavLink-label">Обсуждения (архив)</span><span class="m_57492dcc mantine-NavLink-description"></span></div></button><div style="--toc-bg:var(--mantine-color-blue-light);--toc-color:var(--mantine-color-blue-light-color);--toc-size:var(--mantine-font-size-sm);--toc-radius:var(--mantine-radius-sm);margin-top:var(--mantine-spacing-xl)" class="m_bcaa9990 mantine-TableOfContents-root" data-variant="light" data-size="sm"></div></div><div class="mantine-hidden-from-sm"><div style="--stack-gap:0rem;--stack-align:stretch;--stack-justify:flex-start" class="m_6d731127 mantine-Stack-root"><a style="--button-color:var(--mantine-color-white);margin-bottom:var(--mantine-spacing-xs);padding:0rem;text-decoration:none" class="mantine-focus-auto m_849cf0da mantine-focus-auto m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses/js-setup-environment/lessons/dev-dependencies/finish_unit?unit=theory" data-disabled="true" data-block="true" disabled=""><span class="m_80f1301b mantine-Button-inner"><span class="m_811560b9 mantine-Button-label">→</span></span></a><button style="--ai-size:var(--ai-size-sm);--ai-bg:transparent;--ai-hover:var(--mantine-color-indigo-light-hover);--ai-color:var(--mantine-color-indigo-light-color);--ai-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;padding-block:var(--mantine-spacing-lg);color:inherit;width:100%" class="mantine-focus-auto m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="subtle" data-size="sm" data-disabled="true" type="button" disabled=""><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-list-numbers "><path d="M11 6h9"></path><path d="M11 12h9"></path><path d="M12 18h8"></path><path d="M4 16a2 2 0 1 1 4 0c0 .591 -.5 1 -1 1.5l-3 2.5h4"></path><path d="M6 10v-6l-2 2"></path></svg></span></button><button style="--ai-size:var(--ai-size-sm);--ai-bg:transparent;--ai-hover:var(--mantine-color-indigo-light-hover);--ai-color:var(--mantine-color-indigo-light-color);--ai-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;padding-block:var(--mantine-spacing-lg);color:inherit;width:100%" class="mantine-focus-auto mantine-active m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="subtle" data-size="sm" type="button"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-message "><path d="M8 9h8"></path><path d="M8 13h6"></path><path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12"></path></svg></span></button></div></div></div></div></div></div></div>
</main>
<footer class="bg-dark fw-light text-light px-3 py-5">
<div class="row small">
<div class="col-12 col-sm-6 col-md-3">
<div class="h5 mb-3">Хекслет</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/about">О нас</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/testimonials">Отзывы</a>
</li>
<li>
<span class="nav-link link-light py-1 ps-0 external-link" data-href="https://b2b.hexlet.io" role="button">Корпоративное обучение</span>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/blog">Блог</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/qna">Вопросы и ответы</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/glossary">Глоссарий</a>
</li>
<li>
<span class="nav-link link-light py-1 ps-0 external-link" data-href="https://help.hexlet.io" data-target="_blank" role="button">Справка</span>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" target="_blank" rel="noopener noreferrer" href="/map">Карта сайта</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5 fw-normal mb-3">Направления</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_devops">DevOps
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_data_analytics">Аналитика
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_backend_development">Бэкенд
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_programming">Программирование
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_testing">Тестирование
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_front_end_dev">Фронтенд
</a></li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5">Профессии</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/devops-engineer-from-scratch">DevOps-инженер с нуля</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/go">Go-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/java">Java-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/python">Python-разработчик </a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/data-analytics">Аналитик данных</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/qa-engineer">Инженер по ручному тестированию</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/php">РНР-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/frontend">Фронтенд-разработчик</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5">Навыки</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/python-django-developer">Django</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/docker">Docker</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/php-laravel-developer">Laravel</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/postman">Postman</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/js-react-developer">React</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/js-rest-api">REST API в Node.js</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/spring-boot">Spring Boot</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/typescript">Typescript</a>
</li>
</ul>
</div>
</div>
<hr>
<div class="row">
<div class="col-12 col-sm-4 col-md-2">
<div class="fs-4">
<ul class="list-unstyled d-flex">
<li class="me-3">
<a aria-label="Telegram" target="_blank" class="link-light" rel="noopener noreferrer nofollow" href="https://t.me/hexlet_ru"><span class="bi bi-telegram"></span>
</a></li>
<li>
<a aria-label="Youtube" target="_blank" class="link-light" rel="noopener noreferrer nofollow" href="https://www.youtube.com/user/HexletUniversity"><span class="bi bi-youtube"></span>
</a></li>
</ul>
</div>
<div class="mb-2 d-flex flex-column">
<a class="link-light text-decoration-none" rel="nofollow" href="mailto:support@hexlet.io">support@hexlet.io</a>
<a class="link-light text-decoration-none py-2" target="_blank" href="https://t.me/hexlet_help_bot">t.me/hexlet_help_bot</a>
</div>
<ul class="list-unstyled d-flex">
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 external-link" rel="nofollow" data-href="https://hexlet.io/locale/switch?new_locale=en" data-target="_self" role="button"><span class="my-auto">EN</span>
</span></li>
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 opacity-100 external-link" rel="nofollow" data-href="https://ru.hexlet.io/locale/switch?new_locale=ru" data-target="_self" role="button"><span class="my-auto">RU</span>
</span></li>
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 external-link" rel="nofollow" data-href="https://kz.hexlet.io/locale/switch?new_locale=kz" data-target="_self" role="button"><span class="my-auto">KZ</span>
</span></li>
</ul>
</div>
<div class="col-12 col-sm-4 col-md-3">
<ul class="list-unstyled fs-4">
<li class="mb-3">
<a class="link-light text-decoration-none" href="tel:8%20800%20100%2022%2047">8 800 100 22 47</a>
<span class="d-block opacity-50 small">бесплатно по РФ</span>
</li>
<li>
<a class="link-light text-decoration-none" href="tel:%2B7%20495%20085%2021%2062">+7 495 085 21 62</a>
<span class="d-block opacity-50 small">бесплатно по Москве</span>
</li>
</ul>
</div>
<div class="col-12 col-sm-4 col-md-3">
<div class="small mb-3">Образовательные услуги оказываются на основании Л035-01298-77/01989008 от 14.03.2025</div>
<ul class="list-unstyled small">
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/legal">Правовая информация</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/offer">Оферта</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/license">Лицензия</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/contacts">Контакты</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-12 col-md-4 small">
<div class="mb-2">
<div>ООО «<a href="/" class="text-decoration-none link-light">Хекслет Рус</a>»</div>
<div>108813 г. Москва, вн.тер.г. поселение Московский,</div>
<div>г. Московский, ул. Солнечная, д. 3А, стр. 1, помещ. 20Б/3</div>
<div>ОГРН 1217300010476</div>
<div>ИНН 7325174845</div>
</div>
<hr>
<div>АНО ДПО «<a href="/" class="text-decoration-none link-light">Учебный центр «Хекслет</a>»</div>
<div>119331 г. Москва, вн. тер. г. муниципальный округ</div>
<div>Ломоносовский, пр-кт Вернадского, д. 29</div>
<div>ОГРН 1247700712390</div>
<div>ИНН 7736364948</div>
</div>
</div>
</footer>
<div id="root-assistant-offcanvas"></div>
<script src="/vite/assets/assistant-CdBlNCiQ.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/init-nkZBEvfU.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ErrorFallbackBlock-naDSYSy9.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/MarkdownBlock-DbyKWoR_.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/gon-D3e4yh1x.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/mantine-CGMYrt2Y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/shiki-V011pkdv.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/utils-DRqSHbQE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/lib-XR8Qr8kR.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dist-GCHh59xr.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Box-B5-OOzBf.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/notifications.store-C-3AFSMn.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useIsomorphicEffect-HJ6VK0D3.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/lib-KSp6QbZ0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/axios-BEvgo0ym.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/classnames-l6ipYlLR.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dayjs.min-BkKovM-s.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/debounce-jMQ_Cf4f.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/i18next-BlSq9s7B.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/client-U9M77rxp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-dom-DaLxUz_h.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useTranslation-Bx1Cdrkz.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/compiler-runtime-6XxiPFnt.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/jsx-runtime-CwjcCKJi.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-CkL4ZRHB.js" as="script" crossorigin="anonymous">
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v67327c56f0bb4ef8b305cae61679db8f1769101564043" integrity="sha512-rdcWY47ByXd76cbCFzznIcEaCN71jqkWBBqlwhF1SY7KubdLKZiEGeP7AyieKZlGP9hbY/MhGrwXzJC/HulNyg==" data-cf-beacon='{"version":"2024.11.0","token":"d11015b65d11429ea6b4a2ef37dd7e0b","server_timing":{"name":{"cfCacheStatus":true,"cfEdge":true,"cfExtPri":true,"cfL4":true,"cfOrigin":true,"cfSpeedBrain":true},"location_startswith":null}}' crossorigin="anonymous"></script>
</body>
</html>