[Перевод] Минимальное окружение для JS-разработки: ava, standard, chokidar-cli и precommit-hook
По опыту знаю: первый шаг нового проекта, например, создания модуля или средства командной строки, заключается в настройке рабочего окружения. Некоторым этот шаг нравится, некоторые его терпеть не могут, но и у тех и у других предварительная подготовка часто занимает непозволительно много времени. Особенно, когда надо всё тщательно проверить и заставить все механизмы слаженно и стабильно работать вместе.
Конечно, можно включить в арсенал JS-разработчика webpack, eslint, jasmine, или даже TypeScript. При таком подходе с нахождением и устранением ошибок проблем не будет. Но всё дело в том, что для решения большинства вспомогательных задач прекрасно подойдут простые инструменты, которые практически не нуждаются в настройке. Окружение, собранное из них, позволит максимально быстро начать работу, обеспечит контроль правильности кода и своевременное оповещение об ошибках.
Когда я задумываюсь о минимальном JS-окружении, на ум сразу приходят четыре вещи: тестирование программы и анализ кода, отслеживание изменений файлов в процессе работы и проверка проекта перед фиксацией транзакций в системе контроля версий.
Сейчас я подробно расскажу о том, как, буквально на пустом месте, создать среду разработки, которая позволит в считанные минуты приступить к продуктивному труду.
Инициализация проекта Node.js и Git-репозитория
Сначала создадим директорию и перейдём в неё. Здесь конструкция
$_
хранит аргумент последней команды.$ mkdir awesome-module && cd $_
Теперь инициализируем проект Node.js с настройками по умолчанию.
npm init --yes
Создадим папки и файлы
$ mkdir lib test
$ touch index.js lib/meaningOfLife.js test/index.test.js test/meaningOfLife.test.js
Теперь инициализируем Git-репозиторий и зафиксируем первую транзакцию.
$ git init
$ git add -A; git commit -am "Awesome Module, day one"
Структуру проекта мы подготовили, займёмся инструментами.
Установка инструментов
Мы будем использовать четыре простых модуля, каждый из которых предназначен для решения одной задачи:
- Ava — тестирование.
- Standard — статический анализ кода.
- Chokidar-cli — наблюдение за изменениями в файлах.
- Precommit-hook — автоматический запуск npm-скриптов.
Почему я выбрал именно их? Просто потому, что они не требуют вообще никакой настройки. Такой подход отлично разгружает голову, открывая дорогу полезным идеям, касающимся разработки. Установим модули, выполнив следующую команду в папке проекта:
$ npm i --save-dev ava standard chokidar-cli precommit-hook
После установки (скорость которой зависит только от настроения NPM), не забудьте создать файл
.gitignore
и добавить в него папку node_modules
. Она в репозитории не нужна.Настройка проекта
Сами по себе, наши инструменты в настройке не нуждаются, но вот проект, всё же, настроить придётся. Правда, здесь всё предельно просто. Откройте
package.json
и добавьте в него следующие скрипты: "scripts": {
"test": "ava",
"lint": "standard",
"dev": "chokidar '**/*.js' -c 'standard && ava'"
},
"pre-commit": ["test", "lint"],
Вот, собственно, и всё. Как только вы выполнит команду
npm run dev
, chokidar
начнёт наблюдать за состоянием файлов, запуская, при необходимости, standard
для статического анализа, и ava
для тестирования кода. Если обнаружатся проблемы, вы тут же об этом узнаете. То же самое касается и внесения изменений в репозиторий. Наша среда не даст зафиксировать транзакцию до тех пор, пока проект не будет успешно проанализирован и протестирован.Здесь хотелось бы обратить внимание на две вещи.
- Не нужно устанавливать
standard
илиava
глобально, так как они исполняются изнутри контекстаnode
. - Так как мы используем
&&
вместо;
в скриптеdev
, тесты не будут вызваны до тех пор, пока код не пройдёт проверку статическим анализатором. Это ускоряет работу.
Как этим пользоваться
Среда разработки рассчитана на программирование в стиле разработки через тестирование (TDD). Как только будет запущен скрипт
dev
, можно создавать тесты, они будут автоматически добавляться к набору испытаний кода, без необходимости перезапуска средства наблюдения за файлами или выполнения любых других операций.Создадим первый тест.
// test/meaningOfLife.test.js
const test = require('ava')
const meaningOfLife = require('../lib/meaningOfLife')
test('Real meaning of life', (t) => {
t.is(meaningOfLife(), 42)
})
После сохранения этого файла система тут же сообщит о том, что один из тестов провален. Исправим это.
// lib/meaningOfLife.js
module.exports = () => 42
Теперь всё работает как надо! Проще некуда. Создадим модуль, который умножает числовые параметры. Сразу же подготовим модульный тест для него, а также посмотрим, правильно ли работает новый модуль с
meaningOfLife
. Это, кстати, будет уже интеграционный, а не модульный тест. Вот код модуля: // lib/multiply.js
module.exports = (number) => {
if (typeof number !== 'number') throw new TypeError('Only numbers can be multiplied!')
return number * 2
}
Вот тест к нему:
// test/multiply.test.js
const test = require('ava')
const multiply = require('../lib/multiply')
test('Can multiply numbers', (t) => {
t.is(multiply(10), 20)
})
test('Throws when you try to multiply non-number value', (t) => {
t.throws(() => multiply('ohai!'), 'Only numbers can be multiplied!')
})
Теперь протестируем всё вместе:
// test/index.test.js
const test = require('ava')
const awesomeModule = require('../index')
test('Works nicely together', (t) => {
t.is(awesomeModule(), 84)
})
И внесём следующее в index.js:
// index.js
const meaningOfLife = require('./lib/meaningOfLife')
const multiply = require('./lib/multiply')
module.exports = () => multiply(meaningOfLife())
Тесты пройдены! Как видите, благодаря простоте инструментов, мы очень быстро приступили к работе над проектом, потратив совсем немного времени на подготовку окружения.
Итоги
Новые сверкающие инструменты часто буквально гипнотизируют программистов, заставляя забыть о главном. А главное — это упрощение и ускорение работы и борьба с ошибками. Обычно, гораздо чаще, чем может показаться, для решения этих задач достаточно самых простых средств. Таких, которые позволяют тратить время на создание программ, а не на настройку вспомогательных систем.
Когда проект начнёт расти, возможно, вы почувствуете, что вам нужно что-нибудь гораздо более продвинутое, нежели простая комбинация ava, standard, chokidar-cli и precommit-hook. Но в большинстве случаев, однако, больше ничего не понадобится. И те простые и понятные инструменты, о которых я рассказал, прослужат вам верой и правдой очень и очень долго.
А в какой среде создаёте программы вы?
Комментарии (2)
9 декабря 2016 в 15:24
0↑
↓
У меня насчёт AVA вопрос:
Предположим, что у меня есть такой код:
import React from 'react'; import styles from './ExampleComponent.css'; import DemoIMG from '../assets/logo.png'; import DemoSVG from '../assets/dummy.svg'; export class ExampleComponent extends React.Component { render () { return (
Этот код работает только благодаря loader-ам Webpack-а. Чем AVA лучше Mocha, если без компиляции кода теста, тест всё равно не завести?
9 декабря 2016 в 15:26
0↑
↓
if (typeof number !== 'number') throw new TypeError('Only numbers can be multiplied!')
Вместо того, чтобы обмазывать такими проверками весь код, а потом еще писать тесты на эти проверки, лучше сразу использовать Typescript.