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

Едва ли скрытая функция, но это смотрело на меня как вуду, в первый раз, когда я видел что-то вроде этого:


void callback(const char *msg, void *data)
{
    // do something with msg, e.g.
    printf("%s\n", msg);

    return;
    data = NULL;
}

причина этой конструкции, это при компиляции этого с-Wextra и без "данных = ПУСТОЙ УКАЗАТЕЛЬ"; - строка, gcc выложит предупреждение о неиспользованных параметрах. Но с этой бесполезной строкой Вы не получаете предупреждение.

РЕДАКТИРОВАНИЕ: Я знаю, что существуют другие (лучшие) способы предотвратить те предупреждения. Это просто выглядело странным для меня, в первый раз, когда я видел это.

36
задан Matt 22 July 2016 в 21:26
поделиться

7 ответов

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

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

<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 и подключаю сетевой диск.)

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

24
ответ дан 27 November 2019 в 06:10
поделиться

На самом деле есть гораздо более простой способ использовать Web Deployment Projects (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

8
ответ дан 27 November 2019 в 06:10
поделиться

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

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

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

4
ответ дан 27 November 2019 в 06:10
поделиться

As others have suggested, you'd be best off creating a static minified build. Alternatively, there's a version of YUICompressor available for .NET here: http://www.codeplex.com/YUICompressor

2
ответ дан 27 November 2019 в 06:10
поделиться

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

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

Спасибо

Guido

0
ответ дан 27 November 2019 в 06:10
поделиться

На http://www.drasticdata.nl есть несколько интересных графических приложений на основе флэш-памяти и карт treemap. Иерархическая гистограмма или динамическая карта может представлять интерес для вашей задачи.

-121--3235995-

я нашел более простое решение, просто добавьте к ссылке поведение щелчком мыши:

onclick='return false;'

ваши ссылки автоматически изменятся на target = «_ self» .

но если вы хотите перейти к другому целевому объекту или удалить атрибут с помощью pheraps, следует добавить прослушиватель и заменить javascript следующим образом:

  GEvent.addListener(map,"infowindowprepareopen", function(iwtabs) {
  iwtabs[0].contentElem.innerHTML = iwtabs[0].contentElem.innerHTML.replace("_blank", "_parent");
  });

это очень полезно для использования при наличии ссылки на lightbox (или подобной) внутри окна infowindow.

ура

-121--4692026-

Можно использовать MvcContribut.IncludeHandling. Он:

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

в разделе

2
ответ дан 27 November 2019 в 06:10
поделиться

MvcContrib.IncludeHandling хорошо подходит для этой ситуации. В этом примере у меня есть Модель с набором стилей (строка). Также, если мне нужно добавить пользовательский стиль / JS на страницу, это тоже можно сделать. {{ 1}} Затем вызов 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кбс.

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

4
ответ дан 27 November 2019 в 06:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: