Ускорьте рабочий процесс разработки JavaScript с помощью npm и package.json

Каждый день миллионы разработчиков используют npm (или Yarn) для своих проектов JavaScript. Запуск таких команд, как npm init или npx create-react-app, стал удобным способом начать практически любой проект JavaScript, независимо от того, создаете ли вы код для клиентской или серверной стороны - или даже если вы создаете настольное приложение.

Но npm - это гораздо больше, чем инициализация проектов или установка пакетов. В этой статье мы обсудим 13 приемов, позволяющих максимально эффективно использовать npm: от простых ярлыков до пользовательских npm init скриптов.

Поскольку многие из нас используют npm каждый день, даже небольшая экономия времени может иметь существенное значение в долгосрочной перспективе. Эти приемы предназначены для начинающих и средних разработчиков, но даже если вы опытный разработчик, я надеюсь, что вы все же найдете одну или две функции, с которыми раньше не сталкивались.

Наконец, если вы новичок в npm, он поставляется в комплекте с Node.js, который вы можете установить по адресу https://nodejs.org/en/. Если вы работаете в Windows, я рекомендую установить Git Bash, чтобы продолжить. Давайте погрузимся.

1. Изучите основные ярлыки

Начнем с основ. Короткое время, потраченное на изучение наиболее распространенных сочетаний клавиш npm, в конечном итоге означает экономию времени.

  • Установка - Обычная: npm install. Ярлык: npm i.
  • Тестирование— Обычное: npm test. Ярлык: npm t.
  • Получение помощи - Обычно: npm --help. Ярлык: npm -h.
  • Мировой флаг - обычный: --global. Ярлык -g.
  • Сохранение как зависимость от разработки - Обычное: --save-dev. Ярлык: -D.
  • Принятие настроек npm init по умолчанию - Обычное: npm init --yes или npm init --force. Ярлык: npm init -y или npm init -f.

Вам больше не нужно использовать --save или -S для сохранения пакетов, поскольку теперь это значение по умолчанию. Чтобы установить пакет без его сохранения, используйте флаг --no-save.

Менее распространенные ярлыки

Есть также несколько менее распространенных ярлыков, в том числе:

  • Сохранение как необязательной зависимости - Обычное: --save-optional. Ярлык: -O.
  • Сохранение точной версии пакета - Обычный: --save-exact. Ярлык: -E.

Если вам когда-нибудь понадобится сохранить пакет npm локально или выбрать несколько пакетов, доступных через загрузку одного файла, вы можете объединить их вместе, используя --save-bundle или -B, и получить пакет, используя npm pack.

Корневой ярлык

Символ . обычно используется для обозначения корневого каталога приложения или (в зависимости от контекста) точки входа приложения - в терминах npm это то, что указано как значение "main" в package.json:

{
  "main": "index.js"
}

Этот ярлык также можно использовать с такими командами, как npx create-react-app. Таким образом, вместо создания нового my-app каталога с npx create-react-app my-app вы можете запустить npx create-react-app ., чтобы настроить React в папке, в которой вы уже находитесь.

2. Установите свойства npm init по умолчанию.

Запуская npm init, чтобы начать новый проект, вы, вероятно, обнаружите, что снова и снова набираете некоторые детали. Например, скорее всего, вы являетесь автором большинства своих проектов. Чтобы сэкономить время, вы можете установить значения по умолчанию для этих полей, например:

npm config set init.author.name  "Joe Bloggs"
npm config set init.author.email "[email protected]"
npm config set init.author.url   "joebloggs.com"
npm config set init.license      "MIT"

Чтобы убедиться, что эти свойства были добавлены правильно, введите npm config edit, чтобы открыть файл конфигурации. Вы также можете редактировать детали, вводя значения непосредственно в этот файл. Если вы хотите изменить глобальную настройку npm, используйте npm config edit -g.

Чтобы вернуться к настройкам по умолчанию, вы можете использовать следующий скрипт. Первая строка заменяет файл конфигурации пустой строкой, а вторая строка повторно заполняет его настройками по умолчанию.

echo "" > $(npm config get userconfig)
npm config edit

Приведенный выше сценарий сбросит пользовательские настройки по умолчанию, а следующий - глобальные настройки по умолчанию:

echo "" > $(npm config get globalconfig)
npm config --global edit

3. Сделайте скрипты кроссплатформенными.

Любой код, выполняемый в командной строке, рискует проблемами совместимости, особенно между Windows и системами на базе Unix (включая Mac и Linux). Это не проблема, если вы - и только вы - работаете над конкретным проектом, но есть много случаев, когда кроссплатформенная совместимость является ключевой: любой проект с открытым исходным кодом или совместный проект, а также примеры и учебные проекты должны работать независимо от операционной системы.

К счастью, решение простое. Есть несколько вариантов, но лучший результат у меня - cross-env. Установите его как зависимость для разработки, используя npm i -D cross-env. Затем включите ключевое слово cross-env перед любыми переменными среды, например:

{
  "scripts": {
    "build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js"
  }
}

Я обнаружил, что cross-env - самый простой способ добиться кроссплатформенной совместимости, но, возможно, стоит проверить два других популярных инструмента, которые могут в этом помочь:

  • Римраф можно установить глобально для запуска кроссплатформенных скриптов;
  • ShellJS - это переносимая реализация команд оболочки Unix поверх API Node.js.

4. Параллельное выполнение скриптов.

Вы можете использовать && для запуска двух или более процессов один за другим. Но как насчет параллельного запуска скриптов? Для этого мы можем выбирать из множества пакетов npm. Concurrently и npm-run-all - самые популярные решения, и в этом примере мы будем использовать их одновременно.

Сначала установите его как зависимость для разработки: npm i -D concurrently. Затем вы можете добавить его в свои скрипты в следующем формате:

{
  "start": "concurrently \"command1 arg\" \"command2 arg\""
}

5. Запускайте скрипты в разных каталогах.

Иногда у вас есть приложение с несколькими package.json файлами в разных папках. Было бы удобно получить доступ к этим сценариям из корневого каталога, а не переходить к разным папкам каждый раз, когда вы хотите запустить сценарий, и есть два способа сделать это.

Во-первых, вы можете использовать cd для автоматического доступа к различным папкам:

cd folder && npm start && cd ..

Но есть более элегантное решение - использовать флаг --prefix для указания пути:

npm start --prefix path/to/your/folder

Вот пример этого решения в рабочем приложении, где мы хотим запустить npm start как в нашем интерфейсе (в каталоге «client»), так и в нашем внутреннем интерфейсе (в каталоге «server»).

"start": "concurrently \"(npm start --prefix client)\" \"(npm start --prefix server)\"",

6. Отложите выполнение сценариев до тех пор, пока порт не будет готов.

Часто во время разработки полнофункционального приложения вы, вероятно, захотите запустить и серверный, и клиентский уровень представления. Модуль узла wait-on предоставляет удобный способ убедиться, что процессы выполняются только тогда, когда определенные процессы готовы: в нашем случае это конкретный порт.

Например, вот сценарий dev, который я использую в проекте Electron, который использует интерфейс React. Используя concurrently, сценарий загружает уровень представления и окно Electron параллельно. Но при использовании wait-on окно Electron открывается только тогда, когда уровень представления React готов http://localhost:3000.

"dev": "concurrently \"cross-env BROWSER=none npm run start\" \"wait-on http://localhost:3000 && electron .\"",

Вдобавок React по умолчанию открывает окно браузера, но для разработки Electron в этом нет необходимости. Мы можем отключить это поведение, передав переменную окружения BROWSER=none, перед которой стоит cross-env, для кросс-платформенной совместимости.

7. Список и выбор доступных сценариев.

Вывести список сценариев, доступных в package.json файле, просто: просто перейдите в корневой каталог вашего проекта и введите npm run в терминале.

Но есть еще более удобный способ получить список скриптов, который можно запустить сразу: для этого установите модуль NTL (npm Task List) глобально:

npm i -g ntl

Затем запустите команду ntl в папке проекта. Вы получите список доступных сценариев с возможностью выбора одного из них для запуска.

Это может быть удобно, если вы не знаете, какие сценарии используются в проекте, или если вы предпочитаете вводить ntl, а не более длинное имя сценария!

8. Запуск сценариев до и после.

Возможно, вы знакомы с такими сценариями, как prebuild и postbuild, которые позволяют вам определять код для запуска до или после вашего build сценария. Но на самом деле pre и post можно добавить перед любым скриптом, в том числе и кастомным.

Это не только делает ваш код более чистым, но также позволяет запускать сценарии pre и post изолированно.

9. Управляйте версией своего приложения.

Вместо того, чтобы вручную изменять версию вашего приложения, в npm есть несколько полезных ярлыков для этого. Чтобы увеличить версию, введите npm version plus major, minor или patch:

// 1.0.0
npm version patch
// 1.0.1
npm version minor
// 1.1.0
npm version major
// 2.0.0

В зависимости от того, насколько регулярно вы обновляете свое приложение, вы можете сэкономить время, увеличивая номер версии каждый раз при развертывании, используя такой сценарий, как:

{
  "predeploy": "npm version patch"
}

10. Отредактируйте package.json из командной строки.

package.json - это обычный json файл, поэтому его можно редактировать из командной строки с помощью инструмента json. Это открывает новые возможности для изменения package.json, позволяя создавать ярлыки, выходящие за рамки значений по умолчанию. Установите его глобально:

npm install -g json

Затем вы можете использовать его для редактирования на месте с -I. Например, чтобы добавить новый скрипт foo со значением bar, введите:

json -I -f package.json -e 'this.scripts.foo="bar"'

Более практический пример работы модуля json см. В следующем совете!

11. Установите и откройте свой репозиторий автоматически.

Если в вашем package.json файле есть запись "repository", вы можете открыть ее в браузере по умолчанию, набрав npm repo.

Если ваш проект уже подключен к удаленному репозиторию и у вас установлен git в командной строке, вы можете узнать свой репозиторий с помощью этой команды:

git config --get remote.origin.url

Еще лучше, если вы последовали совету выше и установили модуль узла json, вы можете использовать следующий сценарий для автоматического добавления в правильный репозиторий в package.json:

json -I -f package.json -e "this.repository=\"$(git config --get remote.origin.url)\""

12. Создайте собственный сценарий инициализации npm.

Давайте сделаем еще один шаг вперед с нашим собственным npm init скриптом, который берет URL-адрес репозитория GitHub и автоматически отправляет нашу первую фиксацию. В этом совете мы обсудим, как создать собственный npm init скрипт. В следующем (и последнем) совете мы добавим git.

Вы можете отредактировать сценарий npm init, перенаправив его в файл .npm-init.js в вашем домашнем каталоге. (В Windows это обычно c/Users/<username>, а в Mac - /Users/<username>).

Начнем с создания файла .npm-init.js в нашем домашнем каталоге. Чтобы убедиться, что npm init направлен в правильный файл, вы можете запустить:

npm config set init-module ~\.npm-init.js

Перед интеграцией git воспользуйтесь простым .npm-init.js файлом, который имитирует вопросы по умолчанию npm init:

module.exports = {
  name: prompt('package name', basename || package.name),
  version: prompt('version', '0.0.0'),
  decription: prompt('description', ''),  
  main: prompt('entry point', 'index.js'),
  repository: prompt('git repository', ''),
  keywords: prompt(function (s) { return s.split(/\s+/) }),
  author: prompt('author', 'Joe Bloggs <[email protected]> (joebloggs.com)'),
  license: prompt('license', 'ISC')
}

Каждый вопрос следует шаблону nameInPackage: prompt('nameInPrompt', 'defaultValue'). Чтобы без вопросов установить значение по умолчанию, просто удалите метод prompt.

Если вы хотите вернуться к настройкам по умолчанию, просто удалите .npm-init.js.

13. Отправьте свою первую фиксацию на GitHub с помощью специального сценария инициализации npm.

Чтобы включить git команды в наш .npm-init.js файл, нам понадобится способ управления командной строкой. Для этого мы можем использовать модуль child_process. Нам потребуется, чтобы он находился в верхней части нашего файла, и, поскольку нам нужна только функция execSync, мы можем получить ее самостоятельно, используя синтаксис деструктурирующего присваивания:

const { execSync } = require('child_process');

Я также создал вспомогательную функцию, которая выводит результаты нашей функции на консоль:

function run(func) {
  console.log(execSync(func).toString())
}

Наконец, мы сделаем запрос для URL-адреса репозитория GitHub и, если он есть, сгенерируем файл README.md и отправим нашу первую фиксацию. Это должен быть один из элементов нашего module.exports объекта:

repository: prompt('github repository url', '', function (url) {
  if (url) {
    run('touch README.md');
    run('git init');
    run('git add README.md');
    run('git commit -m "first commit"');
    run(`git remote add origin ${url}`);
    run('git push -u origin master');
  }
  return url;
})

В целом наш .npm-init.js файл должен выглядеть примерно так:

И это даст нам package.json файл со следующими полями:

Вы можете пойти еще дальше, включив GitHub API, так что вам даже не придется создавать новый репозиторий - но я оставлю это на ваше усмотрение!

В целом, я надеюсь, что эта статья открыла вам глаза на то, чего можно достичь с помощью npm, и продемонстрировала некоторые способы, которыми вы можете повысить свою продуктивность - будь то знание общих горячих клавиш, получение максимальной отдачи от скриптов в package.json или написав специальную версию npm init.

Если у вас есть какие-либо вопросы, не стесняйтесь оставлять комментарии и не забудьте проверить официальную документацию npm для получения дополнительной информации. Спасибо за прочтение!