Увиденный недавно топик, про валидацию css в Visual Studio подстегнул к написанию похожей вещи про валидацию Ява скрипта.
Когда яваскрипт в веб-проекте занимает достаточно большую долю кода, и клиентские скрипты вырастают за рамки "инлайн-скриптов" с одной-двумя строчками вызова jquery-плагинов, вопрос проверки их валидности встает достаточно явно (даже для .net-разработчиков, достаточно далеких от js в принципе :)).
В идеале - хотелось иметь компилятор, который при сборке проекта "компилировал" бы и яваскрипт, с привычным указанием ошибок/предупреждений в окне VS.
Для подобной компиляции уже написан ряд утилит, и я даже сделал небольшой обзор существующих решений.
Если кратко, то проверять яваскрипт можно с помощью jslint, jshint и google closure. Нетрудно догадаться, что у последнего возможности наиболее широкие, и для его интеграции в Visual Studio существует как минимум пара готовых решений.
В этой статье я расскажу об еще одной утилите интеграции google closure в Visual Studio, а именно - jsvalidator, небольшой open-source проект, который и был мной написан после вышеупомянутого анализа.
Ключевое отличие моей реализации - в простоте интеграции и возможности конфигурирования отображения определенных типов предупреждений.
JsValidator - это утилита, запускаемая по post-build-event'у с json-like конфигурационным файлом, проверяющая яваскрипт с помощью java-библиотеки google closure. Из этого следует и первое требование - для работы утилиты необходима установленная на компьютере java (с java.exe добавленным в системные пути (system PATH)).
После интеграции утилиты на каждый билд в вашей Visual Studio будет нечто вроде:
(в данном случае утилита сообщает нам о необъявленной переменной asd, по двойному клику на ошибке откроется js-файл на строчке с ошибкой, как мы и привыкли).
Для интеграции jsvalidator'a в проект достаточно установить nuget-пакет JsValidator. Если вы не используете нугет, то можно все шаги, которые пакет сделает автоматически, проделать вручную:
Скачать бинарники библиотеки и распаковать например в папку $(SolutionDir)/JsValidatorBin.
Создать конфигурационный файл в ASP.Net проекте (например, в Scripts/jsvalidator/config.js). В простейшем случае он может выглядеть так:
{ "inputs": [ "../_test.js" ] }
Путь к файлу _test.js может быть заменен на путь к любому js-файлу вашего проекта (или папке с js-файлами). Все пути должны указываться относительно расположения конфигурационного файла config.js.
Добавить JsValidator как post-build-event (Project/Properties/Build events/Post-build event command line) к вашему asp.net проекту. Строка post-build-event'a может выглядеть так:
"$(SolutionDir)JsValidatorBin\jsvalidator.exe" "$(ProjectDir)Scripts\jsvalidator\config.js"
(если вы распаковывали jsvalidator в пути отличные от примеров, то пути нужно будет исправить)
Вот и всё! Скомпилируйте ваш проект и убедитесь, что в ваших яваскриптах ошибок нет :)
Выше я привел пример простейшего конфигурационного файла, состоящего из одной строчки. Реальные конфиги не намного сложнее. Вот пример одного из них:
{
inputs: [ "../../Scripts/zw_Runtime.js", "../../Scripts/UC/", "../../Scripts/jquery.common.js"],
externs: ["//jquery-1.7.js"],
IgnoreAllWarnings: "true",
Warnings: [".* is never defined"]
}
Расшифрую, за что отвечает каждый из параметров:
inputs (массив строк). Специфицирует пути к файлам/папкам для проверки. Самая простая, очевидная и нужная опция :)
externs (массив строк). Специфицирует внешние библиотеки, необходимые для валидации (jquery, mootols, и.т.д.). Аналог параметра externs в google closure. У гугла есть ряд "документированных" версий популярных библиотек, подготовленных к подключению в качестве внешних. Библиотеки из этого источника могут быть использованы с помощью префикса "//". В примере выше мы говорим, что в наших файлах возможно использование библиотеки jquery версии 1.7.
IgnoreAllWarnings (bool). "true" или "false" (по умолчанию - "false"). Найденные "предупреждения" игнорируются (выводятся только найденные "ошибки)
Warnings (массив строк). Список регекспов; подходящие под регексп "предупреждения" переводятся в статус "ошибок".
Хочется заострить внимание на параметре Warnings, потому что именно он отсутсвовал в других реализациях и подтолкнул к написанию велосипеда.
Google Closure сортирует все "подозрительные области" яваскрипта на ошибки и предупреждения. Подчас хочется некоторые предупреждения перевести в статус ошибок, чтобы их невозможно было игнорировать (warning'ов генерируется обычно достаточно много, и смысла анализировать/исправлять их все обычно нет). Для этого и существует опция Warnings. Как сказано выше, если предупреждение подпадает под один из включенных регекспов, оно переходит в категорию "ошибка".
Есть еще некоторые опции, которые не упомянуты в примере, но могут оказаться полезными:
TreatNoJavaAsWarning (bool). Значения "true" или "false" (по умолчанию - "false", то есть при отсутствии на компьютере установленной Java будет сгенерирована ошибка)
IgnoreWarnings (массив строк). Список регекспов, подходящие под регексп "предупреждения" отметаются.
Есть и некоторые другие параметры, которые зеркалируют параметры closure compiler'a. Изменение этих параметров обычно не требуется, они описаны детальнее на странице проекта (CompilationLevel, WarningLevel, Ccargs).
Если кому-то пригодится - отпишите, пожалуйста, success-story и используемые параметры конфига :)