使用BundlerMinifier在bundleconfig.json中使用相对路径和通配模式(文件夹/子文件夹中的所有文件)

时间:2018-04-04 21:19:44

标签: c# asp.net-core bundling-and-minification

我有一个ASP.NET核心Web项目。我正在尝试使用项目根目录下的bundleconfig.json文件中的BundlerMinifier package捆绑一堆静态.js文件。我遇到的问题是我要捆绑的.js文件在解决方案中的另一个项目中(我称之为MainProject),所以我必须使用相对路径来指定它们,如下所示:

"outputFileName": "../MainProject/bundles/libraryscripts.js",
"inputFiles": [
  "../MainProject/Scripts/Libraries/Angular/**/*.js",
  // more input files
],
"minify": {
  "enabled": true
}

当我构建项目时,捆绑器不会出现任何错误,并且在指定的文件夹中创建了文件libraryscripts.js。问题是文件是空的,我认为这是由于globbing模式(** / * .js)。当我枚举所有文件而不是使用此模式时,它工作正常。更复杂的是,当我不使用相对路径(开头没有../)时,使用globbing模式似乎工作正常。

这让我相信将相对路径与globbing模式结合使用会带来问题。任何人都可以证实这一点,有没有人知道这方面的方法?我不想枚举数百个.js文件(既不优雅也不可持续)。

1 个答案:

答案 0 :(得分:0)

注意:以下是我实施的一个hacky解决方法 - 它不是这个问题的官方解决方案,尽管它可能仍然有用。

我克隆了BundlerMinifier项目,因此我可以调试它是如何捆绑bundleconfig.json中指定的文件并查看问题所在。问题出在Bundle.cs,特别是GetAbsoluteInputFiles方法。此行获取存储bundleconfig.json的文件夹的路径:

string folder = new DirectoryInfo(Path.GetDirectoryName(FileName)).FullName;

问题是,稍后在修剪找到的文件路径的开头时会使用相同的folder变量:

var allFiles = Directory.EnumerateFiles(searchDir, "*" + ext, SearchOption.AllDirectories).Select(f => f.Replace(folder + FileHelpers.PathSeparatorChar, ""));

由于文件位于另一个目录中,.Select(f => f.Replace());部分没有删除文件路径的开头,这意味着匹配后比较失败。因此,没有找到同时具有../和通配模式的文件。

我为自己想出了一个hacky解决方案,但我认为它并不健全,因此我不会为Git项目做出贡献。尽管如此,我还是把它放在这里以防其他人有同样的问题。我创建了folder的副本:

string folder = new DirectoryInfo(Path.GetDirectoryName(FileName)).FullName;
string alternateFolder = folder;
bool folderModified = false;

然后我创建了inputFile的副本,并检查它是否以../开头。如果是,请将其删除,同时从alternateFolder

中删除最后一个文件夹名称
string searchDir = new FileInfo(Path.Combine(folder, relative).NormalizePath()).FullName;
string newInput = inputFile;
while (newInput.StartsWith("../"))
{
    // I'm sure there's a better way to do this using some class/library.
    newInput = newInput.Substring(3);
    if (!folderModified)
    {
        int lastSlash = alternateFolder.LastIndexOf('\\');
        alternateFolder = alternateFolder.Substring(0, lastSlash);
        folderModified = true;
    }                        
}

然后我在以下行中仅使用alternateFoldernewInput

var allFiles = Directory.EnumerateFiles(searchDir, "*" + ext, SearchOption.AllDirectories).Select(f => f.Replace(alternateFolder + FileHelpers.PathSeparatorChar, ""));
var matches = Minimatcher.Filter(allFiles, newInput, options).Select(f => Path.Combine(alternateFolder, f));

其他地方仍使用folderinputFile。另请注意使用folderModified布尔值。重要的是只删除alternateFolder上的最后一个文件夹,因为它位于foreach循环中。