Repository navigation
Replace Parcel with Vite for frontend builds #4205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
22f817d
d7fe897
100eb5b
24254f5
a965d07
520f233
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ | |
| <InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);Microsoft.AspNetCore.Http.Generated</InterceptorsPreviewNamespaces> | ||
| <IsPublishable>true</IsPublishable> | ||
| <EnableDefaultRazorSlices>false</EnableDefaultRazorSlices> | ||
| <SkipNpmBuild Condition="'$(SkipNpmBuild)' == ''">false</SkipNpmBuild> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
|
|
@@ -35,7 +36,17 @@ | |
| The first time the task is executed. Then, it only runs when you change the package.json file. | ||
| Documentation: https://learn.microsoft.com/en-us/visualstudio/msbuild/incremental-builds?WT.mc_id=DT-MVP-5003978 | ||
| --> | ||
| <Target Name="NpmInstall" Inputs="package.json" Outputs="node_modules/.install-stamp"> | ||
| <Target Name="EnsureSkipNpmBuildArtifacts" | ||
| BeforeTargets="NpmInstall;NpmRunBuild" | ||
| Condition="'$(SkipNpmBuild)' == 'true'"> | ||
| <Error Condition="!Exists('_static/main.js') Or !Exists('_static/styles.css') Or !Exists('_static/assembler.css') Or !Exists('_static/isolated.css') Or !Exists('_static/codex.css')" | ||
| Text="SkipNpmBuild is set but one or more _static artifacts are missing. Run a full frontend build first." /> | ||
| </Target> | ||
|
|
||
| <Target Name="NpmInstall" | ||
| Condition="'$(DesignTimeBuild)' != 'true' And '$(SkipNpmBuild)' != 'true'" | ||
| Inputs="package.json;package-lock.json" | ||
| Outputs="node_modules/.install-stamp"> | ||
| <Exec Command="npm ci" WorkingDirectory="$(MSBuildThisFileDirectory)" ConsoleToMsBuild="true" /> | ||
|
|
||
| <!-- Write the stamp file, so incremental builds work --> | ||
|
|
@@ -57,8 +68,7 @@ | |
| <NpmBuildInputFiles Include="package-lock.json" /> | ||
| <NpmBuildInputFiles Include="tsconfig.json" /> | ||
| <NpmBuildInputFiles Include="tailwind.config.js" /> | ||
| <NpmBuildInputFiles Include=".parcelrc" /> | ||
| <NpmBuildInputFiles Include=".postcssrc" /> | ||
| <NpmBuildInputFiles Include="vite.config.ts" /> | ||
| </ItemGroup> | ||
| <!-- Tailwind scans these directories for utility class usage (see tailwind.config.js content paths). | ||
| Resolved inside a target so external cshtml files don't appear in the IDE's project tree. --> | ||
|
|
@@ -73,44 +83,47 @@ | |
| <Target Name="NpmRunBuild" | ||
| DependsOnTargets="NpmInstall;MinVer;CollectExternalCshtmlInputs" | ||
| BeforeTargets="BeforeBuild" | ||
| Condition="'$(DesignTimeBuild)' != 'true' And '$(SkipNpmBuild)' != 'true'" | ||
| Inputs="@(NpmBuildInputFiles)" | ||
| Outputs="_static/.build-stamp;_static/main.js;_static/styles.css"> | ||
| <Message Text="Building frontend with version: $(MinVerVersion)" Importance="high" /> | ||
| <Exec Command="npm run build" | ||
| WorkingDirectory="$(MSBuildThisFileDirectory)" | ||
| ConsoleToMsBuild="true" | ||
| EnvironmentVariables="DOCS_BUILDER_VERSION=$(MinVerVersion)"> | ||
| <Output TaskParameter="ConsoleOutput" PropertyName="OutputOfExec" /> | ||
| </Exec> | ||
| EnvironmentVariables="DOCS_BUILDER_VERSION=$(MinVerVersion)" | ||
| IgnoreStandardErrorWarningFormat="true" /> | ||
| <!-- Write the stamp file, so incremental builds work --> | ||
| <Touch Files="_static/.build-stamp" AlwaysCreate="true" /> | ||
| </Target> | ||
|
|
||
| <!-- Clean old hashed assets before each frontend build to avoid accumulating stale files. | ||
| Without this, multiple Parcel runs (e.g. across dotnet build vs dotnet run) can leave | ||
| old hashed filenames in _static; all get embedded and then copied to assembler output, | ||
| causing duplicated JS/CSS with different hashes in the final _static folder. --> | ||
| <Target Name="CleanOldHashedAssets" BeforeTargets="NpmRunBuild" Condition="'$(IsPublishing)' == 'true'"> | ||
| <Target Name="CleanGeneratedStaticAssets" | ||
| BeforeTargets="NpmRunBuild" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [HIGH] Cleanup runs even when frontend build is skipped, leaving broken chunk references
I reproduced this on the current branch by invoking Please make cleanup conditional on the build actually running (for example, move cleanup into |
||
| Condition="'$(DesignTimeBuild)' != 'true' And '$(SkipNpmBuild)' != 'true'"> | ||
| <RemoveDir Directories="_static/assets" Condition="Exists('_static/assets')" /> | ||
| <ItemGroup> | ||
| <OldHashedFiles Include="_static/*.????????*.js" /> | ||
| <OldHashedFiles Include="_static/*.????????*.css" /> | ||
| <OldHashedFiles Include="_static/*.????????*.js.map" /> | ||
| <OldHashedFiles Include="_static/*.????????*.css.map" /> | ||
| <!-- Only remove content-hashed chunk/asset files from prior Vite runs so they | ||
| don't accumulate across builds. Do NOT list the stable named outputs here | ||
| (main.js, styles.css, etc.) — deleting them before NpmRunBuild's incremental | ||
| output check would force a full npm run build on every dotnet build invocation | ||
| even when no source files changed. --> | ||
| <ViteGeneratedFiles Include="_static/asset-*" /> | ||
| <ViteGeneratedFiles Include="_static/chunk-*" /> | ||
| <OldHashedBundles Include="_static/*.????????*.js" /> | ||
| <OldHashedBundles Include="_static/*.????????*.css" /> | ||
| </ItemGroup> | ||
| <Delete Files="@(OldHashedFiles)" ContinueOnError="true" /> | ||
| <Delete Files="@(ViteGeneratedFiles);@(OldHashedBundles)" ContinueOnError="true" /> | ||
| </Target> | ||
|
|
||
| <Target Name="EmbedGeneratedAssets" AfterTargets="NpmRunBuild"> | ||
| <Target Name="EmbedGeneratedAssets" DependsOnTargets="NpmRunBuild" BeforeTargets="BeforeBuild"> | ||
| <ItemGroup> | ||
| <EmbeddedResource Include="_static/*.js" Watch="false" /> | ||
| <EmbeddedResource Include="_static/*.js.map" Watch="false" Condition="'$(Configuration)' == 'Debug'" /> | ||
| <EmbeddedResource Include="_static/*.css" Watch="false" /> | ||
| <EmbeddedResource Include="_static/*.css.map" Watch="false" Condition="'$(Configuration)' == 'Debug'" /> | ||
| <EmbeddedResource Include="_static/*.svg" Watch="false" /> | ||
| <EmbeddedResource Include="_static/*.png" Watch="false" /> | ||
| <EmbeddedResource Include="_static/*.ttf" Watch="false" /> | ||
| <EmbeddedResource Include="_static/*.woff" Watch="false" /> | ||
| <EmbeddedResource Include="_static/*.woff2" Watch="false" /> | ||
| <EmbeddedResource Include="_static/**/*.js" Watch="false" /> | ||
| <EmbeddedResource Include="_static/**/*.js.map" Watch="false" Condition="'$(Configuration)' == 'Debug'" /> | ||
| <EmbeddedResource Include="_static/**/*.css" Watch="false" /> | ||
| <EmbeddedResource Include="_static/**/*.css.map" Watch="false" Condition="'$(Configuration)' == 'Debug'" /> | ||
| <EmbeddedResource Include="_static/**/*.svg" Watch="false" /> | ||
| <EmbeddedResource Include="_static/**/*.png" Watch="false" /> | ||
| <EmbeddedResource Include="_static/**/*.ttf" Watch="false" /> | ||
| <EmbeddedResource Include="_static/**/*.woff" Watch="false" /> | ||
| <EmbeddedResource Include="_static/**/*.woff2" Watch="false" /> | ||
| </ItemGroup> | ||
| </Target> | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[MEDIUM]
SkipNpmBuildcheck still allows incomplete Vite outputEnsureSkipNpmBuildArtifactsverifies only five top-level files, but Vite runtime also needs generatedchunk-*/asset-*files referenced bymain.js. InSkipNpmBuild=truebuilds, a partially-populated_static/directory can pass this check and produce runtime 404s when the browser requests missing chunks/assets.Please also validate bundle completeness for the skip path (for example by checking for required generated chunk/asset outputs or validating a manifest from the last full build).