Gra*_*ark 24 bundle less asp.net-mvc-4
我正在尝试在我的web项目中使用LESS文件,并将MVC 4捆绑功能调用到dotLess库中以将LESS转换为CSS,然后缩小结果并将其提供给浏览器.
我在ASP.NET站点上找到了一个示例(在LESS,CoffeeScript,SCSS,Sass Bundling标题下).这给了我一个LessTransform看起来像这样的类:
public class LessTransform : IBundleTransform
{
public void Process(BundleContext context, BundleResponse response)
{
response.Content = dotless.Core.Less.Parse(response.Content);
response.ContentType = "text/css";
}
}
Run Code Online (Sandbox Code Playgroud)
我BundleConfig班上的这一行:
bundles.Add(new Bundle(
"~/Content/lessTest",
new LessTransform(),
new CssMinify()).Include("~/Content/less/test.less"));
Run Code Online (Sandbox Code Playgroud)
最后我在_Layout.cshtml中有以下行<head>:
@Styles.Render("~/Content/lessTest")
Run Code Online (Sandbox Code Playgroud)
如果我将站点设置为调试模式,则会将其呈现给浏览器:
<link href="/Content/less/test.less" rel="stylesheet"/>
Run Code Online (Sandbox Code Playgroud)
应用.less文件中的规则,并在该链接后显示LESS已正确转换为CSS.
但是,如果我将网站置于发布模式,则会显示出来:
<link href="/Content/less?v=lEs-HID6XUz3s2qkJ35Lvnwwq677wTaIiry6fuX8gz01" rel="stylesheet"/>
Run Code Online (Sandbox Code Playgroud)
无法应用.less文件中的规则,因为在链接后出现IIS的404错误.
所以捆绑似乎出了问题.如何让它在发布模式下工作,或者如何找出确切的错误?
Dav*_*and 15
作为已接受答案的补充,我创建了一个LessBundle类,它是StyleBundle类的Less eqivalent.
LessBundle.cs代码是:
using System.Web.Optimization;
namespace MyProject
{
public class LessBundle : Bundle
{
public LessBundle(string virtualPath) : base(virtualPath, new IBundleTransform[] {new LessTransform(), new CssMinify()})
{
}
public LessBundle(string virtualPath, string cdnPath)
: base(virtualPath, cdnPath, new IBundleTransform[] { new LessTransform(), new CssMinify() })
{
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法类似于StyleBundle类,指定LESS文件而不是CSS文件.
将以下内容添加到BundleConfig.RegisterBundles(BundleCollection)方法:
bundles.Add(new LessBundle("~/Content/less").Include(
"~/Content/MyStyles.less"));
Run Code Online (Sandbox Code Playgroud)
这种方法在关闭优化时工作正常,但是在打开优化时我遇到了一些小问题(使用CSS资源路径).经过一个小时研究这个问题,我发现我已经重新发明了轮子......
如果您确实需要我上面描述的LessBundle功能,请查看System.Web.Optimization.Less.
NuGet包可以在这里找到.
Emm*_*ook 12
似乎无点引擎需要知道当前处理的bundle文件的路径以解析@import路径.如果运行上面的进程代码,则当解析的.less文件导入的文件较少时,dotless.Core.Less.Parse()的结果为空字符串.
Ben Foster在这里的回答将通过首先读取导入的文件来解决这个问题:
更改LessTransform文件,如下所示:
public class LessTransform : IBundleTransform
{
public void Process(BundleContext context, BundleResponse bundle)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if (bundle == null)
{
throw new ArgumentNullException("bundle");
}
context.HttpContext.Response.Cache.SetLastModifiedFromFileDependencies();
var lessParser = new Parser();
ILessEngine lessEngine = CreateLessEngine(lessParser);
var content = new StringBuilder(bundle.Content.Length);
var bundleFiles = new List<FileInfo>();
foreach (var bundleFile in bundle.Files)
{
bundleFiles.Add(bundleFile);
SetCurrentFilePath(lessParser, bundleFile.FullName);
string source = File.ReadAllText(bundleFile.FullName);
content.Append(lessEngine.TransformToCss(source, bundleFile.FullName));
content.AppendLine();
bundleFiles.AddRange(GetFileDependencies(lessParser));
}
if (BundleTable.EnableOptimizations)
{
// include imports in bundle files to register cache dependencies
bundle.Files = bundleFiles.Distinct();
}
bundle.ContentType = "text/css";
bundle.Content = content.ToString();
}
/// <summary>
/// Creates an instance of LESS engine.
/// </summary>
/// <param name="lessParser">The LESS parser.</param>
private ILessEngine CreateLessEngine(Parser lessParser)
{
var logger = new AspNetTraceLogger(LogLevel.Debug, new Http());
return new LessEngine(lessParser, logger, true, false);
}
/// <summary>
/// Gets the file dependencies (@imports) of the LESS file being parsed.
/// </summary>
/// <param name="lessParser">The LESS parser.</param>
/// <returns>An array of file references to the dependent file references.</returns>
private IEnumerable<FileInfo> GetFileDependencies(Parser lessParser)
{
IPathResolver pathResolver = GetPathResolver(lessParser);
foreach (var importPath in lessParser.Importer.Imports)
{
yield return new FileInfo(pathResolver.GetFullPath(importPath));
}
lessParser.Importer.Imports.Clear();
}
/// <summary>
/// Returns an <see cref="IPathResolver"/> instance used by the specified LESS lessParser.
/// </summary>
/// <param name="lessParser">The LESS parser.</param>
private IPathResolver GetPathResolver(Parser lessParser)
{
var importer = lessParser.Importer as Importer;
var fileReader = importer.FileReader as FileReader;
return fileReader.PathResolver;
}
/// <summary>
/// Informs the LESS parser about the path to the currently processed file.
/// This is done by using a custom <see cref="IPathResolver"/> implementation.
/// </summary>
/// <param name="lessParser">The LESS parser.</param>
/// <param name="currentFilePath">The path to the currently processed file.</param>
private void SetCurrentFilePath(Parser lessParser, string currentFilePath)
{
var importer = lessParser.Importer as Importer;
if (importer == null)
throw new InvalidOperationException("Unexpected dotless importer type.");
var fileReader = importer.FileReader as FileReader;
if (fileReader == null || !(fileReader.PathResolver is ImportedFilePathResolver))
{
fileReader = new FileReader(new ImportedFilePathResolver(currentFilePath));
importer.FileReader = fileReader;
}
}
}
public class ImportedFilePathResolver : IPathResolver
{
private string currentFileDirectory;
private string currentFilePath;
public ImportedFilePathResolver(string currentFilePath)
{
if (string.IsNullOrEmpty(currentFilePath))
{
throw new ArgumentNullException("currentFilePath");
}
CurrentFilePath = currentFilePath;
}
/// <summary>
/// Gets or sets the path to the currently processed file.
/// </summary>
public string CurrentFilePath
{
get { return currentFilePath; }
set
{
currentFilePath = value;
currentFileDirectory = Path.GetDirectoryName(value);
}
}
/// <summary>
/// Returns the absolute path for the specified improted file path.
/// </summary>
/// <param name="filePath">The imported file path.</param>
public string GetFullPath(string filePath)
{
if (filePath.StartsWith("~"))
{
filePath = VirtualPathUtility.ToAbsolute(filePath);
}
if (filePath.StartsWith("/"))
{
filePath = HostingEnvironment.MapPath(filePath);
}
else if (!Path.IsPathRooted(filePath))
{
filePath = Path.GetFullPath(Path.Combine(currentFileDirectory, filePath));
}
return filePath;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
26406 次 |
| 最近记录: |