Css 使用SquishIt在单独的less文件中引用变量(支持动态less内容)?

Css 使用SquishIt在单独的less文件中引用变量(支持动态less内容)?,css,twitter-bootstrap,less,bundle,squishit,Css,Twitter Bootstrap,Less,Bundle,Squishit,我们正在MVC4中为我们的项目使用引导。到目前为止,我们在主布局页面中引用了bootstrap.less文件,效果非常好。然而,出现了一个新的要求,要求我们为每个部门页面定制外观(每个部门都有自己的使用主布局的布局) bootstrap.less具有以下结构: @import variables.less//定义所有变量 @导入其他//所有导入,如mixin.less、reset.less等 由于需要注入变量覆盖,我们创建了另一个更少的文件: bootstrap-without-variable

我们正在MVC4中为我们的项目使用引导。到目前为止,我们在主布局页面中引用了bootstrap.less文件,效果非常好。然而,出现了一个新的要求,要求我们为每个部门页面定制外观(每个部门都有自己的使用主布局的布局)

bootstrap.less具有以下结构:

@import variables.less//定义所有变量

@导入其他//所有导入,如mixin.less、reset.less等

由于需要注入变量覆盖,我们创建了另一个更少的文件:

bootstrap-without-variables.less//包含bootstrap.less中所有不带变量的导入

这种分离的原因是注入变量覆盖,以便我们可以自定义页面的引导样式

我们正在使用将较少的文件打包成一个包

这是包裹:

    Bundle.Css()
    .Add("~/bootstrap/variables.less")
    .Add("~/variable-override.less") // custom override
    .Add("~/bootstrap/bootstrap-without-variables.less")
    .MvcRender("styles_combined_#.js");
这根本不起作用。如果我删除variables.less并在bootstrap-without-variables.less中引用它(它现在变得类似于bootstrap.less),它就可以正常工作

我认为问题在于,在将每个文件组合在一起之前,它们都会被独立地评估并转换为css


有没有办法告诉捆绑程序先将文件捆绑成一个文件,然后评估并转换为css或更好的解决方案来解决此问题?

你说得对,SquishIt在合并文件之前处理的过程更少。仅使用SquishIt无法实现您的要求,但我认为您可以在进入的过程中自行组合文件(使用.AddString方法将生成的.less内容添加到包中)。我不确定,其中一种选择可能更适合您的需要。

就像前面提到的,我没有办法只使用SquishIt来完成上面提到的工作。但是,如中所述,AddString()有一个重载,允许您添加动态内容

比如说,

.AddString(“LessString”,“.less”)//.less是扩展名

只要LessString不包含任何导入(@import),这就可以很好地工作。因此,我从下载了源代码并开始深入研究代码。查看代码时,我发现通过AddString()加载的内容将CurrentDirectory设置为我的IIS路径(“c:\windows\system32\inetsrv”)。因此,进口量急剧下降

FileNotFoundException(您正在导入一个以 找不到。)

因此,我需要一种方法来设置当前目录(搜索我的导入的参考位置)

以下是我所做的:

步骤1:扩展资产以具有名为CurrentDirectory的属性

  internal string CurrentDirectory { get; set; }
步骤2:向AddString()重载添加第三个可选参数

步骤3:更新AddString()以将当前目录添加到资产

 T AddString(string content, string extension, bool minify, string currentDirectory = null)
    {
        if (bundleState.Assets.All(ac => ac.Content != content))
            bundleState.Assets.Add(new Asset { Content = content, Extension = extension, Minify = minify, CurrentDirectory = currentDirectory });
        return (T)this;
    }
步骤4:修改BundleBase上的PrepreArbitary(用于发布)以设置当前目录

protected string PreprocessArbitrary(Asset asset)
    {
        if (!asset.IsArbitrary) throw new InvalidOperationException("PreprocessArbitrary can only be called on Arbitrary assets.");

        var filename = "dummy." + (asset.Extension ?? defaultExtension);
        var preprocessors = FindPreprocessors(filename);
        return asset.CurrentDirectory != null ?
                    directoryWrapper.ExecuteInDirectory(asset.CurrentDirectory, () => MinifyIfNeeded(PreprocessContent(filename, preprocessors, asset.Content), asset.Minify)) :
                    MinifyIfNeeded(PreprocessContent(filename, preprocessors, asset.Content), asset.Minify);
    }
 if (asset.IsArbitrary)
            {
                var filename = "dummy" + asset.Extension;
                var preprocessors = FindPreprocessors(filename);
                var processedContent = asset.CurrentDirectory != null ?
                        directoryWrapper.ExecuteInDirectory(asset.CurrentDirectory, () => PreprocessContent(filename, preprocessors, asset.Content)) :
                        PreprocessContent(filename, preprocessors, asset.Content);
                sb.AppendLine(string.Format(tagFormat, processedContent));
            }
对于调试,修改RenderDebug以设置当前目录

protected string PreprocessArbitrary(Asset asset)
    {
        if (!asset.IsArbitrary) throw new InvalidOperationException("PreprocessArbitrary can only be called on Arbitrary assets.");

        var filename = "dummy." + (asset.Extension ?? defaultExtension);
        var preprocessors = FindPreprocessors(filename);
        return asset.CurrentDirectory != null ?
                    directoryWrapper.ExecuteInDirectory(asset.CurrentDirectory, () => MinifyIfNeeded(PreprocessContent(filename, preprocessors, asset.Content), asset.Minify)) :
                    MinifyIfNeeded(PreprocessContent(filename, preprocessors, asset.Content), asset.Minify);
    }
 if (asset.IsArbitrary)
            {
                var filename = "dummy" + asset.Extension;
                var preprocessors = FindPreprocessors(filename);
                var processedContent = asset.CurrentDirectory != null ?
                        directoryWrapper.ExecuteInDirectory(asset.CurrentDirectory, () => PreprocessContent(filename, preprocessors, asset.Content)) :
                        PreprocessContent(filename, preprocessors, asset.Content);
                sb.AppendLine(string.Format(tagFormat, processedContent));
            }
下面是我现在如何添加动态或静态较少的文件:

.AddString("@import 'content/bootstrap/variables.less';", ".less", AppDomain.CurrentDomain.BaseDirectory)
对于上述要求,我将variables.less读入字符串生成器,然后添加variable-override.less,最后将bootstrap-without-variables.less添加到字符串生成器

到目前为止,它对我很有效。我测试了以下场景:

  • 带有导入的普通less文件,例如
    .Add(“~/content/styles.less”)

  • 无导入的内联less,例如
    .AddString(LessString,“.less”)

  • 带有导入的动态less文件,例如
    .AddString(@import content/bootstrap/variables.less';“,.less”,AppDomain.CurrentDomain.BaseDirectory)

    我很快会尝试做一个拉动请求。我希望这能帮助那些希望通过导入支持动态内容的人


  • 我将.less文件读入字符串,并尝试扩展名为.less的.AddString重载。但是现在找不到.less文件中的导入。啊,是的,这是有道理的。看起来您正在使用对变量覆盖文件的静态引用-如果这是您的实际用例,我认为您可以使用修改后的variables.less文件。如果没有,您可能需要提出您自己的解决方案(除非其他优化库支持您所需的操作)。很高兴您可以使用它!期待看到你的拉请求,这将是一个伟大的事情添加。所以你知道,弄乱Environment.CurrentDirectory可能会产生一些有趣的结果,因此以某种方式确定更改的范围是很好的。您可能希望使用这个类,它将在给定的目录中执行代码,然后进行恢复以防止不稳定:我刚刚提交了一个pull请求,其中的更改伴随着恢复。