public static (string outAst, string outMinJs, string outNiceJs) CompressTestCore(CompressTestData testData, ICompressOptions options) { string outAst; var outNiceJs = string.Empty; var outMinJs = string.Empty; try { var parser = new Parser(new Options(), testData.InputContent); var toplevel = parser.Parse(); toplevel.FigureOutScope(); toplevel = toplevel.Compress(options); var strSink = new StringLineSink(); var dumper = new DumpAst(new AstDumpWriter(strSink)); dumper.Walk(toplevel); outAst = strSink.ToString(); var outMinJsBuilder = new SourceMapBuilder(); toplevel.PrintToBuilder(outMinJsBuilder, new OutputOptions()); outMinJs = outMinJsBuilder.Content(); var outNiceJsBuilder = new SourceMapBuilder(); toplevel.PrintToBuilder(outNiceJsBuilder, new OutputOptions { Beautify = true }); outNiceJs = outNiceJsBuilder.Content(); } catch (SyntaxError e) { outAst = e.Message; } return(outAst, outMinJs, outNiceJs); }
public string ReadContent(string name) { if (!BuildResult.Path2FileInfo.TryGetValue(name, out var fileInfo)) { throw new InvalidOperationException("Bundler ReadContent does not exists:" + name); } if (fileInfo.Type == FileCompilationType.ImportedCss || fileInfo.Type == FileCompilationType.Css) { return(""); } if (fileInfo.Type == FileCompilationType.Json) { return(fileInfo.Owner.Utf8Content); } if (fileInfo.Type == FileCompilationType.JavaScriptAsset || fileInfo.Type == FileCompilationType.JavaScript || fileInfo.Type == FileCompilationType.EsmJavaScript) { return(fileInfo.Output); } if (fileInfo.Type == FileCompilationType.TypeScriptDefinition) { return(""); } if (fileInfo.Type == FileCompilationType.TypeScript) { var sourceMapBuilder = new SourceMapBuilder(); var adder = sourceMapBuilder.CreateSourceAdder(fileInfo.Output, fileInfo.MapLink); var sourceReplacer = new SourceReplacer(); Project.ApplySourceInfo(sourceReplacer, fileInfo.SourceInfo, BuildResult); sourceReplacer.Apply(adder); return(sourceMapBuilder.Content()); } throw new InvalidOperationException("Bundler Read Content unknown type " + Enum.GetName(typeof(FileCompilationType), fileInfo.Type) + ":" + name); }
public void AddFile( string type, string filename, ArraySegment <byte> bytes, int?position = null, Dictionary <string, object> properties = null, SourceMapBuilder sourceMapBuilder = null ) { lock (Files) { if (position.HasValue) { FileOrder.Insert(position.Value, filename); } else { FileOrder.Add(filename); } Files.Add(filename, new ResultFile { Type = type, Filename = filename, Contents = bytes, Size = bytes.Count, Properties = properties, SourceMapBuilder = sourceMapBuilder }); } }
public void PrintToBuilder(SourceMapBuilder builder, OutputOptions?options = null) { var o = new OutputContext(options, builder); Print(o); builder.AddMapping(null, 0, 0, false); }
public void GivenAMapExistsForTheTheCSVFileSource() { var map = new SourceMapBuilder() .WithIndex(0) .WithDataType(typeof(string)) .Build(); _appContext.CsvFileSource.SetMaps(new List <SourceMap> { map }); }
string Optimize(string input, ICompressOptions compressOptions) { var parser = new Parser(new Options(), input); var toplevel = parser.Parse(); toplevel = toplevel.Compress(compressOptions); var outMinJsBuilder = new SourceMapBuilder(); toplevel.PrintToBuilder(outMinJsBuilder, new OutputOptions()); return(outMinJsBuilder.Content()); }
public void WriteBundle(string name, SourceMapBuilder content) { content.AddText("//# sourceMappingURL=" + name + ".map"); var source = content.Content(); var sm = content.Build(_mainBuildResult.CommonSourceDirectory, SourceMapSourceRoot ?? "..").ToString(); _logger.Info("Bundler created " + name + " with " + source.Length + " chars and sourcemap with " + sm.Length + " chars"); _mainBuildResult.FilesContent.GetOrAddValueRef(name) = source; _mainBuildResult.FilesContent.GetOrAddValueRef(name + ".map") = sm; }
public static SourceMap Identity(string content, string fileName) { var sb = new StringBuilder(); sb.Append("AAAA"); var endsWithNL = SourceMapBuilder.EndsWithNewLine(content); var len = content.Length - (endsWithNL ? 1 : 0); for (var i = 0; i < len; i++) { if (content[i] == '\n') { sb.Append(";AACA"); } } if (endsWithNL) { sb.Append(';'); } return(new(new() { fileName }) { mappings = sb.ToString() });
public void SourceMapBuilder_BuildWorks() { var builder = new SourceMapBuilder( "test.map", @"C:\AC\ACD", @"C:\A\AB"); builder.AddMapping(1, 11, new SourceLocation(@"C:\AC\ACD\sourceUrl1", "sourceName1", 10, 10)); builder.AddMapping(2, 21, new SourceLocation(@"C:\AC\ACD\X\sourceUrl2", "sourceName2", 20, 20)); builder.AddMapping(3, 31, new SourceLocation(@"C:\AC\ACD\Y\Z\sourceUrl3", "sourceName3", 30, 30)); builder.AddMapping(4, 41, new SourceLocation(@"C:\B\sourceUrl4", "sourceName4", 40, 40)); builder.AddMapping(5, 51, new SourceLocation(@"C:\A\AB\ABE\sourceUrl5", "sourceName5", 50, 50)); builder.AddMapping(6, 61, new SourceLocation(@"C:\A\AB\AB F\sourceUrl6", "sourceName6", 60, 60)); var map = builder.Build( new[] { "1", "2", "3", "4", "5", "6" }); var expectedMap = StringHelper.CombineLinesNL ( "{", " \"version\": 3,", " \"file\": \"test.map\",", " \"sourceRoot\": \"C:\\AC\\ACD\",", " \"sources\": [\"../../AC/ACD/sourceUrl1\",\"../../AC/ACD/X/sourceUrl2\",\"../../AC/ACD/Y/Z/sourceUrl3\",\"../../B/sourceUrl4\",\"ABE/sourceUrl5\",\"AB F/sourceUrl6\"],", " \"names\": [\"sourceName1\",\"sourceName2\",\"sourceName3\",\"sourceName4\",\"sourceName5\",\"sourceName6\"],", " \"mappings\": \";WAUUA;qBCUUC;+BCUUC;yCCUUC;mDCUUC;6DCUUC\",", " \"sourcesContent\": [\"1\",\"2\",\"3\",\"4\",\"5\",\"6\"]", "}" ); expectedMap = TextHelper.NormilizeEols(expectedMap, UnicodeNewline.LF); Assert.AreEqual(expectedMap, map); }
public SourceMapTextAdder(SourceMapBuilder owner, string content, SourceMap sourceMap) { _owner = owner; _iterator = new SourceMapIterator(content, sourceMap); _sourceRemap = new StructList <int>(); ref var ownerSources = ref owner._sources;
public PlainTextAdder(SourceMapBuilder owner, string content) { _owner = owner; _content = content; }
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.RecompiledIncrementally.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 is FileCompilationType.TypeScript or FileCompilationType.EsmJavaScript or FileCompilationType.JavaScript) { if (source.Output == null) { continue; // Skip d.ts } var moduleName = source.Owner !.FullPath; if (source.Type is FileCompilationType.TypeScript or FileCompilationType.EsmJavaScript or FileCompilationType.JavaScript) { moduleName = PathUtils.WithoutExtension(moduleName); } sourceMapBuilder.AddText( $"R('{PathUtils.Subtract(moduleName, 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});"); }
private static void WriteBytesToFile(string folder, string name, ArraySegment <byte> bytes, SourceMapBuilder sourceMapBuilder = null) { var filePath = Path.Combine(folder, name); var fileMode = File.Exists(filePath) ? FileMode.Truncate : FileMode.CreateNew; EnsureDirectoryExists(Path.GetDirectoryName(filePath)); bool writeMapLink = sourceMapBuilder != null && sourceMapBuilder.Build(folder, name); using (var fs = File.Open(filePath, fileMode, FileAccess.Write, FileShare.Read)) { fs.Write(bytes.Array, bytes.Offset, bytes.Count); if (writeMapLink) { sourceMapBuilder.WriteSourceMapLink(fs, folder, name); } fs.Flush(); } }
public (string?, SourceMap?) ReadContent(string name) { if (name == "<empty>") { return("module.exports = {};", null); } if (!_buildResult.Path2FileInfo.TryGetValue(name, out var fileInfo)) { throw new InvalidOperationException("Bundler ReadContent does not exists:" + name); } if (fileInfo.Type == FileCompilationType.ImportedCss || fileInfo.Type == FileCompilationType.Css) { return("", null); } if (fileInfo.Type == FileCompilationType.Json) { if (BuildSourceMap) { return(fileInfo.Owner.Utf8Content, SourceMap.Identity(fileInfo.Owner.Utf8Content, fileInfo.Owner.FullPath)); } return(fileInfo.Owner.Utf8Content, null); } if (fileInfo.Type == FileCompilationType.JavaScriptAsset || fileInfo.Type == FileCompilationType.JavaScript) { if (BuildSourceMap) { return(fileInfo.Output, SourceMap.Identity(fileInfo.Output, fileInfo.Owner.FullPath)); } return(fileInfo.Output, null); } if (fileInfo.Type == FileCompilationType.TypeScriptDefinition) { return("", null); } if (fileInfo.Type is FileCompilationType.TypeScript or FileCompilationType.EsmJavaScript) { if (BuildSourceMap) { var sourceMapBuilder = new SourceMapBuilder(); var adder = sourceMapBuilder.CreateSourceAdder(fileInfo.Output, fileInfo.MapLink); var sourceReplacer = new SourceReplacer(); _project.ApplySourceInfo(sourceReplacer, fileInfo.SourceInfo, _buildResult); sourceReplacer.Apply(adder); return(sourceMapBuilder.Content(), sourceMapBuilder.Build(".", ".")); } else { var sourceMapBuilder = new SourceMapBuilder(); var adder = sourceMapBuilder.CreateSourceAdder(fileInfo.Output, fileInfo.MapLink); var sourceReplacer = new SourceReplacer(); _project.ApplySourceInfo(sourceReplacer, fileInfo.SourceInfo, _buildResult); sourceReplacer.Apply(adder); return(sourceMapBuilder.Content(), null); } } throw new InvalidOperationException("Bundler Read Content unknown type " + Enum.GetName(typeof(FileCompilationType), fileInfo.Type) + ":" + name); }
ParseTestCore( ParserTestData testData) { string outAst; var outMinJs = string.Empty; var outMinJsMap = string.Empty; var outNiceJs = string.Empty; var outNiceJsMap = string.Empty; try { var comments = new List <(bool block, string content, SourceLocation location)>(); var commentListener = new CommentListener(); var parser = new Parser( new() { SourceFile = testData.SourceName, EcmaVersion = testData.EcmaScriptVersion, OnComment = (block, content, location) => { commentListener.OnComment(block, content, location); comments.Add((block, content, location)); }, SourceType = testData.SourceName.StartsWith("module-") ? SourceType.Module : SourceType.Script }, testData.Input); var toplevel = parser.Parse(); commentListener.Walk(toplevel); SourceMap?inputSourceMap = null; if (testData.InputSourceMap != null) { inputSourceMap = SourceMap.Parse(testData.InputSourceMap, "."); inputSourceMap.ResolveInAst(toplevel); } var strSink = new StringLineSink(); toplevel.FigureOutScope(); var dumper = new DumpAst(new AstDumpWriter(strSink)); dumper.Walk(toplevel); foreach (var(block, content, location) in comments) { strSink.Print( $"{(block ? "Block" : "Line")} Comment ({location.Start.ToShortString()}-{location.End.ToShortString()}): {content}"); } outAst = strSink.ToString(); var outMinJsBuilder = new SourceMapBuilder(); var outputOptions = new OutputOptions { Shorthand = testData.EcmaScriptVersion >= 6 }; toplevel.PrintToBuilder(outMinJsBuilder, outputOptions); outMinJsBuilder.AddText( $"//# sourceMappingURL={PathUtils.ChangeExtension(testData.SourceName, "minjs.map")}"); if (inputSourceMap != null) { outMinJsBuilder.AttachSourcesContent(inputSourceMap); } outMinJs = outMinJsBuilder.Content(); outMinJsMap = outMinJsBuilder.Build(".", ".").ToString(); var outNiceJsBuilder = new SourceMapBuilder(); outputOptions = new() { Beautify = true, Shorthand = testData.EcmaScriptVersion >= 6 }; toplevel.PrintToBuilder(outNiceJsBuilder, outputOptions); outNiceJsBuilder.AddText( $"//# sourceMappingURL={PathUtils.ChangeExtension(testData.SourceName, "nicejs.map")}"); if (inputSourceMap != null) { outNiceJsBuilder.AttachSourcesContent(inputSourceMap); } outNiceJs = outNiceJsBuilder.Content(); outNiceJsMap = outNiceJsBuilder.Build(".", ".").ToString(); strSink = new StringLineSink(); toplevel.FigureOutScope(); dumper = new DumpAst(new AstDumpWriter(strSink)); dumper.Walk(toplevel); var beforeClone = strSink.ToString(); toplevel = toplevel.DeepClone(); strSink = new StringLineSink(); toplevel.FigureOutScope(); dumper = new DumpAst(new AstDumpWriter(strSink)); dumper.Walk(toplevel); var afterClone = strSink.ToString(); if (beforeClone != afterClone) { throw new Exception("Dump of clone is not identical"); } toplevel.Mangle(); } catch (SyntaxError e) { outAst = e.Message; } return(outAst, outMinJs, outMinJsMap, outNiceJs, outNiceJsMap); }
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 static Dictionary <string, string> BobrilSourceInfoTestCore(BobrilSourceInfoTestData testData) { var output = new Dictionary <string, string>(); var source = SourceMap.RemoveLinkToSourceMap(testData.InputContent["index.js"]); var toplevel = Parser.Parse(source); toplevel.FigureOutScope(); var files = new InMemoryImportResolver(); var ctx = new ResolvingConstEvalCtx("index.js", files); var sourceInfo = GatherBobrilSourceInfo.Gather(toplevel, ctx, (myctx, text) => { if (text.StartsWith('.')) { return(PathUtils.Join(PathUtils.Parent(myctx.SourceName), text)); } return(text); }); var builder = new SourceMapBuilder(); var adder = builder.CreateSourceAdder(source, testData.InputContent.ContainsKey("index.js.map") ? SourceMap.Parse(testData.InputContent["index.js.map"], ".") : null); var sourceReplacer = new SourceReplacer(); ProcessReplacements(sourceReplacer, sourceInfo); sourceReplacer.Apply(adder); builder.AddText("//# sourceMappingURL=index.js.map"); output["index.sourceinfo.json"] = JsonSerializer .Serialize(sourceInfo, new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }) .Replace("\r\n", "\n"); output["index.js"] = builder.Content(); output["index.js.map"] = builder.Build(".", "..").ToString(); if (testData.InputContent.ContainsKey("index.js.map")) { SourceMap.Parse(testData.InputContent["index.js.map"], ".").ResolveInAst(toplevel); } var coverageInstrumentation = new CoverageInstrumentation(); toplevel = coverageInstrumentation.Instrument(toplevel); coverageInstrumentation.AddCountingHelpers(toplevel); coverageInstrumentation.CleanUp(new TestUtf8Reader(testData.InputContent)); builder = new SourceMapBuilder(); toplevel.PrintToBuilder(builder, new OutputOptions { Beautify = true }); builder.AddText("//# sourceMappingURL=cov.js.map"); output["cov.info.json"] = JsonSerializer .Serialize(coverageInstrumentation.InstrumentedFiles, new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }) .Replace("\r\n", "\n"); output["cov.js"] = builder.Content(); output["cov.js.map"] = builder.Build(".", "..").ToString(); return(output); }
public void Run() { var stopwatch = Stopwatch.StartNew(); foreach (var(splitName, mainFileList) in PartToMainFilesMap) { foreach (var mainFile in mainFileList) { if (_cache.TryGetValue(mainFile, out var sourceFile)) { MarkRequiredAs(sourceFile, splitName); continue; } Check(mainFile, splitName); } _splitMap[splitName] = new SplitInfo(splitName) { ShortName = _ctx.GenerateBundleName(splitName), PropName = "ERROR", IsMainSplit = true }; } stopwatch.Stop(); _ctx.ReportTime("Parse", stopwatch.Elapsed); foreach (var(_, sourceFile) in _cache) { foreach (var(file, path) in sourceFile.NeedsImports) { _cache.TryGetValue(file, out var targetFile); targetFile !.CreateWholeExport(path); } } var lazySplitCounter = 0; foreach (var f in _order) { var fullBundleName = f.PartOfBundle !; if (!_splitMap.TryGetValue(fullBundleName, out var split)) { var shortenedBundleName = _ctx.GenerateBundleName(fullBundleName); split = new SplitInfo(fullBundleName) { ShortName = shortenedBundleName, PropName = BundlerHelpers.NumberToIdent(lazySplitCounter++) }; _splitMap[fullBundleName] = split; } foreach (var dependency in f.PlainJsDependencies) { split.PlainJsDependencies.Add(dependency); } } if (lazySplitCounter > 0) { DetectBundleExportsImports(ref lazySplitCounter); } foreach (var(splitName, splitInfo) in _splitMap) { var topLevelAst = Parser.Parse(_ctx.JsHeaders(splitName, lazySplitCounter > 0)); if (GlobalDefines != null && GlobalDefines.Count > 0) { topLevelAst.Body.Add(Helpers.EmitVarDefines(GlobalDefines)); } topLevelAst.FigureOutScope(); foreach (var jsDependency in splitInfo.PlainJsDependencies) { var content = _ctx.ReadContent(jsDependency); var jsAst = Parser.Parse(content.Item1 !); content.Item2?.ResolveInAst(jsAst); jsAst.FigureOutScope(); BundlerHelpers.SimplifyJavaScriptDependency(jsAst); _currentFileIdent = BundlerHelpers.FileNameToIdent(jsDependency); BundlerHelpers.AppendToplevelWithRename(topLevelAst, jsAst, _currentFileIdent); } foreach (var sourceFile in _order) { if (sourceFile.PartOfBundle != splitName) { continue; } foreach (var keyValuePair in sourceFile.Ast.Globals !) { topLevelAst.Globals !.TryAdd(keyValuePair.Key, keyValuePair.Value); topLevelAst.NonRootSymbolNames?.Add(keyValuePair.Key); } } AddExternallyImportedFromOtherBundles(topLevelAst, splitInfo); foreach (var sourceFile in _order) { if (sourceFile.PartOfBundle != splitName) { continue; } _currentSourceFile = sourceFile; _currentFileIdent = BundlerHelpers.FileNameToIdent(sourceFile.Name); BundlerHelpers.AppendToplevelWithRename(topLevelAst, sourceFile.Ast, _currentFileIdent , BeforeAdd); } IfNeededPolyfillGlobal(topLevelAst); AddExportsFromLazyBundle(splitInfo, topLevelAst); BundlerHelpers.WrapByIIFE(topLevelAst); if (lazySplitCounter > 0 && PartToMainFilesMap.ContainsKey(splitName)) { var astVar = new AstVar(topLevelAst); astVar.Definitions.Add(new AstVarDef(new AstSymbolVar("__bbb"), new AstObject())); topLevelAst.Body.Insert(0) = astVar; } if (CompressOptions != null) { stopwatch = Stopwatch.StartNew(); topLevelAst.FigureOutScope(); topLevelAst = topLevelAst.Compress(CompressOptions, new ScopeOptions { TopLevel = false, BeforeMangling = IgnoreEvalInTwoScopes }); stopwatch.Stop(); _ctx.ReportTime("Compress", stopwatch.Elapsed); } if (Mangle) { stopwatch = Stopwatch.StartNew(); topLevelAst.Mangle(new ScopeOptions { FrequencyCounting = MangleWithFrequencyCounting, TopLevel = false, BeforeMangling = IgnoreEvalInTwoScopes }, OutputOptions); stopwatch.Stop(); _ctx.ReportTime("Mangle", stopwatch.Elapsed); } _ctx.ModifyBundle(splitInfo.ShortName !, topLevelAst); if (GenerateSourceMap) { stopwatch = Stopwatch.StartNew(); var builder = new SourceMapBuilder(); topLevelAst.PrintToBuilder(builder, OutputOptions); stopwatch.Stop(); _ctx.ReportTime("Print", stopwatch.Elapsed); _ctx.WriteBundle(splitInfo.ShortName !, builder); } else { stopwatch = Stopwatch.StartNew(); var content = topLevelAst.PrintToString(OutputOptions); stopwatch.Stop(); _ctx.ReportTime("Print", stopwatch.Elapsed); _ctx.WriteBundle(splitInfo.ShortName !, content); } } }
static void Test2() { SourceMaps.List <SourceFile> sources = new SourceMaps.List <SourceFile>(); sources.Add(new SourceFile("http://www.mysite.com/source1.txt", LoadFromFile(@"..\..\..\Website\source1.txt"))); sources.Add(new SourceFile("http://www.mysite.com/source2.txt", LoadFromFile(@"..\..\..\Website\source2.txt"))); string destfile = ""; foreach (var sf in sources) { destfile += sf.content.ToLower(); } destfile += "\r\n//# sourceMappingURL=myapp.js.map"; SaveToFile(@"..\..\..\Website\myapp.js", destfile); SourceFile target = new SourceFile("http://www.mysite.com/myapp.js", destfile); // build tokens/source map entries SourceMaps.List <SourceMapEntry> sme = new SourceMaps.List <SourceMapEntry>(); // this will map every single character, no name specified int cumulative_l = 0; foreach (var sf in sources) { for (int cx = 0; cx < sf.content.Length; cx++) { string c = ""; //sf.content[cx].ToString(); var tok = new TokenSourceFileLocation(sf, c, cx); sme.add(new SourceMapEntry(tok, cx + cumulative_l)); } cumulative_l += sf.length; } // this maps only identifiers /* * Regex R = new Regex(@"[_a-zA-Z][_a-zA-Z0-9]*"); * int cumulative_l = 0; * foreach(var sf in sources) * { * MatchCollection mc = R.Matches(sf.content); * foreach(Match match in mc) * { * var keyword = match.Value.ToLower(); * * var tok = new TokenSourceFileLocation(sf, match.Value.ToLower(), match.Index); * sme.add( new SourceMapEntry(tok,match.Index+cumulative_l)); * } * cumulative_l += sf.length; * } */ Uri sourceMapUri = Uri.parse("http://www.mysite.com/myapp.map"); Uri fileUri = Uri.parse("http://www.mysite.com/myapp.js"); SourceMapBuilder sourceMapBuilder = new SourceMapBuilder(sourceMapUri, fileUri, target); foreach (var e in sme) { sourceMapBuilder.addMapping(e.targetOffset, e.sourceLocation); } String sourceMap = sourceMapBuilder.build(); SaveToFile(@"..\..\..\Website\myapp.js.map", sourceMap); }
public void Build(string sourceRoot, string mapUrl, bool testProj = false) { _versionDirPrefix = ""; if (Project.OutputSubDir != null) { _versionDirPrefix = Project.OutputSubDir + "/"; } var root = Project.CommonSourceDirectory; if (root == null) { return; } var sourceMapBuilder = new SourceMapBuilder(); if (!testProj && Project.NoHtml) { sourceMapBuilder.AddText(GetInitG11nCode()); sourceMapBuilder.AddText(_tools.LoaderJs); sourceMapBuilder.AddText(GetGlobalDefines()); sourceMapBuilder.AddText(GetModuleMap()); } sourceMapBuilder.AddText(_tools.TsLibSource); var cssLink = ""; foreach (var source in BuildResult.Path2FileInfo) { if (source.Value.Type == FileCompilationType.JavaScriptAsset) { sourceMapBuilder.AddSource(source.Value.Output, source.Value.MapLink); } } foreach (var source in BuildResult.Path2FileInfo) { if (source.Value.Type == FileCompilationType.TypeScript || source.Value.Type == FileCompilationType.JavaScript) { if (source.Value.Output == null) { continue; // Skip d.ts } sourceMapBuilder.AddText( $"R('{PathUtils.Subtract(PathUtils.WithoutExtension(source.Key), root)}',function(require, module, exports, global){{"); sourceMapBuilder.AddSource(source.Value.Output, source.Value.MapLink); sourceMapBuilder.AddText("});"); } else if (source.Value.Type == FileCompilationType.Css) { string cssPath = source.Value.OutputUrl; FilesContent[cssPath] = source.Value.Output; cssLink += "<link rel=\"stylesheet\" href=\"" + cssPath + "\">"; } else if (source.Value.Type == FileCompilationType.Resource) { FilesContent[source.Value.OutputUrl] = source.Value.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[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))}');"); } sourceMapBuilder.AddText("//# sourceMappingURL=" + mapUrl); _sourceMap = sourceMapBuilder.Build(root, sourceRoot); _sourceMapString = _sourceMap.ToString(); _bundleJs = sourceMapBuilder.Content(); if (!testProj && !Project.NoHtml && Project.ExampleSources.Count > 0) { if (Project.ExampleSources.Count == 1) { BuildFastBundlerIndexHtml( PathUtils.WithoutExtension(PathUtils.Subtract(Project.ExampleSources[0], root)), cssLink); } else { var htmlList = new List <string>(); foreach (var exampleSrc in Project.ExampleSources) { var moduleNameWOExt = PathUtils.WithoutExtension(PathUtils.Subtract(exampleSrc, root)); BuildFastBundlerIndexHtml(moduleNameWOExt, cssLink); var justName = PathUtils.SplitDirAndFile(moduleNameWOExt).Item2; FilesContent[justName + ".html"] = _indexHtml; htmlList.Add(justName); } BuildExampleListHtml(htmlList, cssLink); } } else if (testProj) { BuildFastBundlerTestHtml(Project.TestSources, root, cssLink); } else if (!Project.NoHtml) { BuildFastBundlerIndexHtml(PathUtils.WithoutExtension(PathUtils.Subtract(Project.MainFile, root)), cssLink); } if (testProj) { FilesContent["test.html"] = _indexHtml; FilesContent[_versionDirPrefix + "jasmine-core.js"] = _tools.JasmineCoreJs; FilesContent[_versionDirPrefix + "jasmine-boot.js"] = _tools.JasmineBootJs; FilesContent[_versionDirPrefix + "loader.js"] = _tools.LoaderJs; } else if (!Project.NoHtml) { FilesContent["index.html"] = _indexHtml; FilesContent[_versionDirPrefix + "loader.js"] = _tools.LoaderJs; if (Project.LiveReloadEnabled) { FilesContent[_versionDirPrefix + "liveReload.js"] = _tools.LiveReloadJs.Replace("##Idx##", (Project.LiveReloadIdx + 1).ToString()); } } FilesContent[_versionDirPrefix + PathUtils.WithoutExtension(mapUrl)] = _bundleJs; FilesContent[_versionDirPrefix + mapUrl] = _sourceMapString; BuildResult.SourceMap = _sourceMap; }
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 } }; } }