public override bool Execute() { var razorComponentsWithJsModules = new List <ITaskItem>(); var razorGenerateWithJsModules = new List <ITaskItem>(); var unmatchedJsModules = new List <ITaskItem>(JSFileModuleCandidates); var jsModulesByRazorItem = new Dictionary <string, IList <ITaskItem> >(); for (var i = 0; i < RazorComponents.Length; i++) { var componentCandidate = RazorComponents[i]; MatchJsModuleFiles( razorComponentsWithJsModules, componentCandidate, unmatchedJsModules, jsModulesByRazorItem, "RazorComponent", "(.*)\\.razor\\.js$", "$1.razor"); } for (var i = 0; i < RazorGenerate.Length; i++) { var razorViewCandidate = RazorGenerate[i]; MatchJsModuleFiles( razorGenerateWithJsModules, razorViewCandidate, unmatchedJsModules, jsModulesByRazorItem, "View", "(.*)\\.cshtml\\.js$", "$1.cshtml"); } foreach (var kvp in jsModulesByRazorItem) { if (RazorComponents.Any(rc => string.Equals(rc.ItemSpec, kvp.Key, StringComparison.OrdinalIgnoreCase))) { var component = kvp.Key; var jsModuleFiles = kvp.Value; if (jsModuleFiles.Count > 1) { Log.LogError(null, "BLAZOR105", "", component, 0, 0, 0, 0, $"More than one JS module files were found for the razor component '{component}'. " + $"Each razor component must have at most a single associated JS module file." + Environment.NewLine + string.Join(Environment.NewLine, jsModuleFiles.Select(f => f.ItemSpec))); } } else { var view = kvp.Key; var jsModuleFiles = kvp.Value; if (jsModuleFiles.Count > 1) { Log.LogError(null, "RZ1007", "", view, 0, 0, 0, 0, $"More than one JS module files were found for the razor view '{view}'. " + $"Each razor view must have at most a single associated JS module file." + Environment.NewLine + string.Join(Environment.NewLine, jsModuleFiles.Select(f => f.ItemSpec))); } } } foreach (var unmatched in unmatchedJsModules) { Log.LogError(null, "BLAZOR106", "", unmatched.ItemSpec, 0, 0, 0, 0, $"The JS module file '{unmatched.ItemSpec}' was defined but no associated razor component or view was found for it."); } JsFileModules = jsModulesByRazorItem.Values.SelectMany(e => e).ToArray(); return(!Log.HasLoggedErrors); }
public override bool Execute() { var razorComponentsWithScopes = new List <ITaskItem>(); var razorGenerateWithScopes = new List <ITaskItem>(); var unmatchedScopedCss = new List <ITaskItem>(ScopedCss); var scopedCssByRazorItem = new Dictionary <string, IList <ITaskItem> >(); for (var i = 0; i < RazorComponents.Length; i++) { var componentCandidate = RazorComponents[i]; MatchScopedCssFiles( razorComponentsWithScopes, componentCandidate, unmatchedScopedCss, scopedCssByRazorItem, "RazorComponent", "(.*)\\.razor\\.css$", "$1.razor"); } for (var i = 0; i < RazorGenerate.Length; i++) { var razorViewCandidate = RazorGenerate[i]; MatchScopedCssFiles( razorGenerateWithScopes, razorViewCandidate, unmatchedScopedCss, scopedCssByRazorItem, "View", "(.*)\\.cshtml\\.css$", "$1.cshtml"); } foreach (var kvp in scopedCssByRazorItem) { if (RazorComponents.Any(rc => string.Equals(rc.ItemSpec, kvp.Key, StringComparison.OrdinalIgnoreCase))) { var component = kvp.Key; var scopeFiles = kvp.Value; if (scopeFiles.Count > 1) { Log.LogError(null, "BLAZOR101", "", component, 0, 0, 0, 0, $"More than one scoped css files were found for the razor component '{component}'. " + $"Each razor component must have at most a single associated scoped css file." + Environment.NewLine + string.Join(Environment.NewLine, scopeFiles.Select(f => f.ItemSpec))); } } else { var view = kvp.Key; var scopeFiles = kvp.Value; if (scopeFiles.Count > 1) { Log.LogError(null, "RZ1007", "", view, 0, 0, 0, 0, $"More than one scoped css files were found for the razor view '{view}'. " + $"Each razor view must have at most a single associated scoped css file." + Environment.NewLine + string.Join(Environment.NewLine, scopeFiles.Select(f => f.ItemSpec))); } } } // We don't want to allow scoped css files without a matching component. Our convention is very specific in its requirements // so failing to have a matching component very likely means an error. // When the matching component was specified explicitly, failing to find a matching component is an error. // This simplifies a few things like being able to assume that the presence of a .razor.css file or a ScopedCssInput item will result in a bundle being produced, // that the contents of the bundle are independent of the existence of a component and that users will be able to catch errors at compile // time instead of wondering why their component doesn't have a scope applied to it. // In the rare case that a .razor file exists on the user project, has an associated .razor.css file and the user decides to exclude it as a RazorComponent they // can update the Content item for the .razor.css file with Scoped=false and we will not consider it. foreach (var unmatched in unmatchedScopedCss) { Log.LogError(null, "BLAZOR102", "", unmatched.ItemSpec, 0, 0, 0, 0, $"The scoped css file '{unmatched.ItemSpec}' was defined but no associated razor component or view was found for it."); } RazorComponentsWithScopes = razorComponentsWithScopes.ToArray(); RazorGenerateWithScopes = razorGenerateWithScopes.ToArray(); return(!Log.HasLoggedErrors); }