Как я могу автоматически сжимать и сворачивать файлы JavaScript в приложении ASP.NET MVC?

StackOverflow https://stackoverflow.com/questions/1224292

Вопрос

Итак, у меня есть ASP.NET Приложение MVC, которое ссылается на несколько файлов javascript в разных местах (в главном каталоге сайта и дополнительных ссылках в нескольких представлениях).

Я хотел бы знать, существует ли автоматический способ сжатия и минимизации таких ссылок в один js-файл, где это возможно.Такой , что это ...

<script src="<%= ResolveUrl("~") %>Content/ExtJS/Ext.ux.grid.GridSummary/Ext.ux.grid.GridSummary.js" type="text/javascript"></script>
<script src="<%= ResolveUrl("~") %>Content/ExtJS/ext.ux.rating/ext.ux.ratingplugin.js" type="text/javascript"></script>
<script src="<%= ResolveUrl("~") %>Content/ExtJS/ext-starslider/ext-starslider.js" type="text/javascript"></script>
<script src="<%= ResolveUrl("~") %>Content/ExtJS/ext.ux.dollarfield.js" type="text/javascript"></script>
<script src="<%= ResolveUrl("~") %>Content/ExtJS/ext.ux.combobox.js" type="text/javascript"></script>
<script src="<%= ResolveUrl("~") %>Content/ExtJS/ext.ux.datepickerplus/ext.ux.datepickerplus-min.js" type="text/javascript"></script>
<script src="<%= ResolveUrl("~") %>Content/ExtJS/SessionProvider.js" type="text/javascript"></script>
<script src="<%= ResolveUrl("~") %>Content/ExtJS/TabCloseMenu.js" type="text/javascript"></script>
<script src="<%= ResolveUrl("~") %>Content/ActivityViewer/ActivityForm.js" type="text/javascript"></script>
<script src="<%= ResolveUrl("~") %>Content/ActivityViewer/UserForm.js" type="text/javascript"></script>
<script src="<%= ResolveUrl("~") %>Content/ActivityViewer/SwappedGrid.js" type="text/javascript"></script>
<script src="<%= ResolveUrl("~") %>Content/ActivityViewer/Tree.js" type="text/javascript"></script>

...можно было бы свести к чему - то подобному этому ...

<script src="<%= ResolveUrl("~") %>Content/MyViewPage-min.js" type="text/javascript"></script>

Спасибо

Это было полезно?

Решение

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

У меня есть раздел, который гласит:

<Target Name="BeforeDeploy">

        <ReadLinesFromFile File="%(JsFile.Identity)">
            <Output TaskParameter="Lines" ItemName="JsLines"/>
        </ReadLinesFromFile>

        <WriteLinesToFile File="Scripts\all.js" Lines="@(JsLines)" Overwrite="true"/>

        <Exec Command="java -jar tools\yuicompressor-2.4.2.jar Scripts\all.js -o Scripts\all-min.js"></Exec>

    </Target>

И в моем главном файле страницы я использую:

if (HttpContext.Current.IsDebuggingEnabled)
   {%>
    <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/jquery-1.3.2.js")%>"></script>
    <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/jquery-ui-1.7.2.min.js")%>"></script>
    <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/jquery.form.js")%>"></script>
    <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/jquery.metadata.js")%>"></script>
    <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/jquery.validate.js")%>"></script>
    <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/additional-methods.js")%>"></script>
    <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/form-interaction.js")%>"></script>
    <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/morevalidation.js")%>"></script>
    <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/showdown.js") %>"></script>
<%
   }  else  {%> 
  <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/all-min.js")%>"></script>
<% } %>

Сценарий сборки берет все файлы из раздела и объединяет их все вместе.Затем я использую минификатор YUI, чтобы получить уменьшенную версию javascript.Поскольку это обслуживается IIS, я бы предпочел включить сжатие в IIS, чтобы получить сжатие gzip.**** Добавлено **** Мой сценарий развертывания - это сценарий MSBuild.Я также использую отличные задачи сообщества MSBuild (http://msbuildtasks.tigris.org/), чтобы помочь развернуть приложение.

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

В следующем разделе будет запущена сборка asp.net компилятор для копирования приложения на целевой диск.(На предыдущем шаге я просто запускаю exec net use commands и сопоставляю сетевой общий диск).

<Target Name="Precompile" DependsOnTargets="build;remoteconnect;GetTime">

        <MakeDir Directories="%(WebApplication.SharePath)\$(buildDate)" />

        <Message Text="Precompiling Website to %(WebApplication.SharePath)\$(buildDate)" />

        <AspNetCompiler
            VirtualPath="/%(WebApplication.VirtualDirectoryPath)"
            PhysicalPath="%(WebApplication.PhysicalPath)"
            TargetPath="%(WebApplication.SharePath)\$(buildDate)"
            Force="true"
            Updateable="true"
            Debug="$(Debug)"
            />
        <Message Text="copying the correct configuration files over" />

        <Exec Command="xcopy $(ConfigurationPath) %(WebApplication.SharePath)\$(buildDate) /S /E /Y" />

     </Target>

После того, как все проекты решений скопированы, я запускаю это:

    <Target Name="_deploy">
        <Message Text="Removing Old Virtual Directory" />
        <WebDirectoryDelete
            VirtualDirectoryName="%(WebApplication.VirtualDirectoryPath)"
            ServerName="$(IISServer)"
            ContinueOnError="true"
            Username="$(username)"  
            HostHeaderName="$(HostHeader)"
            />

        <Message Text="Creating New Virtual Directory" />

        <WebDirectoryCreate 
            VirtualDirectoryName="%(WebApplication.VirtualDirectoryPath)" 
            VirtualDirectoryPhysicalPath="%(WebApplication.IISPath)\$(buildDate)"
            ServerName="$(IISServer)"
            EnableDefaultDoc="true"
            DefaultDoc="%(WebApplication.DefaultDocument)"
            Username="$(username)"
            HostHeaderName="$(HostHeader)"
            />
</Target>

Этого должно быть достаточно, чтобы вы начали автоматизировать развертывание.Я поместил все это в отдельный файл под названием Aspnetdeploy.msbuild.Я просто msbuild / t: Target всякий раз, когда мне нужно выполнить развертывание в среде.

Другие советы

На самом деле есть гораздо более простой способ, используя Проекты веб-развертывания (ВДП).WDP будет управлять сложностями, связанными с aspnet__компилятор и aspnet__слияние инструмент.Вы можете настроить процесс с помощью пользовательского интерфейса внутри Visual Studio.

Что касается сжатия файлов js, вы можете оставить все свои файлы js на месте и просто сжать эти файлы в процессе сборки.Итак, в WDP вы бы объявили что-то вроде этого:

<Project>
   REMOVE CONTENT HERE FOR WEB

<Import 
  Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
<!-- Extend the build process -->
<PropertyGroup>
  <BuildDependsOn>
    $(BuildDependsOn);
    CompressJavascript
  </BuildDependsOn>
</PropertyGroup>

<Target Name="CompressJavascript">
  <ItemGroup>
    <_JSFilesToCompress Include="$(OutputPath)Scripts\**\*.js" />
  </ItemGroup>
  <Message Text="Compresing Javascript files" Importance="high" />
  <JSCompress Files="@(_JSFilesToCompress)" />
</Target>
</Project>

При этом используется задача JSCompress MSBuild из Задачи сообщества MSBuild который, я думаю, основан на JSMin.

Идея в том, чтобы оставить все ваши js-файлы такими, какие они есть (т.е.отлаживаемый / читаемый человеком).Когда вы создадите свой WDP, он сначала скопирует js-файлы в Выходной путь и тогда Сжимать JavaScript target вызывается для минимизации файлов js.Это не изменяет ваши исходные файлы, только те, что находятся в выходной папке проекта WDP.Затем вы развертываете файлы по выходному пути WDPs, который включает предварительно скомпилированный сайт.Я описал именно этот сценарий в своей книге (ссылка под моим именем).

Вы также можете позволить WDP обрабатывать создание виртуального каталога, просто установите флажок и введите имя виртуального каталога.

Для некоторых ссылок на MSBuild:

Сайед Ибрагим Хашими

Моя Книга: Внутри движка сборки Microsoft :Использование MSBuild и Team Foundation Build

Скотт Хансельман недавно написал в блоге о объединение и перемещение скриптов в статические файлы, в основном используя ScriptManager с CompositeScript ссылки и Path атрибут:

<asp:ScriptManager runat="server">
    <CompositeScript path="http://www.example.com/1.js">
        <Scripts>
            <asp:ScriptReference />
            <asp:ScriptReference />
            <!-- etc. -->
        </Scripts>
    </CompositeScript>
</asp:ScriptManager>

Что касается сокращения статических файлов, вам, вероятно, придется (и следует) использовать инструменты сокращения во время сборки / развертывания.

MVC Contrib.Включая обработку хорошо подходит для этой ситуации.В приведенном примере у меня есть модель с коллекцией стилей (string).Также, если мне нужно добавить пользовательский стиль / JS на страницу, я тоже могу это сделать.Затем вызов Html.RenderCss объединяет все стили / js в один файл и минимизирует его.

<head>
<% foreach (var styleSheet in Model.Styles) {%>
<% Html.IncludeCss(styleSheet)); 

<% } %>
<% Html.IncludeCss("~/Scripts/jquery.1.4.2.js")); 

<%= Html.RenderCss() %>
</head>

То же самое и для javascript.

<%
Html.IncludeJs("~/scripts/ConsoleLogger.js");
Html.IncludeJs("~/scripts/jquery.log.js");
Html.IncludeJs("~/Scripts/2010.1.416/jquery.validate.min.js");
Html.IncludeJs("~/Scripts/2010.1.416/telerik.calendar.min.js");
Html.IncludeJs("~/Scripts/2010.1.416/telerik.datepicker.js");
Html.IncludeJs("~/scripts/jquery.ui.datepicker-en-GB.js");
%>

Когда это отображается клиенту, результат выглядит следующим образом (уменьшенный объединенный 1 файл)

<link rel='stylesheet' type='text/css' href='/include/css/-QdUg9EnX5mpI0e4aKAaOySIbno%40'/>

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

За считанные минуты я поднялся с низкого балла F до B.(24 сценария уменьшились до 2)...Потрясающе!И падение на 40 кб.

Очевидным недостатком является то, что сервер выполняет сжатие "на лету".Я думаю, что есть варианты кэширования объединенного скрипта на определенный период, который, однако, быстро облегчил бы эту проблему.

Как предлагали другие, вам было бы лучше создать статическую уменьшенную сборку.В качестве альтернативы, доступна версия YUICompressor для .NET здесь: http://www.codeplex.com/YUICompressor

Вы могли бы использовать MvcContrib.Включить обработку.IT:

  • Поддерживает CSS и JS
  • Объединяет в один запрос
  • Уменьшает
  • Сжимаемые файлы Gzip/Deflate
  • Настраивает заголовки кэша
  • Использует методы расширения HtmlHelper для регистрации включений, чтобы затем объединить их во время выполнения
  • Подключается через IoC

Под крышкой он использует YUICompressor.

Я написал кое-что, чтобы справиться с этим автоматически.Он использует компилятор закрытия Google.Вы можете прочитать код здесь:

http://www.picnet.com.au/blogs/Guido/post/2009/12/10/Javascript-runtime-compilation-using-AspNet-and-Googles-Closure-Compiler.aspx

Спасибо

Гвидо

Я знаю, что это старый вопрос, но он возник первым, когда я проводил несколько поисков по минификации.Я бы рекомендовал использовать Gruntjs, http://gruntjs.com.Это полноценный инструмент для веб-сборки.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top