Skip to content

Commit fe7e875

Browse files
authored
[Infrastructure] Make npm restore and build incremental (#62466)
* Adds incrementality to NPM restore * Adds incrementality to NPM build
1 parent b4bcd6a commit fe7e875

File tree

2 files changed

+139
-7
lines changed

2 files changed

+139
-7
lines changed

eng/Npm.Workspace.nodeproj

Lines changed: 124 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,131 @@
1919
<_NpmAdditionalEnvironmentVariables>PUPPETEER_SKIP_DOWNLOAD=1</_NpmAdditionalEnvironmentVariables>
2020
</PropertyGroup>
2121

22-
<Target Name="Restore">
22+
<PropertyGroup>
23+
<NpmWorkspaceRoot>$(MSBuildThisFileDirectory)..</NpmWorkspaceRoot>
24+
<NodeModulesMarkerFile>$(NpmWorkspaceRoot)\node_modules\.package-lock.json</NodeModulesMarkerFile>
25+
<!-- Common exclude patterns for NPM build input/output files -->
26+
<NpmCommonExcludePatterns>
27+
**\pkg-version.ts;
28+
$(NpmWorkspaceRoot)\src\**\node_modules\**\*;
29+
$(NpmWorkspaceRoot)\src\**\bin\**\*;
30+
$(NpmWorkspaceRoot)\src\**\obj\**\*
31+
</NpmCommonExcludePatterns>
32+
</PropertyGroup>
33+
34+
<!-- Input files for incremental restore check -->
35+
<ItemGroup>
36+
<NpmInputFiles Include="$(NpmWorkspaceRoot)\package.json" />
37+
<NpmInputFiles Include="$(NpmWorkspaceRoot)\package-lock.json" Condition="Exists('$(NpmWorkspaceRoot)\package-lock.json')" />
38+
<NpmInputFiles Include="$(NpmWorkspaceRoot)\src\**\package.json" Exclude="$(NpmWorkspaceRoot)\src\**\node_modules\**\package.json" />
39+
<NpmInputFiles Include="$(NpmWorkspaceRoot)\.npmrc" Condition="Exists('$(NpmWorkspaceRoot)\.npmrc')" />
40+
</ItemGroup>
41+
42+
<!-- Output files for incremental restore check -->
43+
<ItemGroup>
44+
<NpmOutputFiles Include="$(NodeModulesMarkerFile)" />
45+
</ItemGroup>
46+
47+
<!-- Output files for incremental build check -->
48+
<ItemGroup>
49+
<!-- SignalR client outputs -->
50+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr\dist\browser\signalr.js" />
51+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr\dist\browser\signalr.js.map" />
52+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr\dist\browser\signalr.min.js" />
53+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr\dist\browser\signalr.min.js.map" />
54+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr\dist\cjs\**\*.js" />
55+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr\dist\cjs\**\*.js.map" />
56+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr\dist\esm\**\*.d.ts" />
57+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr\dist\esm\**\*.js" />
58+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr\dist\esm\**\*.js.map" />
59+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr\dist\webworker\signalr.js" />
60+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr\dist\webworker\signalr.js.map" />
61+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr\dist\webworker\signalr.min.js" />
62+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr\dist\webworker\signalr.min.js.map" />
63+
64+
<!-- SignalR MessagePack protocol outputs -->
65+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.js" />
66+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.js.map" />
67+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.min.js" />
68+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.min.js.map" />
69+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr-protocol-msgpack\dist\cjs\**\*.js" />
70+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr-protocol-msgpack\dist\cjs\**\*.js.map" />
71+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr-protocol-msgpack\dist\esm\**\*.d.ts" />
72+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr-protocol-msgpack\dist\esm\**\*.js" />
73+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\signalr-protocol-msgpack\dist\esm\**\*.js.map" />
74+
75+
<!-- JSInterop outputs -->
76+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\JSInterop\Microsoft.JSInterop.JS\src\dist\src\Microsoft.JSInterop.d.ts" />
77+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\JSInterop\Microsoft.JSInterop.JS\src\dist\src\Microsoft.JSInterop.d.ts.map" />
78+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\JSInterop\Microsoft.JSInterop.JS\src\dist\src\Microsoft.JSInterop.js" />
79+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\JSInterop\Microsoft.JSInterop.JS\src\dist\src\Microsoft.JSInterop.js.map" />
80+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\JSInterop\Microsoft.JSInterop.JS\src\dist\tsconfig.tsbuildinfo" />
81+
82+
<!-- Components Web.JS outputs -->
83+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\Web.JS\dist\Debug\blazor.server.js" />
84+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\Web.JS\dist\Debug\blazor.server.js.map" />
85+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\Web.JS\dist\Debug\blazor.web.js" />
86+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\Web.JS\dist\Debug\blazor.web.js.map" />
87+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\Web.JS\dist\Debug\blazor.webassembly.js" />
88+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\Web.JS\dist\Debug\blazor.webassembly.js.map" />
89+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\Web.JS\dist\Debug\blazor.webview.js" />
90+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\Web.JS\dist\Release\blazor.server.js" />
91+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\Web.JS\dist\Release\blazor.server.js.map" />
92+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\Web.JS\dist\Release\blazor.web.js" />
93+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\Web.JS\dist\Release\blazor.web.js.map" />
94+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\Web.JS\dist\Release\blazor.webassembly.js" />
95+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\Web.JS\dist\Release\blazor.webassembly.js.map" />
96+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\Web.JS\dist\Release\blazor.webview.js" />
97+
98+
<!-- WebAssembly Authentication outputs -->
99+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\WebAssembly\WebAssembly.Authentication\src\Interop\dist\Debug\AuthenticationService.js" />
100+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\WebAssembly\WebAssembly.Authentication\src\Interop\dist\Debug\AuthenticationService.js.map" />
101+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\WebAssembly\WebAssembly.Authentication\src\Interop\dist\Release\AuthenticationService.js" />
102+
103+
<!-- WebAssembly Authentication MSAL outputs -->
104+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\WebAssembly\Authentication.Msal\src\Interop\dist\Debug\AuthenticationService.js" />
105+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\WebAssembly\Authentication.Msal\src\Interop\dist\Debug\AuthenticationService.js.map" />
106+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\WebAssembly\Authentication.Msal\src\Interop\dist\Release\AuthenticationService.js" />
107+
108+
<!-- Custom Elements outputs -->
109+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\CustomElements\src\js\dist\Debug\Microsoft.AspNetCore.Components.CustomElements.lib.module.js" />
110+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\CustomElements\src\js\dist\Debug\Microsoft.AspNetCore.Components.CustomElements.lib.module.js.map" />
111+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\Components\CustomElements\src\js\dist\Release\Microsoft.AspNetCore.Components.CustomElements.lib.module.js" />
112+
113+
<!-- FunctionalTests outputs -->
114+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\FunctionalTests\wwwroot\dist\signalr-functional-tests.js" />
115+
<NpmBuildOutputFiles Include="$(NpmWorkspaceRoot)\src\SignalR\clients\ts\FunctionalTests\wwwroot\dist\signalr-functional-tests.js.map" />
116+
</ItemGroup>
117+
118+
<!-- Input files for incremental build check -->
119+
<ItemGroup>
120+
<!-- Source files -->
121+
<NpmBuildInputFiles Include="$(NpmWorkspaceRoot)\src\**\*.ts" Exclude="@(NpmBuildOutputFiles);$(NpmCommonExcludePatterns)" />
122+
<NpmBuildInputFiles Include="$(NpmWorkspaceRoot)\src\**\*.js" Exclude="@(NpmBuildOutputFiles);$(NpmCommonExcludePatterns);**\samples\**\wwwroot\lib\**\*;**\FunctionalTests\wwwroot\lib\**\*;$(NpmWorkspaceRoot)\src\**\dist\**\*" />
123+
<NpmBuildInputFiles Include="$(NpmWorkspaceRoot)\src\**\*.mjs" Exclude="@(NpmBuildOutputFiles);$(NpmCommonExcludePatterns);$(NpmWorkspaceRoot)\src\**\dist\**\*" />
124+
125+
<!-- Configuration files -->
126+
<NpmBuildInputFiles Include="$(NpmWorkspaceRoot)\src\**\package.json" Exclude="@(NpmBuildOutputFiles);$(NpmCommonExcludePatterns);$(NpmWorkspaceRoot)\src\**\node_modules\**\package.json" />
127+
<NpmBuildInputFiles Include="$(NpmWorkspaceRoot)\src\**\tsconfig*.json" Exclude="@(NpmBuildOutputFiles);$(NpmCommonExcludePatterns)" />
128+
<NpmBuildInputFiles Include="$(NpmWorkspaceRoot)\src\**\rollup.config.*" Exclude="@(NpmBuildOutputFiles);$(NpmCommonExcludePatterns)" />
129+
<NpmBuildInputFiles Include="$(NpmWorkspaceRoot)\src\**\webpack.config.*" Exclude="@(NpmBuildOutputFiles);$(NpmCommonExcludePatterns)" />
130+
<NpmBuildInputFiles Include="$(NpmWorkspaceRoot)\src\**\jest.config.*" Exclude="@(NpmBuildOutputFiles);$(NpmCommonExcludePatterns)" />
131+
132+
<!-- Root workspace configuration files that affect build -->
133+
<NpmBuildInputFiles Include="$(NpmWorkspaceRoot)\package.json" />
134+
<NpmBuildInputFiles Include="$(NpmWorkspaceRoot)\tsconfig*.json" />
135+
</ItemGroup>
136+
137+
138+
<Target Name="Restore" Inputs="@(NpmInputFiles)" Outputs="@(NpmOutputFiles)">
23139
<Message Text="Restoring NPM packages..." Importance="high" />
24140
<Exec
25141
Command="npm ci"
26-
WorkingDirectory="$(MSBuildThisFileDirectory).."
142+
WorkingDirectory="$(NpmWorkspaceRoot)"
27143
EnvironmentVariables="$(_NpmAdditionalEnvironmentVariables)" />
28144
</Target>
29145

30-
<Target Name="Build">
146+
<Target Name="Build" DependsOnTargets="Restore" Inputs="@(NpmBuildInputFiles)" Outputs="@(NpmBuildOutputFiles)">
31147
<PropertyGroup>
32148
<PackageVersion>$(VersionPrefix)</PackageVersion>
33149
<PackageVersion Condition="'$(VersionSuffix)' != ''">$(VersionPrefix)-$(VersionSuffix)</PackageVersion>
@@ -51,7 +167,7 @@
51167
<Exec Command="npm run test" ContinueOnError="true" WorkingDirectory="$(MSBuildThisFileDirectory).." />
52168
</Target>
53169

54-
<Target Name="Pack">
170+
<Target Name="Pack" DependsOnTargets="Build">
55171
<PropertyGroup>
56172
<PackageVersion>$(VersionPrefix)</PackageVersion>
57173
<PackageVersion Condition="'$(VersionSuffix)' != ''">$(VersionPrefix)-$(VersionSuffix)</PackageVersion>
@@ -60,6 +176,10 @@
60176
<MakeDir Directories="$(PackageOutputPath)" Condition="!Exists('$(PackageOutputPath)')" />
61177
<MakeDir Directories="$(IntermediateOutputPath)" Condition="!Exists('$(IntermediateOutputPath)')" />
62178

179+
<Exec
180+
Command="node $(MSBuildThisFileDirectory)scripts/npm/pack-workspace.mjs --update-versions $(RepoRoot)package.json $(PackageVersion) $(PackageOutputPath) $(IntermediateOutputPath)"
181+
EnvironmentVariables="$(_NpmAdditionalEnvironmentVariables)" />
182+
63183
<Exec
64184
Command="node $(MSBuildThisFileDirectory)scripts/npm/pack-workspace.mjs --create-packages $(RepoRoot)package.json $(PackageVersion) $(PackageOutputPath) $(IntermediateOutputPath)"
65185
EnvironmentVariables="$(_NpmAdditionalEnvironmentVariables)" />

eng/scripts/npm/update-dependency-versions.mjs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ function applyPackageVersion(packagesToPack, defaultPackageVersion) {
4545
const packageName = packageJson.name;
4646
const packageVersion = defaultPackageVersion;
4747
const packageDir = path.dirname(packagePath);
48+
49+
// Check if the version is already correct
50+
if (packageJson.version === packageVersion) {
51+
console.log(`Skipping ${packageName} - version ${packageVersion} already applied.`);
52+
continue;
53+
}
54+
4855
// Run npm version packageVersion --no-git-tag-version
4956
// This will update the package.json version to the specified version without creating a git tag
5057
// Make a backup of the package.json
@@ -90,11 +97,16 @@ function updateDependencyVersions(packagesToPack) {
9097
// Find the dependency in packagesToPack, load the package.json and update the dependency version
9198
const dependencyPackage = seenPackagesAndVersions.find(([_, packageJson]) => packageJson.name === dependency);
9299
if (dependencyPackage) {
93-
modified = true;
94100
const dependencyPackagePath = dependencyPackage[0];
95101
const dependencyPackageJson = JSON.parse(fs.readFileSync(dependencyPackagePath, 'utf-8'));
96-
dependencies[dependency] = `>=${dependencyPackageJson.version}`;
97-
console.log(`Updated dependency ${dependency} to ${dependencyPackageJson.version} in ${packageJson.name}.`);
102+
const newDependencyVersion = `>=${dependencyPackageJson.version}`;
103+
104+
// Only update if the dependency version is actually different
105+
if (dependencies[dependency] !== newDependencyVersion) {
106+
modified = true;
107+
dependencies[dependency] = newDependencyVersion;
108+
console.log(`Updated dependency ${dependency} to ${dependencyPackageJson.version} in ${packageJson.name}.`);
109+
}
98110
}
99111
}
100112
if (modified) {

0 commit comments

Comments
 (0)