public string ExpandHtmlHead(BuildResult buildResult) { return(ResourceLinkDetector.Replace(HtmlHead, m => { var fn = PathUtils.Join(Owner.Owner.FullPath, m.Value.Substring(2, m.Length - 4)); return buildResult.ToOutputUrl(fn); })); }
public string ExpandHtmlHead(string htmlHead) { return(new Regex("<<[^>]+>>").Replace(htmlHead, (Match m) => { var info = AutodetectAndAddDependency( PathUtils.Join(Owner.Owner.FullPath, m.Value.Substring(2, m.Length - 4)), true); if (info == null) { Owner.Logger.Error("HtmlHead in package.json missing dependency " + m.Value.Substring(2, m.Length - 4)); return ""; } return Result.ToOutputUrl(info); })); }
public void Build(bool compress, bool mangle, bool beautify, bool _, string?__) { var cssLink = ""; var cssToBundle = new List <SourceFromPair>(); foreach (var source in _buildResult.Path2FileInfo.Values.OrderBy(f => f.Owner.FullPath).ToArray()) { if (source.Type == FileCompilationType.Css || source.Type == FileCompilationType.ImportedCss) { cssToBundle.Add(new SourceFromPair(source.Owner.Utf8Content, source.Owner.FullPath)); } else if (source.Type == FileCompilationType.Resource) { _mainBuildResult.FilesContent.GetOrAddValueRef(_buildResult.ToOutputUrl(source)) = source.Owner.ByteContent; } } if (cssToBundle.Count > 0) { string cssPath = _mainBuildResult.AllocateName("bundle.css"); var cssProcessor = new CssProcessor(_project.Tools); var cssContent = cssProcessor.ConcatenateAndMinifyCss(cssToBundle, (string url, string from) => { var full = PathUtils.Join(from, url); var fullJustName = full.Split('?', '#')[0]; _buildResult.Path2FileInfo.TryGetValue(fullJustName, out var fileAdditionalInfo); _mainBuildResult.FilesContent.GetOrAddValueRef(_buildResult.ToOutputUrl(fileAdditionalInfo)) = fileAdditionalInfo.Owner.ByteContent; return(PathUtils.GetFile(fileAdditionalInfo.OutputUrl) + full.Substring(fullJustName.Length)); }).Result; var cssImports = ""; foreach (var match in Regex.Matches(cssContent, "@import .*;")) { cssImports += match.ToString(); cssContent = cssContent.Replace(match.ToString(), ""); } _mainBuildResult.FilesContent.GetOrAddValueRef(cssPath) = cssImports + cssContent; cssLink += "<link rel=\"stylesheet\" href=\"" + cssPath + "\">"; } if (_project.SpriteGeneration) { _bundlePng = _project.BundlePngUrl; var bundlePngContent = _project.SpriteGenerator.BuildImage(true); if (bundlePngContent != null) { _bundlePngInfo = new List <float>(); foreach (var slice in bundlePngContent) { _mainBuildResult.FilesContent.GetOrAddValueRef(PathUtils.InjectQuality(_bundlePng, slice.Quality)) = slice.Content; _bundlePngInfo.Add(slice.Quality); } } else { _bundlePng = null; } } var bundler = new BundlerImpl(_tools); bundler.Callbacks = this; if ((_project.ExampleSources?.Count ?? 0) > 0) { bundler.MainFiles = new[] { _project.ExampleSources[0] }; } else { bundler.MainFiles = new[] { _project.MainFile }; } _mainJsBundleUrl = _buildResult.BundleJsUrl; bundler.Compress = compress; bundler.Mangle = mangle; bundler.Beautify = beautify; bundler.Defines = _project.BuildDefines(_mainBuildResult); bundler.Bundle(); if (!_project.NoHtml) { BuildFastBundlerIndexHtml(cssLink); _mainBuildResult.FilesContent.GetOrAddValueRef("index.html") = _indexHtml; } if (_project.SubProjects != null) { var newSubBundlers = new RefDictionary <string, BundleBundler>(); foreach (var(projPath, subProject) in _project.SubProjects.OrderBy(a => a.Value?.Variant == "serviceworker")) { if (subProject == null) { continue; } if (_subBundlers == null || !_subBundlers.TryGetValue(projPath, out var subBundler)) { subBundler = new BundleBundler(_tools, _mainBuildResult, subProject, _buildResult.SubBuildResults.GetOrFakeValueRef(projPath)); } newSubBundlers.GetOrAddValueRef(projPath) = subBundler; subBundler.Build(compress, mangle, beautify, false, null); } _subBundlers = newSubBundlers; } else { _subBundlers = null; } }
public void Build(string sourceRoot, bool testProj = false, bool allowIncremental = true) { _versionDirPrefix = ""; var coverage = _project.CoverageEnabled; if (coverage) { allowIncremental = false; } if (_mainBuildResult.OutputSubDir != null) { _versionDirPrefix = _mainBuildResult.OutputSubDir + "/"; } var root = _mainBuildResult.CommonSourceDirectory; var incremental = _buildResult.Incremental && allowIncremental; var start = DateTime.UtcNow; var sourceMapBuilder = new SourceMapBuilder(); if (_project.Localize) { if (!incremental) { sourceMapBuilder.AddText( $"function g11nPath(s){{return\"./{_mainBuildResult.OutputSubDirPrefix}\"+s.toLowerCase()+\".js\"}};"); if (_project.DefaultLanguage != null) { sourceMapBuilder.AddText($"var g11nLoc=\"{_project.DefaultLanguage}\";"); } } } if (_project.SpriteGeneration) { _bundlePng = _project.BundlePngUrl; var bundlePngContent = _project.SpriteGenerator.BuildImage(false); if (bundlePngContent != null) { _bundlePngInfo = new List <float>(); foreach (var slice in bundlePngContent) { _mainBuildResult.FilesContent.GetOrAddValueRef( PathUtils.InjectQuality(_bundlePng, slice.Quality)) = slice.Content; _bundlePngInfo.Add(slice.Quality); } } else { _bundlePng = null; } } if (_bundlePng != null && !incremental) { sourceMapBuilder.AddText(_mainBuildResult.GenerateCodeForBobrilBPath(_bundlePng, _bundlePngInfo)); } if (!incremental) { sourceMapBuilder.AddText(_tools.LoaderJs); sourceMapBuilder.AddText(GetGlobalDefines()); sourceMapBuilder.AddText(GetModuleMap()); sourceMapBuilder.AddText(BundlerHelpers.JsHeaders(false)); } var cssLink = ""; var sortedResultSet = incremental ? _buildResult.RecompiledIncrementaly.OrderBy(f => f.Owner.FullPath).ToArray() : _buildResult.Path2FileInfo.Values.OrderBy(f => f.Owner.FullPath).ToArray(); if (!incremental) { foreach (var source in _buildResult.JavaScriptAssets) { sourceMapBuilder.AddSource(source.Output, source.MapLink); } } foreach (var source in sortedResultSet) { if (source.Type == FileCompilationType.TypeScript || source.Type == FileCompilationType.EsmJavaScript || source.Type == FileCompilationType.JavaScript) { if (source.Output == null) { continue; // Skip d.ts } sourceMapBuilder.AddText( $"R('{PathUtils.Subtract(PathUtils.WithoutExtension(source.Owner.FullPath), root)}',function(require, module, exports, global){{"); var adder = sourceMapBuilder.CreateSourceAdder(source.Output, source.MapLink); var sourceReplacer = new SourceReplacer(); _project.ApplySourceInfo(sourceReplacer, source.SourceInfo, _buildResult); sourceReplacer.Apply(adder); sourceMapBuilder.AddText("\n});"); } else if (source.Type == FileCompilationType.Json) { sourceMapBuilder.AddText( $"R('{PathUtils.Subtract(source.Owner.FullPath, root)}',"); sourceMapBuilder.AddText(source.Owner.Utf8Content); sourceMapBuilder.AddText(");"); } else if (source.Type == FileCompilationType.ImportedCss) { sourceMapBuilder.AddText( $"R('{PathUtils.Subtract(source.Owner.FullPath, root)}',function(){{}});"); string cssPath = _buildResult.ToOutputUrl(source); _mainBuildResult.FilesContent.GetOrAddValueRef(cssPath) = source.Output; cssLink += "<link rel=\"stylesheet\" href=\"" + cssPath + "\">"; } else if (source.Type == FileCompilationType.Css) { string cssPath = _buildResult.ToOutputUrl(source); _mainBuildResult.FilesContent.GetOrAddValueRef(cssPath) = source.Output; cssLink += "<link rel=\"stylesheet\" href=\"" + cssPath + "\">"; } else if (source.Type == FileCompilationType.Resource) { _mainBuildResult.FilesContent.GetOrAddValueRef(_buildResult.ToOutputUrl(source)) = source.Owner.ByteContent; } } if (!testProj && _project.NoHtml) { sourceMapBuilder.AddText(RequireBobril()); if (_project.MainFile != null) { sourceMapBuilder.AddText( $"R.r('./{PathUtils.WithoutExtension(PathUtils.Subtract(_project.MainFile, root))}');"); } } if (_project.Localize) { _project.TranslationDb.BuildTranslationJs(_tools, _mainBuildResult.FilesContent, _mainBuildResult.OutputSubDir); } if (incremental) { sourceMapBuilder.AddText("//# sourceMappingURL=bundle2.js.map"); _sourceMap2 = sourceMapBuilder.Build(root, sourceRoot); _sourceMap2String = _sourceMap2.ToString(); _bundle2Js = sourceMapBuilder.Content(); _project.Owner.Logger.Info("JS Bundle length: " + _bundleJs.Length + " SourceMap length: " + _sourceMapString.Length + " Delta: " + _bundle2Js.Length + " SM:" + _sourceMap2String.Length + " T:" + (DateTime.UtcNow - start).TotalMilliseconds.ToString("F0") + "ms"); } else { sourceMapBuilder.AddText("//# sourceMappingURL=" + PathUtils.GetFile(_buildResult.BundleJsUrl) + ".map"); if (coverage) { _sourceMap = sourceMapBuilder.Build(".", "."); _bundleJs = sourceMapBuilder.Content(); var toplevel = Parser.Parse(_bundleJs); _sourceMap.ResolveInAst(toplevel); var coverageInst = new CoverageInstrumentation(); coverageInst.RealPath = PathUtils.RealPath; _project.CoverageInstrumentation = coverageInst; toplevel = coverageInst.Instrument(toplevel); coverageInst.AddCountingHelpers(toplevel); coverageInst.CleanUp(new SourceReader(_project.Owner.DiskCache, _mainBuildResult.CommonSourceDirectory)); if (_project.MainFile != null) { MarkImportant(_project.MainFile, _buildResult, new HashSet <string>(), coverageInst); } sourceMapBuilder = new SourceMapBuilder(); toplevel.PrintToBuilder(sourceMapBuilder, new OutputOptions { Beautify = true }); sourceMapBuilder.AddText("//# sourceMappingURL=" + PathUtils.GetFile(_buildResult.BundleJsUrl) + ".map"); } _sourceMap = sourceMapBuilder.Build(root, sourceRoot); _bundleJs = sourceMapBuilder.Content(); _sourceMapString = _sourceMap.ToString(); _sourceMap2 = null; _sourceMap2String = null; _bundle2Js = null; _cssLink = cssLink; _project.Owner.Logger.Info("JS Bundle length: " + _bundleJs.Length + " SourceMap length: " + _sourceMapString.Length + " T:" + (DateTime.UtcNow - start).TotalMilliseconds.ToString("F0") + "ms"); } _mainBuildResult.FilesContent.GetOrAddValueRef(_buildResult.BundleJsUrl) = _bundleJs; _mainBuildResult.FilesContent.GetOrAddValueRef(_buildResult.BundleJsUrl + ".map") = _sourceMapString; if (incremental) { _mainBuildResult.FilesContent.GetOrAddValueRef(_versionDirPrefix + "bundle2.js") = _bundle2Js; _mainBuildResult.FilesContent.GetOrAddValueRef(_versionDirPrefix + "bundle2.js.map") = _sourceMap2String; SourceMaps = new Dictionary <string, SourceMap> { { PathUtils.GetFile(_buildResult.BundleJsUrl), _sourceMap }, { "bundle2.js", _sourceMap2 } }; } else { SourceMaps = new Dictionary <string, SourceMap> { { PathUtils.GetFile(_buildResult.BundleJsUrl), _sourceMap } }; } if (_project.SubProjects != null) { var newSubBundlers = new RefDictionary <string, FastBundleBundler>(); foreach (var(projPath, subProject) in _project.SubProjects.OrderBy(a => a.Value?.Variant == "serviceworker")) { if (subProject == null) { continue; } if (_subBundlers == null || !_subBundlers.TryGetValue(projPath, out var subBundler)) { subBundler = new FastBundleBundler(_tools, _mainBuildResult, subProject, _buildResult.SubBuildResults.GetOrFakeValueRef(projPath)); } newSubBundlers.GetOrAddValueRef(projPath) = subBundler; subBundler.Build(sourceRoot, false, false); } _subBundlers = newSubBundlers; } else { _subBundlers = null; } }
public void ApplySourceInfo(ISourceReplacer sourceReplacer, SourceInfo sourceInfo, BuildResult buildResult) { if (sourceInfo == null) { return; } if (sourceInfo.Assets != null) { foreach (var a in sourceInfo.Assets) { if (a.Name == null) { continue; } var assetName = a.Name; if (assetName.StartsWith("resource:")) { assetName = assetName.Substring(9); } sourceReplacer.Replace(a.StartLine, a.StartCol, a.EndLine, a.EndCol, "\"" + buildResult.ToOutputUrl(assetName) + "\""); } } if (sourceInfo.Sprites != null) { if (SpriteGeneration) { var spriteHolder = SpriteGenerator; var outputSprites = spriteHolder.Retrieve(sourceInfo.Sprites); foreach (var os in outputSprites) { var s = os.Me; if (s.Name == null) { continue; } if (s.HasColor == true && s.Color == null) { // Modify method name to b.spritebc and remove first parameter with sprite name sourceReplacer.Replace(s.StartLine, s.StartCol, s.ColorStartLine, s.ColorStartCol, sourceInfo.BobrilImport + ".spritebc("); // Replace parameters after color with sprite size and position sourceReplacer.Replace(s.ColorEndLine, s.ColorEndCol, s.EndLine, s.EndCol, "," + os.owidth + "," + os.oheight + "," + os.ox + "," + os.oy + ")"); } else { // Modify method name to b.spriteb and replace parameters with sprite size and position sourceReplacer.Replace(s.StartLine, s.StartCol, s.EndLine, s.EndCol, sourceInfo.BobrilImport + ".spriteb(" + os.owidth + "," + os.oheight + "," + os.ox + "," + os.oy + ")"); } } } else { foreach (var s in sourceInfo.Sprites) { if (s.Name == null) { continue; } sourceReplacer.Replace(s.NameStartLine, s.NameStartCol, s.NameEndLine, s.NameEndCol, "\"" + buildResult.ToOutputUrl(s.Name) + "\""); } } } var trdb = TranslationDb; if (trdb != null && sourceInfo.Translations != null) { foreach (var t in sourceInfo.Translations) { if (t.Message == null) { continue; } if (t.JustFormat) { continue; } var id = trdb.AddToDB(t.Message, t.Hint, t.WithParams); var finalId = trdb.MapId(id); sourceReplacer.Replace(t.StartLine, t.StartCol, t.EndLine, t.EndCol, "" + finalId); sourceReplacer.Replace(t.StartHintLine, t.StartHintCol, t.EndHintLine, t.EndHintCol, null); } } var styleDefs = sourceInfo.StyleDefs; if (styleDefs != null) { var styleDefNaming = StyleDefNaming; var styleDefPrefix = PrefixStyleNames; foreach (var s in styleDefs) { var skipEx = s.IsEx ? 1 : 0; if (s.UserNamed) { if (styleDefNaming == StyleDefNamingStyle.AddNames || styleDefNaming == StyleDefNamingStyle.PreserveNames) { if (styleDefPrefix.Length > 0) { if (s.Name != null) { sourceReplacer.Replace(s.StartLine, s.StartCol, s.EndLine, s.EndCol, "\"" + styleDefPrefix + s.Name + "\""); } else { sourceReplacer.Replace(s.StartLine, s.StartCol, s.StartLine, s.StartCol, "\"" + styleDefPrefix + "\"+("); sourceReplacer.Replace(s.EndLine, s.EndCol, s.EndLine, s.EndCol, ")"); } } } else { sourceReplacer.Replace(s.BeforeNameLine, s.BeforeNameCol, s.EndLine, s.EndCol, ""); } } else { if (styleDefNaming == StyleDefNamingStyle.AddNames && s.Name != null) { var padArgs = (s.ArgCount == 1 + (s.IsEx ? 1 : 0)) ? ",undefined" : ""; sourceReplacer.Replace(s.BeforeNameLine, s.BeforeNameCol, s.BeforeNameLine, s.BeforeNameCol, padArgs + ",\"" + styleDefPrefix + s.Name + "\""); } } } } }
public void Build(string sourceRoot, bool testProj = false) { _versionDirPrefix = ""; if (Project.OutputSubDir != null) { _versionDirPrefix = Project.OutputSubDir + "/"; } var root = Project.CommonSourceDirectory; var incremental = BuildResult.Incremental; var start = DateTime.UtcNow; var sourceMapBuilder = new SourceMapBuilder(); if (Project.Localize) { if (!incremental) { sourceMapBuilder.AddText( $"function g11nPath(s){{return\"./{(Project.OutputSubDir != null ? (Project.OutputSubDir + "/") : "")}\"+s.toLowerCase()+\".js\"}};"); if (Project.DefaultLanguage != null) { sourceMapBuilder.AddText($"var g11nLoc=\"{Project.DefaultLanguage}\";"); } } } if (_bundlePng != null && !incremental) { sourceMapBuilder.AddText(GetInitSpriteCode()); } if (!incremental) { sourceMapBuilder.AddText(_tools.LoaderJs); if (Project.Defines != null) { sourceMapBuilder.AddText(GetGlobalDefines()); } sourceMapBuilder.AddText(GetModuleMap()); sourceMapBuilder.AddText(_tools.TsLibSource); } var cssLink = ""; var sortedResultSet = incremental ? BuildResult.RecompiledIncrementaly.OrderBy(f => f.Owner.FullPath).ToArray() : BuildResult.Path2FileInfo.Values.OrderBy(f => f.Owner.FullPath).ToArray(); if (!incremental) { foreach (var source in BuildResult.JavaScriptAssets) { sourceMapBuilder.AddSource(source.Output, source.MapLink); } } foreach (var source in sortedResultSet) { if (source.Type == FileCompilationType.TypeScript || source.Type == FileCompilationType.EsmJavaScript || source.Type == FileCompilationType.JavaScript) { if (source.Output == null) { continue; // Skip d.ts } sourceMapBuilder.AddText( $"R('{PathUtils.Subtract(PathUtils.WithoutExtension(source.Owner.FullPath), root)}',function(require, module, exports, global){{"); var adder = sourceMapBuilder.CreateSourceAdder(source.Output, source.MapLink); var sourceReplacer = new SourceReplacer(); Project.ApplySourceInfo(sourceReplacer, source.SourceInfo, BuildResult); sourceReplacer.Apply(adder); //sourceMapBuilder.AddSource(source.Output, source.MapLink); sourceMapBuilder.AddText("\n});"); } else if (source.Type == FileCompilationType.Json) { sourceMapBuilder.AddText( $"R('{PathUtils.Subtract(source.Owner.FullPath, root)}',"); sourceMapBuilder.AddText(source.Owner.Utf8Content); sourceMapBuilder.AddText(");"); } else if (source.Type == FileCompilationType.ImportedCss) { sourceMapBuilder.AddText( $"R('{PathUtils.Subtract(source.Owner.FullPath, root)}',function(){{}});"); string cssPath = BuildResult.ToOutputUrl(source); FilesContent.GetOrAddValueRef(cssPath) = source.Output; cssLink += "<link rel=\"stylesheet\" href=\"" + cssPath + "\">"; } else if (source.Type == FileCompilationType.Css) { string cssPath = BuildResult.ToOutputUrl(source); FilesContent.GetOrAddValueRef(cssPath) = source.Output; cssLink += "<link rel=\"stylesheet\" href=\"" + cssPath + "\">"; } else if (source.Type == FileCompilationType.Resource) { FilesContent.GetOrAddValueRef(BuildResult.ToOutputUrl(source)) = source.Owner.ByteContent; } } if (Project.SpriteGeneration) { _bundlePng = Project.BundlePngUrl; var bundlePngContent = Project.SpriteGenerator.BuildImage(false); if (bundlePngContent != null) { _bundlePngInfo = new List <float>(); foreach (var slice in bundlePngContent) { FilesContent.GetOrAddValueRef(PathUtils.InjectQuality(_bundlePng, slice.Quality)) = slice.Content; _bundlePngInfo.Add(slice.Quality); } } else { _bundlePng = null; } } if (!testProj && Project.NoHtml) { sourceMapBuilder.AddText(RequireBobril()); sourceMapBuilder.AddText( $"R.r('{PathUtils.WithoutExtension(PathUtils.Subtract(Project.MainFile, root))}');"); } if (Project.Localize) { Project.TranslationDb.BuildTranslationJs(_tools, FilesContent, Project.OutputSubDir); } if (incremental) { sourceMapBuilder.AddText("//# sourceMappingURL=bundle2.js.map"); _sourceMap2 = sourceMapBuilder.Build(root, sourceRoot); _sourceMap2String = _sourceMap2.ToString(); _bundle2Js = sourceMapBuilder.Content(); Project.Owner.Logger.Info("JS Bundle length: " + _bundleJs.Length + " SourceMap length: " + _sourceMapString.Length + " Delta: " + _bundle2Js.Length + " SM:" + _sourceMap2String.Length + " T:" + (DateTime.UtcNow - start).TotalMilliseconds.ToString("F0") + "ms"); } else { sourceMapBuilder.AddText("//# sourceMappingURL=bundle.js.map"); _sourceMap = sourceMapBuilder.Build(root, sourceRoot); _sourceMapString = _sourceMap.ToString(); _bundleJs = sourceMapBuilder.Content(); _sourceMap2 = null; _sourceMap2String = null; _bundle2Js = null; _cssLink = cssLink; Project.Owner.Logger.Info("JS Bundle length: " + _bundleJs.Length + " SourceMap length: " + _sourceMapString.Length + " T:" + (DateTime.UtcNow - start).TotalMilliseconds.ToString("F0") + "ms"); } FilesContent.GetOrAddValueRef(_versionDirPrefix + "bundle.js") = _bundleJs; FilesContent.GetOrAddValueRef(_versionDirPrefix + "bundle.js.map") = _sourceMapString; if (incremental) { FilesContent.GetOrAddValueRef(_versionDirPrefix + "bundle2.js") = _bundle2Js; FilesContent.GetOrAddValueRef(_versionDirPrefix + "bundle2.js.map") = _sourceMap2String; SourceMaps = new Dictionary <string, SourceMap> { { "bundle.js", _sourceMap }, { "bundle2.js", _sourceMap2 } }; } else { SourceMaps = new Dictionary <string, SourceMap> { { "bundle.js", _sourceMap } }; } }
public void Build(bool compress, bool mangle, bool beautify) { var diskCache = Project.Owner.DiskCache; var cssLink = ""; var cssToBundle = new List <SourceFromPair>(); foreach (var source in BuildResult.Path2FileInfo.Values.OrderBy(f => f.Owner.FullPath).ToArray()) { if (source.Type == FileCompilationType.Css || source.Type == FileCompilationType.ImportedCss) { cssToBundle.Add(new SourceFromPair(source.Owner.Utf8Content, source.Owner.FullPath)); } else if (source.Type == FileCompilationType.Resource) { FilesContent.GetOrAddValueRef(BuildResult.ToOutputUrl(source)) = source.Owner.ByteContent; } } if (cssToBundle.Count > 0) { string cssPath = BuildResult.AllocateName("bundle.css"); var cssProcessor = new CssProcessor(Project.Tools); var cssContent = cssProcessor.ConcatenateAndMinifyCss(cssToBundle, (string url, string from) => { var full = PathUtils.Join(from, url); var fullJustName = full.Split('?', '#')[0]; BuildResult.Path2FileInfo.TryGetValue(fullJustName, out var fileAdditionalInfo); FilesContent.GetOrAddValueRef(BuildResult.ToOutputUrl(fileAdditionalInfo)) = fileAdditionalInfo.Owner.ByteContent; return(PathUtils.GetFile(fileAdditionalInfo.OutputUrl) + full.Substring(fullJustName.Length)); }).Result; var cssImports = ""; foreach (var match in Regex.Matches(cssContent, "@import .*;")) { cssImports += match.ToString(); cssContent = cssContent.Replace(match.ToString(), ""); } FilesContent.GetOrAddValueRef(cssPath) = cssImports + cssContent; cssLink += "<link rel=\"stylesheet\" href=\"" + cssPath + "\">"; } if (Project.SpriteGeneration) { _bundlePng = Project.BundlePngUrl; var bundlePngContent = Project.SpriteGenerator.BuildImage(true); if (bundlePngContent != null) { _bundlePngInfo = new List <float>(); foreach (var slice in bundlePngContent) { FilesContent.GetOrAddValueRef(PathUtils.InjectQuality(_bundlePng, slice.Quality)) = slice.Content; _bundlePngInfo.Add(slice.Quality); } } else { _bundlePng = null; } } var bundler = new BundlerImpl(_tools); bundler.Callbacks = this; if (Project.ExampleSources.Count > 0) { bundler.MainFiles = new[] { Project.ExampleSources[0] }; } else { bundler.MainFiles = new[] { Project.MainFile }; } _mainJsBundleUrl = BuildResult.BundleJsUrl; bundler.Compress = compress; bundler.Mangle = mangle; bundler.Beautify = beautify; var defines = new Dictionary <string, object>(); foreach (var p in Project.Defines) { defines.Add(p.Key, p.Value); } bundler.Defines = defines; bundler.Bundle(); if (!Project.NoHtml) { BuildFastBundlerIndexHtml(cssLink); FilesContent.GetOrAddValueRef("index.html") = _indexHtml; } }