JS/CSS Minify с возможностью аплоада на Azure

29 Фев
2012

На днях мне понадобилось простое и универсальное решение для упаковки всех JS и CSS файлов в один, а так же их минификация, с возможностью автоматической загрузки на Azure Blob. Потратив пару часов на изучение Cdn Helpers, решил-таки сесть и написать свой небольшой класс.
namespace MvcApplication1
{
public static class MinifierClass
{
private const string Folder = "cdncontent"; // Название папки в которой будут храниться файлы CSS и JS на Azure blob
private const string CdnNamespace = "az148059"; // Название конечной точки CDN
private const string BlobEndpoint = "DefaultEndpointsProtocol=http;AccountName=habrauser;AccountKey=Первичный ключ доступа к контейнеру блоб";

private static readonly CloudStorageAccount StorageAccount = CloudStorageAccount.Parse( BlobEndpoint );

private static bool _flag;
private static string _hashname;

private static bool _flagCss;
private static string _hashnameCss;

public static string RegisterJs( params string[] files )
{
if ( !_flag )
{
var fileName = FileWork.GetStamp() + ".js";
BlobWork( fileName, new Minifier().MinifyJavaScript( FileWork.FilesInString( files ) ), "text\\javascript" );
_flag = true;
_hashname = fileName;
return string.Format( "http://{0}.vo.msecnd.net/{1}/{2}", CdnNamespace, Folder, fileName );
}
return string.Format( "http://{0}.vo.msecnd.net/{1}/{2}", CdnNamespace, Folder, _hashname );
}

public static string RegisterCss( params string[] files )
{
if ( !_flagCss )
{
var fileName = FileWork.GetStamp() + ".css";
BlobWork( fileName, new Minifier().MinifyStyleSheet( FileWork.FilesInString( files ) ), "text\\css" );
_flagCss = true;
_hashnameCss = fileName;
return string.Format( "http://{0}.vo.msecnd.net/{1}/{2}", CdnNamespace, Folder, fileName );
}
return string.Format( "http://{0}.vo.msecnd.net/{1}/{2}", CdnNamespace, Folder, _hashnameCss );
}

private static void BlobWork( string filename, string data, string contentType )
{
var blobStorage = StorageAccount.CreateCloudBlobClient();
var container = blobStorage.GetContainerReference( Folder );
container.CreateIfNotExist();
container.SetPermissions( new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Blob } );
var blob = blobStorage.GetBlockBlobReference( string.Format( @"{0}/{1}", Folder, filename ) );
blob.Properties.ContentType = contentType;
blob.UploadText( data );
}
}

/// /// Работа с файлами Js, Css, хешами
///
internal class FileWork
{
/// /// Формирование строки кода из указанных файлов
///
/// "~/Scripts/jquery.js","~/Scripts/core.js"
/// Строковое представление всех данных из файлов files
static public string FilesInString( string[] files )
{
var ret = new StringBuilder();
foreach ( var source in files.Select( file => Path.IsPathRooted( file ) ? file : HostingEnvironment.MapPath( file ) ).Select( File.ReadAllText ) )
ret.AppendLine( source );
return ret.ToString();
}

/// /// Првайдер для MD5
///
static readonly MD5CryptoServiceProvider Md5CryptoServiceProvider = new MD5CryptoServiceProvider();

/// /// Создание уникального штампа MD5
///
/// 32 символа в string
public static string GetStamp()
{
var stringBuilder = new StringBuilder();
var bs = Encoding.UTF8.GetBytes( string.Format( "{0}:{1}", DateTime.Now.ToString( CultureInfo.InvariantCulture ), new Random().Next( int.MaxValue ) ) );
bs = Md5CryptoServiceProvider.ComputeHash( bs );
foreach ( var b in bs )
stringBuilder.Append( b.ToString( "x2" ).ToLower() );
return stringBuilder.ToString();
}
}
}


 @ViewBag.Title
<link href="@MinifierClass.RegisterCss( "~/Content/Site.css" )" rel="stylesheet" type="text/css" />
<script src="@MinifierClass.RegisterJs( "~/Scripts/jquery-1.5.1.min.js", "~/Scripts/modernizr-1.7.min.js" )" type="text/javascript">


Для работы данного метода, указанный выше Cdn Endpoint должен указывать на хранилище Azure Blob.
По материалам Хабрахабр.



загрузка...

Комментарии:

Наверх