Closed olmobrutall closed 1 year ago
Thanks very much for reporting this.
From what I can see the fast up-to-date check is working correctly and the problem exists elsewhere, perhaps in the Microsoft.TypeScript.MSBuild
package. To wit:
Comparing timestamps of inputs and outputs:
<snip>
Adding UpToDateCheckBuilt outputs:
C:\Users\drnoakes\source\repos\WebApplication54\WebApplication54\bin\Debug\net7.0\WebApplication54.dll
C:\Users\drnoakes\source\repos\WebApplication54\WebApplication54\obj\Debug\net7.0\WebApplication54.dll
C:\Users\drnoakes\source\repos\WebApplication54\WebApplication54\obj\Debug\net7.0\WebApplication54.pdb
C:\Users\drnoakes\source\repos\WebApplication54\WebApplication54\bin\Debug\net7.0\WebApplication54.pdb
<snip>
Adding TypeScriptCompile inputs:
C:\Users\drnoakes\source\repos\WebApplication54\WebApplication54\CompileMe.ts
<snip>
The .ts
files must not be present in this default set of inputs/outputs. Compiling a changed .ts
file does not result in an update to any of the outputs listed there (.dll
or .pdb
files).
As you correctly identified, these items should be included in a differentiated Set
. That should be happening by default in whatever code is adding these items to the project and configuring them as up-to-date check inputs. Some part of the build is explicitly opting TypeScriptCompile
items in for the check. It must also control the set. Further, the set must have at least one output item so that there is something to check input timestamps against.
I won't have time to dig into this until later in the week at the earliest. Hopefully the above is helpful if you want to investigate further.
Let's get that fixed/understood first. We can investigate the overbuild warnings around tsconfig.json
and package.json
after, if they're still an issue.
Thanks @drewnoakes for the early response.
The .ts files must not be present in this default set of inputs/outputs. Compiling a changed .ts file does not result in an update to any of the outputs listed there (.dll or .pdb files).
As you correctly identified, these items should be included in a differentiated Set. That should be happening by default in whatever code is adding these items to the project and configuring them as up-to-date check inputs. Some part of the build is explicitly opting TypeScriptCompile items in for the check. It must also control the set. Further, the set must have at least one output item so that there is something to check input timestamps against.
I'm glad that we both seem to agree on what is going on. Let's see if we can get someone in the Typescript team involved. @RyanCavanaugh?
I won't have time to dig into this until later in the week at the earliest. Hopefully the above is helpful if you want to investigate further.
It is true that by using UpToDateCheckInput
/ UpToDateCheckOutput
I can only add items to compare, but I can not remove the ones that are implicitly added (probably by Microsoft.TypeScript.MSBuild
)?
Without this feature, I can not completly split the default
set from the Scripts
set. I can add ts_out/tsconfig.tsbuildinfo
to the default set, but since the check is MAX(input) < MIN(output), it doesn'T solve the problem because the old .dll
wins over the new .tsbildinfo
Let's get that fixed/understood first. We can investigate the overbuild warnings around tsconfig.json and package.json after, if they're still an issue.
I've found a solution for this. Adding in Directory.Build.targets
<ItemGroup>
<Content Update="package.json">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Content>
<Content Update="tsconfig.json">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Content>
</ItemGroup>
Prevents the chain-reaction and only recompiles ad infinitum Signum.csproj
.
Why are this json files "Copy If Newer" by default? It makese sense for appsettings.json
but not for package.json
or tsconfig.json
.
Shouldn't this common files be considered by VS item templates?
The TypeScript team needs to take a look at this and expose their project items correctly for the fast up-to-date check.
Thanks for filing https://github.com/microsoft/TypeScript/issues/53795. I'll comment there. At this point there's no work item for this repo.
Visual Studio Version
Visual Studio 2022 64-bits 17.5.3 Microsoft.TypeScript.MSBuild 5.0.4
Summary
⚠️ ⚠️ Very important performance problem for any TypeScript developer in Visual Studio, specially when using more than one probject ⚠️ ⚠️
TypeScript files afect the build, but do not produce any output in
bin
/obj
, because of this, after succesfully compiling a Web Application (<Project Sdk="Microsoft.NET.Sdk.Web">
) that uses the NugetMicrosoft.TypeScript.MSBuild
to compile somets
file, if you modify ats
file, the project will be forever ignored by theup-to-date check
until a .cs file is changes and a build updates the outputdll
.Steps to Reproduce
In Visual Studio, create a new project of type: ASP.Net Core Web App called "WebApplication1"
Add a TypeScript file
file.ts
in the root directory of "WebApplication1" with contentvar a = 2;
.Visual Studio will sugest to install the nuget
Microsoft.TypeScript.MSBuild
, if not install it manuallyActivate Up-to-Date logging level as explained here.
Compile the project, of course the project gets compiled the first time. ✅
Compile Again, no changes detected, MSBuild is skipped ✅
Modify
file.ts
by writingvar a = 3;
. Compile again. Of course if recompiles... but produces a warning 🤔Without modifying the solution, compile again... it incorrectly calls MSBuild, compiling the project again. 🔥 🐛 👎
Repeating 8 will never fix the problem. Only by making a change in a
Program.cs
file the output files will be newer than thets
files. re-enablingFastUpToDate
. No warning this time ✅Compile again without changes.
FastUpToDate
correctly detects the project as up-to-date.Expected Behavior
A C# project that contains changes only in TS files gets compiled one time, then correctly detected as up-to-date
Actual Behavior
The project won't be detected until a change in a C# file is made, forcing MSBuild to rebuild the assets.
User Impact
I think most developer using VisualStudio to build web applications tend to use TypeScript and I think all are impacted by this issue. The problem is often overseen because Web Applications tend to be at the end of the dependency graph.
My example using https://github.com/signumsoftware/southwind (depends on https://github.com/signumsoftware/framework)
In my case we were used to consider TypeScript compilation slower than C# (about 3x times slower), but since they were only three projects (
Southwind.React
,Signum.React.Extensions
andSignum.React
) we could live with it.Lately we are restructuring the project to have one csproj per vertical module instead of layer, so Extensions instead of being one project is.... 43 web projects that need TypeScript compilation. https://github.com/signumsoftware/framework/tree/revolution/Extensions
A clean rebuild of
Southwind
project takes about 6 mins in my machine... time to make a coffe I suppose.After that, building
Southwind
is very fast.But if you make a change TS/TSX file in some referenced project, like
Signum
, and then recompileSouthwind
it produces a chain reaction:If needs to recompile almost everithing:
The reason is this chain reaction:
I have tried playing with
UpToDateCheckInput
/UpToDateCheckOutput
with no resultsAFAIK, this options only allow to add new items, but not to remove / change set of items implicitly added, in this case by
TypeScriptCompile
.