public static TSFileAdditionalInfo AutodetectAndAddDependencyCore(ProjectOptions projectOptions, string depName, IFileCache usedFrom) { var dc = projectOptions.Owner.DiskCache; var extension = PathUtils.GetExtension(depName); var depFile = dc.TryGetItem(depName) as IFileCache; if (depFile == null) { if (usedFrom != null) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("In " + usedFrom.FullPath + " missing dependency " + depName); Console.ForegroundColor = ConsoleColor.Gray; TSFileAdditionalInfo.Get(usedFrom, dc).ReportDiag(true, -3, "Missing dependency " + depName, 0, 0, 0, 0); } else { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Somethere missing dependency " + depName); Console.ForegroundColor = ConsoleColor.Gray; } return(null); } var assetFileInfo = TSFileAdditionalInfo.Get(depFile, dc); if (projectOptions.BundleCss && extension == "css") { assetFileInfo.Type = FileCompilationType.Css; return(assetFileInfo); } if (assetFileInfo.OutputUrl == null) { assetFileInfo.OutputUrl = projectOptions.AllocateName(PathUtils.Subtract(depFile.FullPath, projectOptions.Owner.Owner.FullPath)); } switch (extension) { case "css": assetFileInfo.Type = FileCompilationType.Css; break; case "js": assetFileInfo.Type = FileCompilationType.JavaScriptAsset; break; default: assetFileInfo.Type = FileCompilationType.Resource; break; } return(assetFileInfo); }
public void FillOutputByAssets(MainBuildResult buildResult, string nodeModulesDir, ProjectOptions projectOptions) { if (Assets == null) { return; } foreach (var asset in Assets) { var fromModules = asset.Key.StartsWith("node_modules/"); var fullPath = fromModules ? nodeModulesDir : Owner.FullPath; if (fromModules) { if (projectOptions.Owner.UsedDependencies == null) { projectOptions.Owner.UsedDependencies = new HashSet <string>(); } var pos = 0; PathUtils.EnumParts(asset.Key, ref pos, out var name, out var isDir); PathUtils.EnumParts(asset.Key, ref pos, out name, out isDir); projectOptions.Owner.UsedDependencies.Add(name.ToString()); } var item = DiskCache.TryGetItem(PathUtils.Join(fullPath, asset.Key)); if (item == null || item.IsInvalid) { continue; } if (item is IFileCache) { buildResult.TakenNames.Add(asset.Value); buildResult.FilesContent.GetOrAddValueRef(asset.Value) = new Lazy <object>(() => { var res = ((IFileCache)item).ByteContent; ((IFileCache)item).FreeCache(); return(res); }); } else { RecursiveAddFilesContent(item as IDirectoryCache, buildResult, asset.Value); } } }
public void FillOutputByAssets(RefDictionary <string, object> filesContent, HashSet <string> takenNames, string nodeModulesDir, ProjectOptions projectOptions) { if (Assets == null) { return; } foreach (var asset in Assets) { var fromModules = asset.Key.StartsWith("node_modules/"); var fullPath = fromModules ? nodeModulesDir : Owner.FullPath; if (fromModules) { if (projectOptions.Owner.UsedDependencies == null) { projectOptions.Owner.UsedDependencies = new HashSet <string>(); } projectOptions.Owner.UsedDependencies.Add(PathUtils.EnumParts(asset.Key).Skip(1).Select(a => a.name) .First()); } var item = DiskCache.TryGetItem(PathUtils.Join(fullPath, asset.Key)); if (item == null || item.IsInvalid) { continue; } if (item is IFileCache) { takenNames.Add(asset.Value); filesContent.GetOrAddValueRef(asset.Value) = new Lazy <object>(() => { var res = ((IFileCache)item).ByteContent; ((IFileCache)item).FreeCache(); return(res); }); } else { RecursiveAddFilesContent(item as IDirectoryCache, filesContent, takenNames, asset.Value); } } }
public void LoadProjectJson(bool forbiddenDependencyUpdate) { DiskCache.UpdateIfNeeded(Owner); var packageJsonFile = Owner.TryGetChild("package.json", true); if (packageJsonFile is IFileCache cache) { var newChangeId = cache.ChangeId; if (newChangeId == PackageJsonChangeId) { return; } MainFileNeedsToBeCompiled = false; JObject parsed; try { parsed = JObject.Parse(cache.Utf8Content); } catch (Exception) { parsed = new JObject(); } var deps = new HashSet <string>(); var devdeps = new HashSet <string>(); var hasMain = false; if (parsed.GetValue("typescript") is JObject parsedT) { if (parsedT.GetValue("main") is JValue mainV) { MainFile = PathUtils.Normalize(mainV.ToString()); TypesMainFile = null; hasMain = true; } } if (parsed.GetValue("module") is JValue moduleV) { MainFile = PathUtils.Normalize(moduleV.ToString()); MainFileNeedsToBeCompiled = true; if (DiskCache.TryGetItem(PathUtils.Join(Owner.FullPath, MainFile)) is IFileCache) { hasMain = true; if (parsed.GetValue("typings") is JValue mainV) { TypesMainFile = PathUtils.Normalize(mainV.ToString()); } } } if (!hasMain) { if (parsed.GetValue("main") is JValue mainV2) { MainFile = PathUtils.Normalize(mainV2.ToString()); } else { MainFile = "index.js"; } if (DiskCache.TryGetItem(PathUtils.Join(Owner.FullPath, PathUtils.ChangeExtension(MainFile, "ts"))) is IFileCache fileAsTs) { MainFile = PathUtils.ChangeExtension(MainFile, "ts"); TypesMainFile = null; hasMain = true; } else { fileAsTs = DiskCache.TryGetItem(PathUtils.Join(Owner.FullPath, PathUtils.ChangeExtension(MainFile, "tsx"))) as IFileCache; if (fileAsTs != null) { MainFile = PathUtils.ChangeExtension(MainFile, "tsx"); TypesMainFile = null; hasMain = true; } } if (!hasMain) { if (parsed.GetValue("types") is JValue mainV) { TypesMainFile = PathUtils.Normalize(mainV.ToString()); hasMain = true; } } } if (TypesMainFile == null) { TypesMainFile = PathUtils.ChangeExtension(MainFile, "d.ts"); if (!IsRootProject && !(DiskCache.TryGetItem(PathUtils.Join(Owner.FullPath, TypesMainFile)) is IFileCache)) { var typesDts = PathUtils.Join(Owner.FullPath, $"../@types/{Owner.Name}/index.d.ts"); if (DiskCache.TryGetItem(typesDts) is IFileCache) { TypesMainFile = typesDts; } } } if (parsed.GetValue("dependencies") is JObject parsedV) { foreach (var i in parsedV.Properties()) { deps.Add(i.Name); } } if (parsed.GetValue("devDependencies") is JObject parsedV2) { foreach (var i in parsedV2.Properties()) { devdeps.Add(i.Name); } } PackageJsonChangeId = newChangeId; Dependencies = deps; DevDependencies = devdeps; Assets = ParseBobrilAssets(parsed); if (ProjectOptions == null) { return; } ProjectOptions.FillProjectOptionsFromPackageJson(parsed); if (forbiddenDependencyUpdate || ProjectOptions.DependencyUpdate == DepedencyUpdate.Disabled) { return; } var packageManager = new CurrentNodePackageManager(DiskCache, Logger); if (ProjectOptions.DependencyUpdate == DepedencyUpdate.Upgrade) { packageManager.UpgradeAll(Owner); } else { packageManager.Install(Owner); } DiskCache.CheckForTrueChange(); DiskCache.ResetChange(); } else { MainFile = "index.js"; Dependencies = new HashSet <string>(); DevDependencies = new HashSet <string>(); Assets = null; ProjectOptions?.FillProjectOptionsFromPackageJson(null); } }
public void Build(BuildCtx buildCtx) { var buildModuleCtx = new BuildModuleCtx() { _buildCtx = buildCtx, _owner = this, _result = new BuildResult(), ToCheck = new OrderedHashSet <string>(), ToCompile = new OrderedHashSet <string>(), ToCompileDts = new OrderedHashSet <string>() }; ITSCompiler compiler = null; try { ProjectOptions.BuildCache.StartTransaction(); compiler = buildCtx.CompilerPool.GetTs(); compiler.DiskCache = DiskCache; compiler.Ctx = buildModuleCtx; var compOpt = buildCtx.TSCompilerOptions.Clone(); compOpt.rootDir = Owner.FullPath; compOpt.outDir = "_virtual"; compOpt.module = ModuleKind.Commonjs; compOpt.declaration = true; if (!ProjectOptions.TypeScriptVersionOverride && DevDependencies != null && DevDependencies.Contains("typescript")) { ProjectOptions.Tools.SetTypeScriptPath(Owner.FullPath); } else { ProjectOptions.Tools.SetTypeScriptVersion(ProjectOptions.TypeScriptVersion); } compiler.MergeCompilerOptions(compOpt); compiler.MergeCompilerOptions(ProjectOptions.CompilerOptions); var positionIndependentOptions = compiler.CompilerOptions.Clone(); positionIndependentOptions.rootDir = null; var trueTSVersion = compiler.GetTSVersion(); buildCtx.ShowTsVersion(trueTSVersion); ProjectOptions.ConfigurationBuildCacheId = ProjectOptions.BuildCache.MapConfiguration(trueTSVersion, JsonConvert.SerializeObject(positionIndependentOptions, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore })); var wasSomeError = false; do { buildModuleCtx.ChangedDts = false; buildModuleCtx.CrawledCount = 0; buildModuleCtx.ToCheck.Clear(); buildModuleCtx.ToCompile.Clear(); buildModuleCtx.ToCompileDts.Clear(); buildModuleCtx.LocalResolveCache.Clear(); ProjectOptions.HtmlHeadExpanded = buildModuleCtx.ExpandHtmlHead(ProjectOptions.HtmlHead); foreach (var src in buildCtx.Sources) { buildModuleCtx.CheckAdd(PathUtils.Join(compOpt.rootDir, src)); } if (ProjectOptions.IncludeSources != null) { foreach (var src in ProjectOptions.IncludeSources) { buildModuleCtx.CheckAdd(PathUtils.Join(compOpt.rootDir, src)); } } buildModuleCtx.Crawl(); if (buildModuleCtx.ToCompile.Count != 0) { if (buildCtx.Verbose) { compiler.MeasurePerformance = true; } var start = DateTime.UtcNow; buildModuleCtx.OutputedJsFiles = 0; buildModuleCtx.OutputedDtsFiles = 0; compiler.CreateProgram(Owner.FullPath, buildModuleCtx.ToCompile.Concat(buildModuleCtx.ToCompileDts).ToArray()); if (!compiler.CompileProgram()) { wasSomeError = true; break; } ProjectOptions.CurrentBuildCommonSourceDirectory = compiler.CommonSourceDirectory; ProjectOptions.CommonSourceDirectory = ProjectOptions.CommonSourceDirectory == null ? compiler.CommonSourceDirectory : PathUtils.CommonDir(ProjectOptions.CommonSourceDirectory, compiler.CommonSourceDirectory); compiler.GatherSourceInfo(); if (ProjectOptions.SpriteGeneration) { ProjectOptions.SpriteGenerator.ProcessNew(); } if (!compiler.EmitProgram()) { wasSomeError = true; break; } buildModuleCtx.UpdateCacheIds(); Logger.Info( $"Compiled Src: {buildModuleCtx.ToCompile.Count} Dts: {buildModuleCtx.ToCompileDts.Count} => Js: {buildModuleCtx.OutputedJsFiles} Dts: {buildModuleCtx.OutputedDtsFiles} in {(DateTime.UtcNow - start).TotalSeconds:F1}s"); buildModuleCtx.ToCompile.Clear(); buildModuleCtx.Crawl(); } } while (buildModuleCtx.ChangedDts || 0 < buildModuleCtx.ToCompile.Count); if (ProjectOptions.BuildCache.IsEnabled && !wasSomeError) { ProjectOptions.StoreResultToBuildCache(buildModuleCtx._result); } buildCtx.BuildResult = buildModuleCtx._result; } finally { if (compiler != null) { buildCtx.CompilerPool.ReleaseTs(compiler); } ProjectOptions.BuildCache.EndTransaction(); } }
public BuildResult(MainBuildResult mainBuildResult, ProjectOptions options) { _mainBuildResult = mainBuildResult; BundleJsUrl = _mainBuildResult.AllocateName(options.GetDefaultBundleJsName(), options.Variant != "serviceworker"); }
public BuildResult(ProjectOptions options) { CompressFileNames = options.CompressFileNames; OutputSubDir = options.OutputSubDir; BundleJsUrl = AllocateName("bundle.js"); }
public void LoadProjectJson(bool forbiddenDependencyUpdate, ProjectOptions?parentProjectOptions) { if (Virtual) { PackageJsonChangeId = -1; Dependencies = new(); DevDependencies = new(); Assets = null; return; } DiskCache.UpdateIfNeeded(Owner); var packageJsonFile = Owner.TryGetChild("package.json"); if (packageJsonFile is IFileCache cache) { var newChangeId = cache.ChangeId; if (newChangeId == PackageJsonChangeId) { return; } var rp = PathUtils.RealPath(packageJsonFile.FullPath); if (rp != packageJsonFile.FullPath) { if (DiskCache.TryGetItem(rp) is IFileCache realPackageJsonFile) { Owner = realPackageJsonFile.Parent !; Owner.Project = this; cache = realPackageJsonFile; newChangeId = cache.ChangeId; } } ProjectOptions.FinalCompilerOptions = null; JObject parsed; try { parsed = JObject.Parse(cache.Utf8Content); } catch (Exception) { parsed = new(); } var deps = new HashSet <string>(); var devdeps = new HashSet <string>(); var hasMain = false; if (parsed.GetValue("typescript") is JObject parsedT) { if (parsedT.GetValue("main") is JValue mainV) { MainFile = PathUtils.Normalize(mainV.ToString()); if (DiskCache.TryGetItem(PathUtils.Join(Owner.FullPath, MainFile)) is IFileCache) { TypesMainFile = null; hasMain = true; } } } if (!hasMain && parsed.GetValue("browser") is JValue browserMain) { MainFile = PathUtils.Normalize(browserMain.ToString()); if (DiskCache.TryGetItem(PathUtils.Join(Owner.FullPath, MainFile)) is IFileCache) { hasMain = true; } } var name = parsed.GetValue("name") is JValue vname?vname.ToString() : ""; if (!hasMain && parsed.GetValue("module") is JValue moduleV) { if (name != "moment") { MainFile = PathUtils.Normalize(moduleV.ToString()); if (DiskCache.TryGetItem(PathUtils.Join(Owner.FullPath, MainFile)) is IFileCache) { hasMain = true; } } } if (parsed.GetValue("typings") is JValue typingsV) { TypesMainFile = PathUtils.Normalize(typingsV.ToString()); } if (!hasMain) { if (parsed.GetValue("main") is JValue mainV2) { MainFile = PathUtils.Normalize(mainV2.ToString()); if (PathUtils.GetExtension(MainFile).IsEmpty) { MainFile += ".js"; } } else { MainFile = "index.js"; } if (name == "@stomp/stompjs") { MainFile = "esm6/index.js"; hasMain = true; } if (DiskCache.TryGetItem(PathUtils.Join(Owner.FullPath, PathUtils.ChangeExtension(MainFile, "ts"))) is IFileCache fileAsTs) { MainFile = PathUtils.ChangeExtension(MainFile, "ts"); TypesMainFile = null; hasMain = true; } else { fileAsTs = DiskCache.TryGetItem(PathUtils.Join(Owner.FullPath, PathUtils.ChangeExtension(MainFile, "tsx"))) as IFileCache; if (fileAsTs != null) { MainFile = PathUtils.ChangeExtension(MainFile, "tsx"); TypesMainFile = null; hasMain = true; } } if (!hasMain) { if (parsed.GetValue("types") is JValue mainV) { TypesMainFile = PathUtils.Normalize(mainV.ToString()); hasMain = true; } } } if (TypesMainFile == null) { TypesMainFile = PathUtils.ChangeExtension(MainFile, "d.ts"); if (!IsRootProject && !(DiskCache.TryGetItem(PathUtils.Join(Owner.FullPath, TypesMainFile)) is IFileCache)) { var typesDts = PathUtils.Join(Owner.FullPath, $"../@types/{Owner.Name}/index.d.ts"); if (DiskCache.TryGetItem(typesDts) is IFileCache) { TypesMainFile = typesDts; } } } if (parsed.GetValue("dependencies") is JObject parsedV) { foreach (var i in parsedV.Properties()) { deps.Add(i.Name); } } if (parsed.GetValue("devDependencies") is JObject parsedV2) { foreach (var i in parsedV2.Properties()) { devdeps.Add(i.Name); } } PackageJsonChangeId = newChangeId; Dependencies = deps; DevDependencies = devdeps; Assets = ParseBobrilAssets(parsed); if (ProjectOptions == null) { return; } ProjectOptions.FillProjectOptionsFromPackageJson(parsed, Owner); if (forbiddenDependencyUpdate || ProjectOptions.DependencyUpdate == DepedencyUpdate.Disabled) { return; } var packageManager = new CurrentNodePackageManager(DiskCache, Logger); if (ProjectOptions.DependencyUpdate == DepedencyUpdate.Upgrade) { packageManager.UpgradeAll(Owner); } else { packageManager.Install(Owner); } DiskCache.CheckForTrueChange(); DiskCache.ResetChange(); } else { PackageJsonChangeId = -1; MainFile = "index.js"; Dependencies = new(); DevDependencies = new(); Assets = null; ProjectOptions?.FillProjectOptionsFromPackageJson(null, Owner); } }