Как автоматически перезапускать приложения Node.js с помощью nodemon
В Node.js для вступления изменений в силу необходимо перезапустить процесс. Это добавляет в рабочий процесс дополнительный шаг, необходимый для внесения изменений. Вы можете устранить этот дополнительный шаг, используя nodemon для автоматического перезапуска процесса.
nodemon — это утилита командной строки, разработанная @rem. Она заключает в оболочку ваше приложение Node, наблюдает за файловой системой и автоматически перезапускает процесс.
Из этой статьи вы узнаете об установке и настройке nodemon .
Предварительные требования
Если вы захотите следовать за этой статьей, вам потребуется следующее:
Локальная установка Node.js, выполненная согласно указаниям учебного модуля Установка Node.js и создание локальной среды разработки.
Шаг 1 — Установка nodemon
Вначале вам нужно будет установить nodemon на вашем компьютере. Установите утилиту в проекте глобально или локально, используя npm или Yarn:
Глобальная установка
Вы можете установить nodemon глобально с помощью npm :
Или с помощью Yarn:
Локальная установка
Также вы можете установить nodemon локально с помощью npm. При локальной установке мы можем установить nodemon как зависимость dev с помощью —save-dev (или —dev ):
Или с помощью Yarn:
При локальной установке нужно знать, сможете ли вы использовать команду nodemon напрямую из командной строки:
Однако вы также можете использовать его как часть некоторых скриптов npm или с npx.
На этом процесс установки nodemon завершен. Далее мы будем использовать nodemon с нашими проектами.
Шаг 2 — Настройка образца проекта Example Express с помощью nodemon
Мы можем использовать nodemon для запуска скрипта Node. Например, если у нас имеется настройка сервера Express в файле server.js , мы можем запустить его и наблюдать за изменениями следующим образом:
Вы можете передавать аргументы точно так же, как если бы запускали скрипт с помощью Node:
Процесс перезапускается каждый раз, когда вы вносите изменение в файл с одним из отслеживаемых по умолчанию расширений ( .js , .mjs , .json , .coffee или .litcoffee ) в текущем каталоге или подкаталоге.
Допустим мы записываем образец файла server.js , который выводит сообщение: Dolphin app listening on port $! .
Мы можем запустить пример с помощью nodemon :
Мы видим следующий вывод на терминале:
Output
[nodemon] 1.17.3 [nodemon] to restart at any time, enter `rs` [nodemon] watching: *.* [nodemon] starting `node server.js` Dolphin app listening on port 3000!
Пока nodemon еще работает, внесем изменение в файл server.js для вывода сообщения: Shark app listening on port $! .
Мы увидим следующий дополнительный вывод на терминале:
Output
[nodemon] restarting due to changes. [nodemon] starting `node server.js` Shark app listening on port 3000!
Вывод приложения Node.js на терминале отображается, как и ожидалось. Вы можете перезапустить процесс в любое время, набрав rs и нажав ENTER .
Также nodemon будет искать файл main , заданный в файле package.json вашего проекта:
package.json
// ."main":"server.js",// .>
Или скрипт start :
package.json
// ."scripts":"start":"node server.js">,// .>
После внесения изменений в package.json вы сможете вызывать nodemon для запуска образца приложения в режиме наблюдения без его передачи в server.js .
Шаг 3 — Использование опций
Вы можете изменить параметры конфигурации, доступные nodemon .
Рассмотрим несколько основных опций:
—exec : используйте оператор —exec , чтобы задать двоичный код для выполнения файла. Например, в сочетании с двоичным кодом ts-node оператор —exec может быть полезен для наблюдения за изменениями и запуска файлов TypeScript.
—ext : задает различные расширения файлов для наблюдения. Для этого оператора требуется указать разделенный запятыми список расширений файлов (например, —ext js,ts ).
—delay : по умолчанию nodemon ожидает одну секунду для перезапуска процесса после изменения файла, однако с помощью оператора —delay вы можете указать другое время задержки. Например, nodemon —delay 3.2 для задержки 3,2 секунды.
—watch : используйте оператор —watch , чтобы задать несколько каталогов или файлов для наблюдения. Добавляйте один оператор —watch для каждого каталога, за которым вы хотите наблюдать. По умолчанию вы наблюдаете за текущим каталогом и его подкаталогами, а с помощью —watch вы можете сузить область наблюдения до нескольких отдельных подкаталогов или файлов.
—ignore : используйте оператор —ignore , чтобы игнорировать определенные файлы, шаблоны файлов или каталоги.
—verbose : более развернутый вывод с информацией о том, какие файлы изменились, для активации перезапуска.
Вы можете просмотреть все доступные опции с помощью следующей команды:
Используя эти опции, создадим команду для соответствия следующему сценарию:
наблюдение за каталогом server
указание файлов с расширением .ts
игнорирование файлов с суффиксом .test.ts
выполнение файла ( server/server.ts ) с ts-node
ожидание перезапуска в течение трех секунд после изменения файла
Эта команда комбинирует опции —watch , —ext , —exec , —ignore и —delay , чтобы выполнить условия для нашего сценария.
Шаг 4 — Использование конфигураций
В предыдущем примере добавление параметров конфигурации при выполнении nodemon может оказаться довольно затруднительным. Лучшее решение для проектов, требующих определенных конфигураций, — задать эти конфигурации в файле nodemon.json .
Например, здесь приведены те же конфигурации, что и в предыдущем примере командной строки, но они содержатся в файле nodemon.json :
Обратите внимание, что execMap используется вместо оператора —exec . execMap позволяет задавать двоичный код, который следует использовать для определенных расширений файлов.
Если вы предпочитаете не добавлять в проект файл конфигурации nodemon.json , вы можете добавить эти конфигурации в файл package.json в ключ nodemonConfig :
Когда вы внесете изменения в nodemon.json или package.json , вы сможете запускать nodemon с помощью желаемого скрипта:
nodemon подбирает конфигурации и использует их. Это позволяет сохранять конфигурации, делиться ими и воспроизводить их, чтобы избежать ошибок при копировании и вставке или ошибок ввода в командной строке.
Заключение
В этой статье мы рассмотрели использование nodemon с приложениями Node.js. Этот инструмент поможет автоматизировать процесс остановки и запуска сервера Node для просмотра изменений.
Дополнительную информацию о доступных характеристиках и ошибках при диагностике и устранении неисправностей можно найти в официальной документации.
Если вы хотите узнать больше о Node.js, на странице темы Node.js вы найдете упражнения и проекты программирования.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
Руководство для начинающих
Это руководство проведёт вас через процесс создания простого Hello World приложения в Electron, похожий на electron/electron-quick-start .
К концу этого урока ваше приложение откроет окно браузера, отображая веб-страницу с информацией о том, какие версии Chromium.js Node и Electron работают.
Требования
Чтобы использовать Electron вы должны установить Node.js. Мы рекомендуем Вам использовать последнюю доступную LTS версию.
Пожалуйста, установите Node.js с помощью предварительно собранных установщиков для вашей платформы. В противном случае могут возникнуть проблемы совместимости.
Чтобы убедится что Node.js был установлен правильно, напишите следующие команды в терминале:
node -vnpm -v
Команды должны вывести версии Node.js и npm соответственно.
Note:Так как Electron встраивает Node.js в двоичный код, выполняемая версия Node.js может отличатся.
Создание приложения
Сборка приложения
Приложения Electron имеют ту же общую структуру, что и другие проекты Node.js. Начните с создания папки и инициализации пакета npm.
mkdir my-electron-app && cd my-electron-appnpm init
mkdir my-electron-app && cd my-electron-appyarn init
Команда init запросит некоторые значения для файла конфигурации. В этом руководстве стоит придерживаться следующего:
Значение entry point должно быть main.js .
Поля author и description могут быть любыми, но необходимы для создания пакета.
Ваш package.json файл должен выглядеть примерно так:
Далее установите пакет electron как devDependencies .
npm install --save-dev electron
yarn add --dev electron
Примечание: Если у вас возникли какие-либо проблемы с установкой Electron, пожалуйста, обратитесь к руководству Advanced Installation.
Наконец, чтобы стал возможен запуск приложения, добавьте команду start в разделе scripts файла package.json , как показано далее:
"scripts":"start":"electron .">>
Эта start команда откроет ваше приложение в режиме разработчика.
npm start
yarn start
Примечание: Эта команда запускает приложение из корневой папки. На этом шаге возможна ошибка, которая заключается в том, что не найдено приложение для запуска.
Запуск main process
Входной точкой для любого приложения на Electron является скрипт main . Этот скрипт управляет основным процессом, который запускается в полной среде Node.js и отвечает за управление рабочего цикла вашего приложения, отображение основного интерфейса, выполнение привилегированных операций и управление процессом визуализации (подробнее об этом позже).
В процессе выполнения, Electron будет искать этот скрипт в основном поле вашего package.json конфига, который вы сконфигурировали в процессе формирования кода приложения.
Чтобы инициализировать основной скрипт, создайте пустой файл с именем main.js в корневой папке вашего проекта.
Примечание: Если вы снова запустите скрипт запуска на этот момент, ваше приложение больше не будет выявлять никаких ошибок! Тем не менее, он не будет делать ничего, потому что мы не добавили код в main.js .
Создание веб-страницы
Прежде чем мы сможем создать окно для нашего приложения, нам нужно создать контент, который будет загружен в него. In Electron, each window displays web contents that can be loaded from either a local HTML file or a remote URL.
В этом туториале вы будете создавать первое. Создайте index.html файл в корневой папке проекта:
DOCTYPEhtml>html>head>metacharset="UTF-8">metahttp-equiv="Content-Security-Policy"content="default-src'self'; script-src'self'">title>Hello World!title>head>body>h1>Hello World!h1>We are using Node.jsspanid="node-version">span>,Chromiumspanid="chrome-version">span>,and Electronspanid="electron-version">span>.body>html>
Замечание: Посмотрев на этот HTML-документ, можно заметить, что версии не указаны в блоке body. Мы вручную вставим их позже с помощью JavaScript.
Открытие веб-страницы в окне браузера
Now that you have a web page, load it into an application window. To do so, you’ll need two Electron modules:
The app module, which controls your application’s event lifecycle.
The BrowserWindow module, which creates and manages application windows.
Because the main process runs Node.js, you can import these as CommonJS modules at the top of your file:
constapp,BrowserWindow>=require('electron')
Then, add a createWindow() function that loads index.html into a new BrowserWindow instance.
Next, call this createWindow() function to open your window.
In Electron, browser windows can only be created after the app module’s ready event is fired. You can wait for this event by using the app.whenReady() API. Call createWindow() after whenReady() resolves its Promise.
app.whenReady().then(()=>createWindow()>)
Note: At this point, your Electron application should successfully open a window that displays your web page!
Manage your window’s lifecycle
Although you can now open a browser window, you’ll need some additional boilerplate code to make it feel more native to each platform. Application windows behave differently on each OS, and Electron puts the responsibility on developers to implement these conventions in their app.
In general, you can use the process global’s platform attribute to run code specifically for certain operating systems.
Quit the app when all windows are closed (Windows & Linux)
On Windows and Linux, exiting all windows generally quits an application entirely.
To implement this, listen for the app module’s ‘window-all-closed’ event, and call app.quit() if the user is not on macOS ( darwin ).
Whereas Linux and Windows apps quit when they have no windows open, macOS apps generally continue running even without any windows open, and activating the app when no windows are available should open a new one.
To implement this feature, listen for the app module’s activate event, and call your existing createWindow() method if no browser windows are open.
Because windows cannot be created before the ready event, you should only listen for activate events after your app is initialized. Do this by attaching your event listener from within your existing whenReady() callback.
Note: At this point, your window controls should be fully functional!
Access Node.js from the renderer with a preload script
Now, the last thing to do is print out the version numbers for Electron and its dependencies onto your web page.
Accessing this information is trivial to do in the main process through Node’s global process object. However, you can’t just edit the DOM from the main process because it has no access to the renderer’s document context. They’re in entirely different processes!
Note: If you need a more in-depth look at Electron processes, see the Process Model document.
This is where attaching a preload script to your renderer comes in handy. A preload script runs before the renderer process is loaded, and has access to both renderer globals (e.g. window and document ) and a Node.js environment.
The above code accesses the Node.js process.versions object and runs a basic replaceText helper function to insert the version numbers into the HTML document.
To attach this script to your renderer process, pass in the path to your preload script to the webPreferences.preload option in your existing BrowserWindow constructor.
constapp,BrowserWindow>=require('electron')// include the Node.js 'path' module at the top of your fileconstpath=require('node:path')// modify your existing createWindow() functionconstcreateWindow=()=>constwin=newBrowserWindow(width:800,height:600,webPreferences:preload:path.join(__dirname,'preload.js')>>)win.loadFile('index.html')>// .
There are two Node.js concepts that are used here:
The __dirname string points to the path of the currently executing script (in this case, your project’s root folder).
The path.join API joins multiple path segments together, creating a combined path string that works across all platforms.
We use a path relative to the currently executing JavaScript file so that your relative path will work in both development and packaged mode.
Bonus: Add functionality to your web contents
At this point, you might be wondering how to add more functionality to your application.
For any interactions with your web contents, you want to add scripts to your renderer process. Because the renderer runs in a normal web environment, you can add a tag right before your index.html file’s closing
tag to include any arbitrary scripts you want:
scriptsrc="./renderer.js">script>
The code contained in renderer.js can then use the same JavaScript APIs and tooling you use for typical front-end development, such as using webpack to bundle and minify your code or React to manage your user interfaces.
Recap
After following the above steps, you should have a fully functional Electron application that looks like this:
The full code is available below:
// main.js// Modules to control application life and create native browser windowconstapp,BrowserWindow>=require('electron')constpath=require('node:path')constcreateWindow=()=>// Create the browser window.constmainWindow=newBrowserWindow(width:800,height:600,webPreferences:preload:path.join(__dirname,'preload.js')>>)// and load the index.html of the app.mainWindow.loadFile('index.html')// Open the DevTools.// mainWindow.webContents.openDevTools()>// This method will be called when Electron has finished// initialization and is ready to create browser windows.// Некоторые интерфейсы API могут использоваться только после возникновения этого события.app.whenReady().then(()=>createWindow()app.on('activate',()=>// On macOS it's common to re-create a window in the app when the// dock icon is clicked and there are no other windows open.if(BrowserWindow.getAllWindows().length===0)createWindow()>)>)// Quit when all windows are closed, except on macOS. There, it's common// for applications and their menu bar to stay active until the user quits// explicitly with Cmd + Q.app.on('window-all-closed',()=>if(process.platform!=='darwin')app.quit()>)// In this file you can include the rest of your app's specific main process// code. Можно также поместить их в отдельные файлы и применить к ним require.
// preload.js// All the Node.js APIs are available in the preload process.// It has the same sandbox as a Chrome extension.window.addEventListener('DOMContentLoaded',()=>constreplaceText=(selector,text)=>constelement=document.getElementById(selector)if(element)element.innerText=text>for(constdependencyof['chrome','node','electron'])replaceText(`$dependency>-version`,process.versions[dependency])>>)
DOCTYPEhtml>html>head>metacharset="UTF-8">metahttp-equiv="Content-Security-Policy"content="default-src'self'; script-src'self'">title>Hello World!title>head>body>h1>Hello World!h1>We are using Node.jsspanid="node-version">span>,Chromiumspanid="chrome-version">span>,and Electronspanid="electron-version">span>.scriptsrc="./renderer.js">script>body>html>
DOCTYPEhtml>html>head>metacharset="UTF-8">title>Hello World!title>metahttp-equiv="Content-Security-Policy"content="script-src'self''unsafe-inline';"/>head>body>h1>Hello World!h1>p>We are using Node.jsspanid="node-version">span>,Chromiumspanid="chrome-version">span>,and Electronspanid="electron-version">span>.p>body>html>
To summarize all the steps we’ve done:
We bootstrapped a Node.js application and added Electron as a dependency.
We created a main.js script that runs our main process, which controls our app and runs in a Node.js environment. In this script, we used Electron’s app and BrowserWindow modules to create a browser window that displays web content in a separate process (the renderer).
In order to access certain Node.js functionality in the renderer, we attached a preload script to our BrowserWindow constructor.
Package and distribute your application
The fastest way to distribute your newly created app is using Electron Forge.
Add Electron Forge as a development dependency of your app, and use its import command to set up Forge’s scaffolding:
npm install --save-dev @electron-forge/clinpx electron-forge import✔ Checking your system✔ Initializing Git Repository✔ Writing modified package.json file✔ Installing dependencies✔ Writing modified package.json file✔ Fixing .gitignoreWe have ATTEMPTED to convert your app to be in a format that electron-forge understands.Спасибо за использование "electron-forge".
yarn add --dev @electron-forge/clinpx electron-forge import✔ Checking your system✔ Initializing Git Repository✔ Writing modified package.json file✔ Installing dependencies✔ Writing modified package.json file✔ Fixing .gitignoreWe have ATTEMPTED to convert your app to be in a format that electron-forge understands.Спасибо за использование "electron-forge".
npm run make> my-electron-app@1.0.0 make /my-electron-app> electron-forge make✔ Checking your system✔ Resolving Forge ConfigWe need to package your application before we can make it✔ Preparing to Package Application for arch: x64✔ Preparing native dependencies✔ Packaging ApplicationMaking for the following targets: zip✔ Making for target: zip - On platform: darwin - For arch: x64
yarn make> my-electron-app@1.0.0 make /my-electron-app> electron-forge make✔ Checking your system✔ Resolving Forge ConfigWe need to package your application before we can make it✔ Preparing to Package Application for arch: x64✔ Preparing native dependencies✔ Packaging ApplicationMaking for the following targets: zip✔ Making for target: zip - On platform: darwin - For arch: x64
Electron Forge creates the out folder where your package will be located:
// Example for macOSout/├── out/make/zip/darwin/x64/my-electron-app-darwin-x64-1.0.0.zip├── .└── out/my-electron-app-darwin-x64/my-electron-app.app/Contents/MacOS/my-electron-app
Использование модулей Node.js с npm и package.json
Благодаря таким функциям, как оперативное выполнение ввода/вывода и его широко известному синтаксису JavaScript, Node.js быстро стал популярной рабочей средой для разработки веб-приложений на стороне сервера. Но по мере роста интереса создаются более крупные приложения, а управление сложностью базы кода и ее зависимостей становится сложнее. Node.js организует эти сложные процессы с помощью модулей, которые являются любым отдельным файлом JavaScript, содержащим функции или объекты, используемые другими программами или модулями. Группа из одного или нескольких модулей часто называется пакетом, а эти пакеты организованы менеджерами пакетов.
Менеджер пакетов Node.js (npm) — это стандартный и наиболее популярный менеджер пакетов в экосистеме Node.js; он преимущественно используется для установки и управления внешними модулями проекта Node.js. Он также часто используется для установки широкого спектра инструментов командной строки и запуска скриптов проекта. npm отслеживает модули, установленные в проекте с файлом package.json , находящимся в директории проекта и содержащим следующее:
Все модули, необходимые для проекта, и их установленные версии
Все метаданные для проекта — например, автор, лицензия и т. п.
Скрипты, которые можно запустить для автоматизации задач в проекте
При создании более сложных проектов Node.js управление своими метаданными и зависимостями при помощи файла package.json позволит обеспечить более предсказуемые сборки, поскольку все внешние зависимости одинаковы. Файл будет автоматически отслеживать эту информацию. Хотя вы можете изменять файл напрямую для обновления метаданных вашего проекта, вам будет редко требоваться взаимодействовать с ним напрямую для управления модулями.
В этом обучающем руководстве вы будете управлять пакетами с помощью npm. Первый шаг будет состоять в создании и понимании файла package.json . Затем вы сможете использовать его для отслеживания всех модулей, которые вы установили в вашем проекте. В заключение вы укажете зависимости пакетов, обновите пакеты, удалите пакеты и проведете проверку на предмет уязвимостей безопасности.
Предварительные требования
Для данного обучающего руководства вам потребуется следующее:
Node.js, установленный на вашем компьютере для разработки. В этом обучающем руководстве используется версия 10.17.0. Чтобы установить его в macOS или Ubuntu 18.04, следуйте указаниям руководства Установка Node.js и создание локальной среды разработки в macOS или раздела Установка с помощью PPA руководства Установка Node.js в Ubuntu 18.04. При установке Node.js также выполняется установка npm, в этом обучающем руководстве используется версия 6.11.3.
Шаг 1 — Создание файла package.json
Начнем это обучающее руководство с проекта в качестве примера — гипотетический модуль локатора Node.js, получающий IP-адрес пользователя и возвращающий страну происхождения. Вы не будете кодировать модуль в этом обучающем руководстве. Однако пакеты, которыми вы управляете, будут актуальны, если вы их разрабатывали.
Вначале вы создадите файл package.json , который будет содержать полезные метаданные проекта и поможет вам управлять зависимыми модулями Node.js проекта. Как следует из названия суффикса, это файл JSON (обозначение объектов JavaScript). JSON — стандартный формат, используемый для обмена, основанный на объектах JavaScript и состоящий из данных, сохраненных как пары «ключ-значение». Если хотите узнать больше о JSON, ознакомьтесь с нашей статьей Введение в JSON.
Поскольку файл package.json содержит многочисленные свойства, может быть затруднительно создавать его вручную без копирования и вставки шаблона из другого места. Чтобы упростить процесс, npm предоставляет команду init . Это интерактивная команда, которая задает ряд вопросов и создает файл package.json на основе ваших ответов.
Использование команды init
Вначале настройте проект, чтобы можно было попрактиковаться в управлении модулями. В своей оболочке создайте новую папку под названием locator :
Затем перейдите в новую папку:
Теперь инициализируйте интерактивную командную строку, введя следующее:
Примечание. Если ваш код будет использовать Git для контроля версий, сначала создайте репозиторий Git, а затем запустите npm init . Команда автоматически понимает, что она находится в папке, управляемой Git. Если задан удаленный Git, он автоматически заполняет следующие поля для вашего файла package.json : repository , bugs и homepage . Если вы инициализировали репозиторий после создания файла package.json , вам нужно будет добавить эту информацию самостоятельно. Дополнительную информацию по контролю версий Git можно найти в нашей серии Введение в Git: установка, использование и ответвления.
Результат будет выглядеть следующим образом:
Output
This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. See `npm help json` for definitive documentation on these fields and exactly what they do. Use `npm install ` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. package name: (locator)
Сначала вам будет предложено ввести имя нового проекта. По умолчанию команда предполагает, что это имя папки, в которой вы находитесь. Значения по умолчанию для каждого свойства показаны в скобках () . Поскольку в настоящем руководстве будет использоваться значение имени по умолчанию, нажмите ENTER , чтобы принять его.
Следующее значение, которое нужно ввести — версия . Как и в случае с именем , это поле требуется, если ваш проект будет размещаться вместе с другими проектами в репозитории пакетов npm.
Примечание. Пакеты Node.js должны соответствовать руководству по указанию версий Semantic (semver). Поэтому первое число будет номером версии MAJOR , который изменяется только при изменении API. Второе число будет номером версии MINOR , который изменяется при добавлении функций. Последнее число будет номером версии PATCH , который изменяется при исправлении ошибок.
Нажмите ENTER , чтобы принять версию по умолчанию.
Следующее поле описание — полезная строка, чтобы объяснить, что делает ваш модуль Node.js. Наш проект гипотетического локатора получит IP-адрес пользователя и выдаст страну происхождения. Подходящее описание : находит страну происхождения по входящему запросу , поэтому введите нечто подобное и нажмите ENTER . Описание очень полезно, когда люди ищут ваш модуль.
Следующая строка запросит у вас точку входа . Если кто-то осуществляет установку и нуждается в вашем модуле, то указанное вами в точке входа будет первой частью вашей загружаемой программы. Значение должно быть относительным местом расположения файла JavaScript и будет добавлено в свойство main файла package.json . Нажмите ENTER , чтобы сохранить значение по умолчанию.
Примечание. В большинстве модулей файл index.js является основной точкой входа. Это значение по умолчанию для свойства main файла package.json , которое представляет собой точку входа для модулей npm. Если не будет package.json , Node.js попробует загружать index.js по умолчанию.
Далее вам нужно будет ввести команду test , исполняемый скрипт или команду, чтобы запустить тесты проекта. Во многих популярных модулях Node.js тесты написаны и осуществляются с помощью Mocha, Jest, Jasmine или других тестовых структур. Поскольку тестирование выходит за рамки этой статьи, оставьте эту опцию пустой и нажмите ENTER , чтобы продолжить.
Затем команда init запросит репозиторий GitHub проекта. Вы не будете использовать его в данном примере, поэтому оставьте и его пустым.
После строки репозитория команда запросит ключевые слова . Это свойство представляет собой массив строк с полезными терминами, которые можно использовать для поиска репозитория. Лучше всего иметь небольшой набор слов, которые наиболее актуальны для вашего проекта, чтобы обеспечить более целенаправленный поиск. Введите эти ключевые слова как строку с запятыми, разделяющими каждое значение. Для данного проекта, служащего примером, введите ip,geo,country в командной строке. В готовом package.json будет три элемента в массиве для ключевых слов .
Следующее поле в командной строке — автор . Это полезно для пользователей вашего модуля, которые хотят связаться с вами. Например, если кто-то обнаружит средство эксплуатации уязвимостей в вашем модуле, они смогут использовать это поле, чтобы сообщить о проблеме, чтобы вы смогли ее исправить. Поле автор представляет собой строку в следующем формате: » Name \ < Email \>( Website )» . Например, «Sammy \ (https://your_domain)» — подходящее значение поля «автор». Электронная почта и веб-сайт являются опциональными данными — подходящее значение поля «автор» может состоять только из имени. Добавьте ваши контактные данные в качестве автора и подтвердите нажатием ENTER .
В заключение вам будет предложено ввести лицензию . Это определяет юридические разрешения и ограничения, которые будут у пользователей при использовании вашего модуля. Многие модули Node.js имеют открытый исходный код, поэтому npm задает значение ISC по умолчанию.
К этому моменту вы должны будете рассмотреть ваши опции лицензирования и определить, что подходит лучше всего для вашего проекта. Дополнительную информацию по различным видам открытых лицензий можно найти в этом списке лицензий от организации Open Source Initiative. Если вы не захотите предоставлять лицензию для частного репозитория, вы можете ввести UNLICENSED в командной строке. Для данного примера используйте лицензию ISC по умолчанию и нажмите ENTER , чтобы завершить этот процесс.
Теперь команда init отобразит файл package.json , который она будет создавать. Он будет выглядеть примерно так:
Output
About to write to /home/sammy/locator/package.json: < "name": "locator", "version": "1.0.0", "description": "Finds the country of origin of the incoming request", "main": "index.js", "scripts": < "test": "echo \"Error: no test specified\" && exit 1" >, "keywords": [ "ip", "geo", "country" ], "author": "Sammy sammy@your_domain> (https://your_domain)", "license": "ISC" > Is this OK? (yes)
Когда информация совпадет с тем, что вы видите здесь, нажмите ENTER , чтобы завершить этот процесс и создать файл package.json . С этим файлом вы можете хранить записи о модулях, которые вы установили для вашего проекта.
Теперь, когда у вас есть файл package.json , вы можете протестировать установку модулей на следующем шаге.
Шаг 2 — Установка модулей
Обычно в разработке программного обеспечения используются внешние библиотеки для выполнения вспомогательных задач в проектах. Это позволяет разработчику сосредотачивать внимание на бизнес-логике и создавать приложения более быстро и эффективно.
Например, если наш модуль локатора , используемый в качестве примера, должен сделать внешний запрос API для получения географических данных, мы можем использовать библиотеку HTTP, чтобы упростить эту задачу. Поскольку наша основная цель — предоставление пользователю соответствующих географических данных, мы можем установить пакет, упрощающий для нас запросы HTTP вместо повторной записи этого кода, т. к. это задача, выходящая за рамки нашего проекта.
Рассмотрим это на примере. В вашем приложении локатора вы будете использовать библиотеку axios, которая поможет вам выполнять запросы HTTP. Установите ее, введя следующее в оболочке:
Вы начинаете эту команду с npm install — это установит данный пакет (для краткости можно использовать npm i ). Затем перечисляете пакеты, которые хотите установить, разделяя их пробелом. В этом случае это axios . В заключение вы заканчиваете команду опциональным параметром —save , который указывает, что axios будет сохранен как зависимость проекта.
После установки библиотеки вы увидите примерно следующее:
Output
. + axios@0.19.0 added 5 packages from 8 contributors and audited 5 packages in 0.764s found 0 vulnerabilities
Теперь откройте файл package.json в текстовом редакторе по вашему выбору. В этом обучающем руководстве мы будем использовать nano :
Вы увидите новое свойство, как подчеркнуто ниже:
locator/package.json
< "name": "locator", "version": "1.0.0", "description": "Finds the country of origin of the incoming request", "main": "index.js", "scripts": < "test": "echo \"Error: no test specified\" && exit 1" >, "keywords": [ "ip", "geo", "country" ], "author": "Sammy sammy@your_domain (https://your_domain)", "license": "ISC", "dependencies": "axios": "^0.19.0" > >
Параметр —save указывает npm обновлять package.json с модулем и версиями, которые были только что установлены. Это замечательно, поскольку другие разработчики, работающие над вашим проектами, смогут легко видеть, какие внешние зависимости требуются.
Примечание. Возможно, вы заметили символ ^ перед номером версии для зависимости axios . Вспомните, что семантическое определение версий состоит из трех цифр: MAJOR, MINOR и PATCH. Символ ^ означает, что любая более высокая версия MINOR или PATCH удовлетворит это ограничение версии. Если видите ~ в начале номера версии, это означает, что только более высокие номера версий PATCH удовлетворяют это ограничение.
После завершения просмотра package.json выйдите из файла.
Зависимости разработки
Пакеты, используемые для разработки проекта, но не для его создания или запуска, называются зависимостями разработки. Они не требуются для вашего модуля или приложения в производственной среде, но могут оказаться полезными при написании кода.
Например, разработчики часто используют инструменты статического анализа кода, чтобы обеспечить соответствие кода передовым практикам и единообразие стиля. Хотя это полезно для разработки, это только увеличивает размер дистрибутива без предоставления ощутимых выгод при развертывании в производственной среде.
Установите инструмент статического анализа кода в качестве зависимости разработки для вашего проекта. Попробуйте это в оболочке:
В этой команде вы использовали флаг —save-dev . Это сохранит eslint как зависимость, которая необходима только для разработки. Обратите внимание, что вы добавили @6.0.0 к своему имени зависимости. После обновления модулей на них ставится тег версии. @ указывает npm искать конкретный тег модуля, который вы устанавливаете. Без указанного тега npm устанавливает последнюю версию с тегами. Откройте package.json еще раз:
В результате вы получите следующий вывод:
locator/package.json
< "name": "locator", "version": "1.0.0", "description": "Finds the country of origin of the incoming request", "main": "index.js", "scripts": < "test": "echo \"Error: no test specified\" && exit 1" >, "keywords": [ "ip", "geo", "country" ], "author": "Sammy sammy@your_domain (https://your_domain)", "license": "ISC", "dependencies": < "axios": "^0.19.0" >, "devDependencies": "eslint": "^6.0.0" > >
eslint сохранился как devDependencies , вместе с номером версии, который вы указали ранее. Выйдите из package.json .
Автоматически сгенерированные файлы: node_modules и package-lock.json
Когда вы в первый раз устанавливаете пакет в проекте Node.js, npm автоматически создает папку node_modules для хранения модулей, необходимых для вашего проекта, и файл package-lock.json , который вы проверили ранее.
Подтвердите, что они находятся в вашей рабочей директории. В вашей оболочке введите ls и нажмите ENTER . Результат будет выглядеть следующим образом:
Output
node_modules package.json package-lock.json
Папка node_modules содержит все установленные зависимости для вашего проекта. В большинстве случаев вы не должны назначать эту папку вашему репозиторию с контролем версии. По мере того как вы будете устанавливать больше зависимостей, размер этой папки будет быстро расти. Кроме того, файл package-lock.json хранит записи точных версий, установленных более сжато, поэтому включение node_modules не требуется.
Хотя файл package.json перечисляет зависимости, которые указывают нам на соответствующие версии, которые должны быть установлены для проекта, файл package-lock.json отслеживает все изменения в package.json или node_modules и указывает на конкретную версию установленного пакета. Обычно вы управляете этим в вашем репозитории с контролем версий, а не в node_modules , т. к. это более прозрачное представление всех ваших зависимостей.
Установка из package.json
С помощью ваших файлов package.json и package-lock.json вы можете быстро задать те же самые зависимости проекта, прежде чем начать разработку нового проекта. Чтобы продемонстрировать это, перейдите на один уровень выше в дереве директорий и создайте новую папку с именем cloned_locator на том же уровне директории, что и locator :
Перейдите в новую директорию:
Теперь скопируйте файлы package.json и package-lock.json из locator в cloned_locator :
Чтобы установить требуемые модули для этого проекта, введите следующее:
npm проверит файл package-lock.json , чтобы установить модули. Если файл lock недоступен, он будет читать из файла package.json , чтобы определить установки. Обычно быстрее устанавливать из package-lock.json , поскольку файл lock содержит точные версии модулей и их зависимости, что означает, что npm может не тратить время на нахождение подходящей версии для установки.
При развертывании в производственную среду вы можете пропустить зависимости разработки. Вспомните, что зависимости разработки хранятся в разделе devDependencies файла package.json и не влияют на управление вашим приложением. При установке модулей в рамках процесса непрерывной интеграции и разработки, чтобы развернуть приложение, пропустите зависимости разработки, введя следующее:
Флаг —production игнорирует раздел devDependencies во время установки. Пока что перейдите к вашей сборке разработки.
Прежде чем перейти к следующему разделу, вернитесь в папку locator :
Глобальная установка
Пока что вы устанавливали модули npm для проекта locator . npm также позволяет устанавливать пакеты на глобальном уровне. Это означает, что пакет доступен вашему пользователю в более широкой системе, как и любая другая команда оболочки. Эта способность полезна для многих модулей Node.js, которые являются инструментами командной строки.
Например, вы хотите завести блог о проекте locator , над которым вы сейчас работаете. Для этого вы можете использовать библиотеку, например Hexo, для создания и управления вашим блогом на статичном веб-сайте. Установите командную строку Hexo на глобальном уровне следующим образом:
Чтобы установить пакет на глобальном уровне, вы добавляете флаг -g к команде.
Примечание. Если вы получите ошибку разрешений, пытаясь выполнить установку этого пакета на глобальном уровне, ваша система может потребовать права суперпользователя для запуска команды. Попробуйте еще раз команду sudo npm i hexo-cli -g .
Проверьте, что пакет успешно установлен, введя следующее:
На данный момент вы узнали, как устанавливать модули с помощью npm. Вы можете установить пакеты к проекту локально —либо как зависимость в производственной среде, либо как зависимость разработки. Также вы можете устанавливать пакеты на базе уже существующих файлов package.json или package-lock.json , что позволяет разрабатывать с теми же зависимостями, что и у ваших коллег. В заключение вы можете использовать флаг -g для установки пакетов на глобальном уровне, чтобы получить доступ к ним, независимо от того, находитесь ли вы в проекте Node.js или нет.
Теперь, когда вы можете устанавливать модули, в следующем разделе вы будете практиковать методы управления своими зависимостями.
Шаг 3 — Управление модулями
Полный менеджер пакетов способен на гораздо большее, чем установка модулей. В npm имеется 20 команд, связанных с управлением зависимостями. На этом шаге вы:
Укажете модули, которые вы установили.
Обновите модули до последней версии.
Удалите модули, которые вам больше не нужны.
Проведете проверку безопасности на ваших модулях, чтобы найти и исправить ошибки безопасности.
Хотя эти примеры будут сделаны в вашей папке locator , все эти команды могут запускаться на глобальном уровне посредством добавления флага -g в конце, как и в случае установки на глобальном уровне.
Указание модулей
Если вы хотите знать, какие модули установлены в проекте, проще использовать команду list или ls вместо чтения package.json напрямую. Для этого введите следующее:
По умолчанию ls отображает все дерево зависимостей — модули, от которых зависит ваш проект, и модули, от которых зависят ваши зависимости. Это может быть довольно неудобно, если вы хотите получить общий обзор того, что установлено.
Чтобы вывести только модули, которые вы установили, без их зависимостей, введите следующее в оболочке:
Результат будет выглядеть следующим образом:
Output
├── axios@0.19.0 └── eslint@6.0.0
Опция —depth позволяет указать, какой уровень дерева зависимостей вы хотите увидеть. Когда значение 0 , вы увидите только зависимости самого высокого уровня.
Обновление модулей
Это хорошая практика, позволяющая поддерживать ваши модули npm обновленными. Это повышает вашу вероятность получения последних исправлений безопасности для модуля. Используйте команду outdated , чтобы проверить, можно ли обновить какие-либо модули:
Вывод будет выглядеть следующим образом:
Output
Package Current Wanted Latest Location eslint 6.0.0 6.7.1 6.7.1 locator
Сначала эта команда указывает пакет ( Package ), который установлен, и текущую ( Current ) версию. В столбце Wanted показано, какая версия удовлетворяет вашему требованию версии в package.json . В столбце Latest показана самая последняя опубликованная версия модуля.
В столбце Location показано, где в дереве зависимостей находится пакет. Команда outdated имеет флаг —depth , как ls . По умолчанию depth равняется 0.
Похоже, вы можете обновить eslint до последней версии. Используйте команду update или up следующим образом:
Вывод команды будет содержать установленную версию:
Output
npm WARN locator@1.0.0 No repository field. + eslint@6.7.1 added 7 packages from 3 contributors, removed 5 packages, updated 19 packages, moved 1 package and audited 184 packages in 5.818s found 0 vulnerabilities
Если хотите обновить все модули одновременно, введите следующее:
Удаление модулей
Команда npm uninstall может удалять модули из ваших проектов. Это означает, что модуль больше не будет установлен в папке node_modules и его нельзя будет увидеть в ваших файлах package.json и package-lock.json .
Удаление зависимостей из проекта — обычное мероприятие в жизненном цикле разработки программного обеспечения. Зависимость может не решить проблему, как заявлено, или может не предоставить удовлетворительный опыт разработки. В этих случаях может быть лучше удалить зависимость и создать собственный модуль.
Представьте, что axios не предоставляет опыт разработки, который вы хотели бы иметь для выполнения запросов HTTP. Удалите axios с помощью команды uninstall или un , введя следующее:
Вывод будет выглядеть следующим образом:
Output
npm WARN locator@1.0.0 No repository field. removed 5 packages and audited 176 packages in 1.488s found 0 vulnerabilities
Здесь не указано явно, что axios был удален. Чтобы убедиться, что он был удален, еще раз укажите зависимости:
Теперь мы видим только то, что установлен eslint :
Output
└── eslint@6.7.1
Это показывает, что вы успешно удалили пакет axios .
Проверка модулей
npm предоставляет команду audit , чтобы выявить потенциальные риски безопасности в ваших зависимостях. Чтобы увидеть проверку в действии, установите устаревшую версию модуля request, выполнив следующее:
После установки устаревшей версии request вы должны увидеть примерно следующий результат:
Output
+ request@2.60.0 added 54 packages from 49 contributors and audited 243 packages in 7.26s found 6 moderate severity vulnerabilities run `npm audit fix` to fix them, or `npm audit` for details
npm указывает, что у вас есть уязвимости в ваших зависимостях. Для получения более подробных сведений проверьте весь ваш проект:
Команда audit показывает таблицы вывода, указывающие на недостатки безопасности:
Output
=== npm audit security report === # Run npm install request@2.88.0 to resolve 1 vulnerability ┌───────────────┬──────────────────────────────────────────────────────────────┐ │ Moderate │ Memory Exposure │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Package │ tunnel-agent │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Dependency of │ request │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Path │ request > tunnel-agent │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ More info │ https://npmjs.com/advisories/598 │ └───────────────┴──────────────────────────────────────────────────────────────┘ # Run npm update request --depth 1 to resolve 1 vulnerability ┌───────────────┬──────────────────────────────────────────────────────────────┐ │ Moderate │ Remote Memory Exposure │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Package │ request │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Dependency of │ request │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Path │ request │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ More info │ https://npmjs.com/advisories/309 │ └───────────────┴──────────────────────────────────────────────────────────────┘ .
Вы видите путь к уязвимости, и иногда npm предоставляет способы ее устранения. Вы можете выполнить команду update, как предложено, или выполнить подкоманду fix команды audit . В своей оболочке введите:
Вы увидите примерно следующий результат:
Output
+ request@2.88.0 added 19 packages from 24 contributors, removed 32 packages and updated 12 packages in 6.223s fixed 2 of 6 vulnerabilities in 243 scanned packages 4 vulnerabilities required manual review and could not be updated
npm смог безопасно обновить два пакета, тем самым устранив две уязвимости. Но у вас все еще есть четыре уязвимости в ваших зависимостях. Команда audit fix не всегда устраняет каждую проблему. Хотя версия модуля может иметь уязвимость безопасности, если вы обновите ее до версии с другим API, то это может нарушить код выше в дереве зависимостей.
Вы можете использовать параметр —force , чтобы обеспечить удаление уязвимости:
Как упоминалось ранее, это не рекомендуется, если вы не уверены, что это не нарушит функциональность.
Заключение
В этом обучающем руководстве вы прошли различные упражнения, чтобы продемонстрировать организацию модулей Node.js в пакетах и управление этими пакетами при помощи npm. В проекте Node.js вы использовали пакеты npm как зависимости, создавая и обслуживая файл package.json — запись метаданных вашего проекта, включая модули, которые вы установили. Вы также использовали инструмент командной строки npm для установки, обновления и удаления модулей, помимо указания дерева зависимостей для ваших проектов, а также проверки и обновления модулей, которые устарели.
В будущем использование существующего кода с помощью модулей ускорит время разработки, так как вам не придется дублировать функциональность. Вы также сможете создавать собственные модули npm, и они, в свою очередь, будут управляться другими модулями с помощью команд npm. В качестве дальнейших шагов экспериментируйте с тем, что вы узнали в этом обучающем руководстве, устанавливая и тестируя различные существующие пакеты. Посмотрите, что предоставляет экосистема для упрощения процесса решения проблем. Например, вы можете попробовать TypeScript — расширенную версию JavaScript, или превратить ваш веб-сайт в мобильные приложения с помощью Cordova. Если хотите узнать больше о Node.js, ознакомьтесь с другими нашими обучающими руководствами по Node.js.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
Начало работы с Node.js
Мы начнем с основ: никаких предварительных знаний Node.js не требуется. Цель этой книги — начать работу с Node.js и убедиться, что вы понимаете, как писать приложение с использованием этой платформы.
В первой главе вы узнаете, что такое Node.js, как установить её на свой компьютер и как начать с ней работать — так что в следующих главах можно будет приступить к реальной разработке. Приступим!
Node.js в двух словах
Node.js — это среда выполнения JavaScript, построенная на JavaScript-движке V8 из Chrome. В основе Node.js лежит событийно-управляемая модель с неблокирующими операциями I/O, что делает её легкой и эффективной.
Другими словами: Node.js предлагает вам возможность писать невероятно производительный серверный код с использованием JavaScript. Как говорится в официальном описании: Node.js — это среда выполнения, использующая тот же JavaScript-движок V8, который вы можете найти в браузере Google Chrome. Но этого недостаточно для успеха Node.js. В Node.js используется libuv — кросс-платформенная библиотека поддержки с акцентом на асинхронный ввод-вывод.
С точки зрения разработчика, Node.js однопоточна, но под капотом libuv использует треды, события файловой системы, реализует цикл событий, включает в себя тред-пулинг и так далее. В большинстве случаев вы не будете взаимодействовать с libuv напрямую.
Установка Node.js для старта
Последнюю версию Node.js вы можете найти на официальном сайте: https://nodejs.org/en/download/.
При таком подходе довольно легко начать работу, но если позже вы захотите добавить в систему больше версий Node.js, лучше начать использовать nvm (node version manager) — диспетчер версий Node.js.
После его установки вы сможете использовать очень простой CLI API для смены версии Node.js:
Установка различных версий Node.js
nvm install 4.4
Затем, если вы хотите проверить в работе экспериментальную версию:
nvm install 5
Чтобы убедиться, что у вас установлена и запущена Node.js, выполните:
node --version
Если все в порядке, эта команда вернет номер версии текущего активного бинарного файла Node.js.
Использование нескольких версий Node.js
Если вы работаете над проектом, поддерживающим Node.js v4, вы можете начать использовать эту версию с помощью следующей команды:
nvm use 4
Затем вы можете переключиться на Node.js v5 с помощью той же самой команды:
nvm use 5
Хорошо, теперь мы знаем, как устанавливать Node.js и переключаться между её версиями, но в чём смысл?
С тех пор как был сформирован Node.js Foundation, Node.js имеет план релизов. Это очень похоже на другие проекты Linux Foundation. Это означает, что есть два релиза: стабильный и экспериментальный. В Node.js стабильными версиями с долговременной поддержкой (LTS) являются те, которые начинаются с четных чисел (4, 6, 8, …). Экспериментальные версии нумеруются нечетными числами (5, 7, …).
Мы рекомендуем использовать версию LTS в продакшене и пробовать новые возможности с экспериментальной версией.
Если вы используете Windows, здесь можно скачать альтернативу для nvm:nvm-windows.
Hello World
Чтобы начать работу с Node.js, давайте попробуем её в консоли! Запустите Node.js, просто набрав node :
$ node >
Хорошо, давайте попробуем что-то напечатать:
$ node > console.log('hello from Node.js')
После нажатия Enter вы получите следующее:
> console.log('hello from Node.js') hello from Node.js undefined
Не стесняйтесь играть с Node.js с помощью этого интерфейса: я обычно тестирую небольшие фрагменты кода здесь, если я не хочу помещать их в файл.
Пришло время создать наше приложение Hello Node.js!
Начнем с создания файла index.js . Откройте свою IDE (Atom, Sublime, Code — выбор за вами), создайте новый файл и сохраните его с именем index.js . Если вы закончили, скопируйте в него следующий фрагмент кода:
// index.js console.log('hello from Node.js')
Чтобы запустить этот файл, вы должны снова открыть свой терминал и перейти в каталог, в котором размещён index.js .
Как только вы успешно переместитесь в нужное место, запустите файл, используя команду node index.js . Вы увидите, что эта команда будет выдавать тот же результат, что и раньше, выводя строку непосредственно в терминале.
Модульность для вашего приложения
Теперь у вас есть файл index.js , поэтому пришло время перейти на следующий уровень! Давайте создадим что-то более сложное, разделив наш исходный код на несколько JavaScript-файлов с целью удобочитаемости и поддерживаемости. Чтобы начать работу, вернитесь в свою IDE и создайте следующую структуру каталогов (с пустыми файлами), но пока не трогайте package.json , мы сгенерируем его автоматически на следующем шаге:
Каждый проект Node.js начинается с создания файла package.json . Вы можете думать о нем как о JSON-представлении приложения и его зависимостей. Он содержит имя вашего приложения, автора (вас) и все зависимости, необходимые для запуска приложения. Мы рассмотрим раздел зависимостей позже в главе «Использование NPM».
Вы можете интерактивно генерировать файл package.json с помощью команды npm init в терминале. После запуска команды вас попросят ввести некоторые данные, например имя вашего приложения, версию, описание и так далее. Не нужно беспокоиться, просто нажимайте Enter, пока не получите сформированный JSON и вопрос is it ok? . Нажмите Enter в последний раз и вуаля: ваш package.json был автоматически сгенерирован и помещен в папку вашего приложения. Если вы откроете этот файл в своей IDE, он будет очень похож на фрагмент кода ниже.
Хорошей практикой является добавление стартового скрипта в ваш пакет package.json . Как только вы это сделаете, как показано в примере выше, вы можете запустить приложение с помощью команды npm start . Это очень удобно, когда вы хотите развернуть свое приложение у PaaS-провайдера: они могут распознать команду start и использовать её для запуска приложения.
Теперь давайте вернемся к первому созданному вами файлу под названием index.js . Я рекомендую оставить этот файл очень компактным: только подключение самого приложения (файл index.js из подкаталога /app , созданного ранее). Скопируйте следующий код в свой файл index.js и сохраните:
// index.js require('./app/index')
Теперь пришло время приступить к созданию реального приложения. Откройте файл index.js из папки /app , чтобы создать очень простой пример: добавление массива чисел. В этом случае файл index.js будет содержать только числа, которые мы хотим добавить, а логика, требующая вычислений, должна быть помещена в отдельный модуль.
Вставьте этот код в файл index.js в каталоге /app .
// app/index.js const calc = require('./calc') const numbersToAdd = [ 3, 4, 10, 2 ]const result = calc.sum(numbersToAdd) console.log(`The result is: $`)
Теперь вставьте фактическую бизнес-логику в файл calc.js , который можно найти в той же папке.
// app/calc.js function sum (arr) return arr.reduce(function(a, b) return a + b >, 0) >module.exports.sum = sum
Чтобы проверить, всё ли вы сделали правильно, сохраните эти файлы, откройте терминал и введите npm start или node index.js . Если вы все сделали правильно, вы получите ответ: 19. Если что-то пошло не так, внимательно просмотрите лог в консоли и найдите проблему на его основе.
В следующей главе под названием «Использование NPM» мы рассмотрим, как использовать NPM — менеджер пакетов для JavaScript.