Ответ 1
Если вы хотите использовать bootstrap как файлы меньшего размера и, кроме того, хотите перестать беспокоиться о связывании и минимизации на вашей машине разработки, а также на вашей производственной машине, вы можете использовать следующий подход.
Примечание: вам не нужно все это, если вы играете только с меньшими файлами, в то время как DEBUGging включен; Но как только вы захотите, чтобы ваше приложение вышло в эфир на производственном сервере, таком как Windows Azure, и все еще хотите просто изменить меньшее количество файлов, не заботясь о процедурах группировки и минимизации... ну... тогда этот подход будет работа
Итак, чтобы решить проблему, я немного застрял, мне пришлось подойти к проблеме по-другому и пришлось модифицировать (см. Модификацию 2 дальше по почте) "BundleSource", который, как я думал, мне бы хотелось.
ТАК НЕ БУДЕТ ЗАПРЕЩАЕТСЯ ПРОЧИТАТЬ 2-ю модификацию/предупреждение рядом с этим ответом!
МОДИФИКАЦИЯ 1)
Таким образом, первая и большая часть задания - это получение пакета без загрузочных файлов. Чтобы сделать это, я взял на себя смелость разбить кусок кода, который я нашел в Интернете, который (если вам нужен только один пакет с меньшим количеством файлов) сам решает мою проблему... если вы не захотите использовать или быть в состоянии использовать несколько меньших пакетов с несколькими базовыми каталогами... Так вот где я действительно нашел подход, который мне очень помог...
... за что я благодарю Кристофа Класа за его блог-запись "Использование ASP.NET для комплектации и минимизации с файлами LESS", которые я случайно и с радостью споткнулся.
Как и я, он попытался использовать LessMinify.cs, который Scott Hanselman показывал в своих речах для работы с 1 LESS файлом вместо простого связывания каждого файла в 1 каталоге, полном LESS файлов.
Но он должен был продлить всю процедуру связывания, как он показывает в своем блоге. Таким образом, решение, которое он предлагает, может связывать 1 меньше файла, который использует импорт для загрузки других меньших файлов. Но поскольку он статически реализует путь, который добавляется в исходный каталог, в котором можно найти меньше файлов... в зависимости от того, какой меньше связок вы определяете, нужно выбрать меньше файла в том же каталоге...
Вот где я взял на себя смелость расширить свое решение немного дальше. Я создал файл LessBundling.cs со следующим содержимым:
using dotless.Core.configuration;
using dotless.Core.Input;
using MvcApplication2.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Web;
using System.Web.Hosting;
using System.Web.Optimization;
namespace MvcApplication2.Extensions
{
// create Less-Minifier (use Type to define source directory of less files [see below at BootstrapFileReader])
public class LessMinify<TFileReader> : CssMinify
where TFileReader : IFileReader
{
public LessMinify() {}
public override void Process(BundleContext context, BundleResponse response)
{
var config = new DotlessConfiguration()
{
MinifyOutput = true,
ImportAllFilesAsLess = true,
CacheEnabled = false,
LessSource = typeof(TFileReader)
};
response.Content = dotless.Core.Less.Parse(response.Content, config);
base.Process(context, response);
}
}
// create a LessStyleBundler to allow initializing LessBundle with a single less file that uses imports
public class LessStyleBundle<TFileReader> : Bundle
where TFileReader : IFileReader
{
public LessStyleBundle(string virtualPath)
: base(virtualPath, new LessMinify<TFileReader>()) {}
public LessStyleBundle(string virtualPath, string cdnPath)
: base(virtualPath, cdnPath, new LessMinify<TFileReader>()) { }
}
// create abstract VirtualFileReader from dotless-IFileReader as a Base for localized
internal abstract class VirtualFileReader : IFileReader
{
public byte[] GetBinaryFileContents(string fileName)
{
fileName = GetFullPath(fileName);
return File.ReadAllBytes(fileName);
}
public string GetFileContents(string fileName)
{
fileName = GetFullPath(fileName);
return File.ReadAllText(fileName);
}
public bool DoesFileExist(string fileName)
{
fileName = GetFullPath(fileName);
return File.Exists(fileName);
}
public string GetFullPath(string path)
{
return HostingEnvironment.MapPath(SourceDirectory + path);
}
public abstract string SourceDirectory {get;}
// implement to return Path to location of less files
// e. g. return "~/Content/bootstrap/less/";
}
// create BootstrapFileReader overwriting the Path where to find the Bootstrap-Less-Files
internal sealed class BootstrapFileReader : VirtualFileReader
{
public override string SourceDirectory
{
get { return "~/Content/bootstrap/less/"; }
}
}
}
Итак, что это на самом деле делает?
- LessMinify расширяет класс CssMinify и поэтому приносит все необходимое для минимизации файлов css
- Важным отличием от "обычного" набора является то, что вы создаете новую Dotless-Configuration с помощью LessSource, определенного как typeof (TFileReader)...
- Используя <TFileReader> вы можете определить класс, который будет содержать исходный каталог, в котором поставщик / minifier будет искать меньше файлов, которые будут учитываться
- LessStyleBundle расширяет Bundle и поэтому приносит все необходимое для объединения файлов
- В этом классе я снова использую TFileReader, так как здесь будет создан экземпляр LessMinify (er)
- VirtualFileReader реализует IFileReader, который представляет собой бесцельный интерфейс, определяющий все методы, необходимые для анализа меньшего количества файлов и предоставления информации о том, где искать файлы для импорта
- Чтобы распространить решение Kristof на проблему, я добавил абстрактное свойство SourceDirectory... требуя, чтобы я также создал абстрактный класс VirtualFileReader
Теперь с помощью этой настройки вы можете создать столько LessFileReaders, сколько хотите. Вам просто нужно расширить абстрактный VirtualFileReader, как это видно в
- BootstrapFileReader расширяет VirtualFileReader
- Единственная цель BootstrapFileReader состоит в том, чтобы иметь свойство-getter для SourceDirectory, в котором поставщик / minifier найдет меньше файлов, которые необходимо импортировать
В моем случае Bootstraps Less-Files находится в ~/Content/bootstrap/less, который должен быть по умолчанию, если вы устанавливаете "twitter.bootstrap.less" -nugget.
Если у вас будет другой каталог в вашем приложении, в котором будет меньше файла, который снова будет иметь несколько импорта, вы просто создадите новый класс, расширяющий VirtualFileReader, и определите свойство-getter для SourceDirectory, чтобы вернуть соответствующий путь
Если вы хотите использовать этот метод Bundling для фактического связывания и минимизации меньших файлов в производственной среде, вы просто добавляете InstantStyleBundle-instantion к BundlerConfig.cs:
bundles.Add(new LessStyleBundle<BootstrapFileReader>("~/bundles/BootstrapCSS")
.Include("~/Content/bootstrap/less/bootstrap.less"));
и, конечно, ваш _Layout.cshtml должен также знать о готовом комплекте
@Styles.Render("~/bundles/BootstrapCSS")
МОДИФИКАЦИЯ 2)
теперь незначительная модификация, которую я также должен был добавить, чтобы получить эту работу
В моей первой попытке связать bootstrap.less я использовал этот
bundles.Add(new LessStyleBundle<BootstrapFileReader>("~/Content/BootstrapCSS")
.Include("~/Content/bootstrap/less/bootstrap.less"));
Я думал, что буду использовать Content в маршрутах для CSS/Less и Bundles в маршрутах для Javascript.
Но это не работает из коробки. ASP.net не позволяет создавать пакет, который начинается с ~/Content. Вы получите отказ авторизации 403. Поэтому самым простым решением для этого является использование ~/bundles:
bundles.Add(new LessStyleBundle<BootstrapFileReader>("~/bundles/BootstrapCSS")
.Include("~/Content/bootstrap/less/bootstrap.less"));
Поскольку для этой проблемы не так много реальных решений, я надеюсь, что это поможет хотя бы некоторым из вас, если вы планируете интегрировать twitter bootstrap в ваше приложение asp.net mvc4.
С наилучшими пожеланиями, Инго