Подтвердить что ты не робот

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

Итак, у меня есть приложение 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>

Спасибо

4b9b3361

Ответ 1

Я лично считаю, что сохранение файлов во время разработки неоценимо и что во время производства это когда-то похожее на это. Поэтому я изменил свое развертывание 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>
<% } %>

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

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

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

<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, когда мне нужно развернуть среду.

Ответ 2

На самом деле гораздо проще использовать Проекты веб-развертывания (WDP). WDP будет управлять сложностями инструмента aspnet__compiler и aspnet__merge. Вы можете настроить процесс с помощью пользовательского интерфейса внутри 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 файлы в OutputPath, а затем вызывается цель CompressJavascript, чтобы свести к минимуму файлы js. Это не изменяет исходные исходные файлы, а только те, которые находятся в выходной папке проекта WDP. Затем вы развертываете файлы в пути вывода WDP, который включает в себя предварительно скомпилированный сайт. Я описал этот точный сценарий в своей книге (ссылка ниже моего имени).

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

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

Сказал Ибрагим Хашими

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

Ответ 3

Скотт Ханзельман недавно написал о комбинирование и перемещение скриптов в статические файлы, в основном используя 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>

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

Ответ 4

MvcContrib.IncludeHandling хорошо работает для этой ситуации. В примере у меня есть модель с набором стилей (строка). Также, если мне нужно добавить пользовательский стиль /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 также предлагает флаг отладки, который при включении не минимизирует или не объединяет скрипты, когда они установлены, что очень полезно.

В течение нескольких минут я пошел от Yslow от F до B. (24 скрипта до 2)... Удивительно! И падение на 40 килобайт.

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

Ответ 5

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

Ответ 6

Вы можете использовать MvcContrib.IncludeHandling. Это:

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

Под обложками используется YUICompressor.

Ответ 8

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