ASP.NET и сжатие клиентского кода

ASP.NET и сжатие клиентского кода

Со времён MSIE4 и блокнота, Я люблю комментировать написанный код. Но одно дело, когда проект создаётся для себя, или при компиляции комментарии не попадут конечному пользователю. И совсем другое дело, когда написанные комментарии могут попасть конечному клиенту. Во первых, они ему не нужны, а во вторых, в комментариях может содержаться некий текст, который может подвергнуть опасности этот или другой проект. И в третьих, содержимые в клиентском коде (HTML, JS, CSS) комментарии, даже в сжатом виде, создают паразитный трафик.Изучая такой код иногда можно натолкнуться на интересные вещи. Вот, к примеру, один из кусков комментариев на одном всеми известном сайте: … //ubepua07/default/main/SonyStyle/WORKAREA/Common/SonyStyleStorefrontAssetStore/include/CMSpot …А внизу всего этого хозяйства красуется вот такой текст:… (Developers should log their changes, including line number for reference here) …Вот пример комментариев от компании Яндекс:"Любишь заглядывать в консоль? А может и js умеешь писать?…"

  1. Клиентский код в виде ресурсов в сборке
  2. Клиентский код в качестве файлов WebForms или MVC решения
  3. Клиентский код, находящийся на сайте для статичных ресурсов (http://static.sitename.com)

В тексте статьи Я использую самописный инструмент: SourceCruncher. Есть намного более эффективные средства для сжатия кода вёрстки HTML, CSS и JS скриптов с поддержкой затенения и более эффективного процесса сжатия. (Я написал свой вариант для более детального понимания процесса парсинга браузерами кода вёрстки и скриптов.)

Клиентский код в виде ресурсов в сборке.

Я начал искать варианты решения задачи используя подручные средства. И для сжатия ресурсов внутри сборки решение нашлось достаточно быстро. На идею про сжатие скрипта в сборке меня натолкнул скрипт, который я использовал до появления в 10ой студии опции, с видоизменением файлов Web.config для разных конфиураций выкладывания решения (Идея была не моя и автора идеи Я забыл). В Visual Studio можно написать команду выполняемую до и после сборки проекта.

(Project Properties → Build Events → )Для того, чтобы работал этот метод, необходимо прописать команду копирования наших клиентских файлов во временный файл. За это отвечает команда копирования:copy "$(ProjectDir)Script.js" "$(ProjectDir)Script.orig.js" /V /YЗатем, необходимо применить сжатие для файла скрипта. В данном проекте, программа для сжатия находится в корневой папке:"$(SolutionDir)..\..\SourceCruncher.exe" /IO:"$(ProjectDir)Script.js" /YПосле того, как сборка собралась, необходимо вернуть наш клиентский скрипт в оригинальный вид. Для этого, добавляем в событие "Post-build event command line:" код перемещения сжатого варианта файла на не сжатый вариант:move /Y "$(ProjectDir)Script.orig.js" "$(ProjectDir)Script.js" Важно! Не забудьте включить событие post-build только после успешной сборки:Run the post-build event: On successful build.Иначе, при ошибки компиляции файл Script.js останется сжатым.В данном примере есть одно ограничение. Если необходимо отладить клиентский код, то необходимо будет вручную убрать код копирования и сжимания js файла. Или захардкодить для отладочного примера ссылку на оригинальный файл скрипта, а не на сжатый файл ресурса из сборки. Это связано с тем, что Build Events выполняется во всех конфигурациях.

Клиентский код в качестве файлов WebForms или MVC решения

  1. Физического доступа на сервер может не быть.
  2. Действие происходит не явно.

Пришлось искать решение в режиме "До выкладывания". Сначала Я решил делать это через события "Build Events" как и в случае с кодом ресурсов сборки. Но они происходят каждый раз после сборки проекта, а не перед выкладыванием. Во первых, затормаживая сам процесс сборки (особенно если учесть что клиентского кода может быть очень много), а во вторых, усложняет процесс поиска ошибок в клиентском коде.Т.к., в большинстве случаев, я выкладываю проект через команду "Publish Web" (т.е. имеется физический доступ к серверу), в студии, то Я решил копать в эту сторону и попытаться сжимать файлы сразу после выкладывания проекта на рабочий сервер.Вот тут я столкнулся с первой проблемой: Для события публикации в студии нет стандартного UI.Немного погуглив, необходимое событие нашлось в EnvDTE для студии, которое используется для написания Add-In"ов.

  1. Подлключаюсь к IIS через ADSI
  2. Беру путь папки в которой у меня работает решение
  3. Удаляю всё содержимое папки _PrevVersion
  4. Копирую всё решение из этой папки в папку _PrevVersion
  5. Переключаю решение с рабочей папки на папку _PrevVersion
  6. Выкладываю решение в рабочую папку
  7. Переключаю папки с _PrevVersion на рабочую папку.

Но такой подход занимает много времени, несмотря на то, что всё это решается автоматом. А если ещё весь проект лежит на DFS, то сервера будут заниматься лишней работой перетасовывания файлов.Пришлось копать дальше… В документации на разработку Ad-In"ов для студии нет ни одного упоминания о пути куда выкладывалось решение. В результате, самым прямолинейным путём осталось копать память. К моему облегчению, код публикации написан на управляемом коде, так что использование рефлексии помогло найти место переменной для VS 2005 и 2008 быстро. Для VS 2010 место переменной, где хранится путь к папке, куда выкладывалось решение пришлось поискать подольше, т.к. разработчики добавили профили выкладывания (Publish Profile).В результате, получился Add-In позволяющий выполнять произвольные команды перед и после выкладывания проекта.

Прописанные комманды сохраняются в .sln файле решения, так что все разработчики решения у которых будет стоять этот Add-In смогут выложить решение с применением необходимого сжатия. Проблемы: При использовании TFS 2010 есть проблема (ссылка больше не доступна). Соответственно, при использовании VS9 и VS10, при открытии решения любым разработчиком, sln файл будет взят разработчиком на изменение автоматически.Если Вы пользуетесь VSS или Tortoise, то таких проблем нет.Есть ещё одна проблема связанная с TFS, которую Я пока до конца не изучил: Если .sln файл взят на изменение другим разработчиком, то плагин не может прочитать команды для сжатия из sln файла.

📎📎📎📎📎📎📎📎📎📎