Appearance
.NET Widget Build
Automatic frontend widget build mechanism in .NET widget projects.
Overview
In .NET widget projects, frontend widget build is automatic. When you Build or Publish from Visual Studio, the widget build process runs automatically.
No need to use manual commands. It is integrated into Visual Studio's build pipeline.
Automatic Build Mechanism
Visual Studio Build
Visual Studio Build/Publish
↓
Pre-Build Event (automatic)
↓
Widget Build (TypeScript → JavaScript)
↓
wwwroot/dist/widget.min.js
↓
.NET Build/Publish continuesDevelopment: F5 or Ctrl+Shift+B → Widget is built automatically Publish: Right-click → Publish → Widget is built automatically
.csproj Integration
Widget build is integrated into the project file:
xml
<Project Sdk="Microsoft.NET.Sdk.Web">
<!-- Pre-build widget compilation -->
<Target Name="CompileWidget" BeforeTargets="Build">
<Exec Command="npm run build" />
</Target>
</Project>Build Output
wwwroot/dist
Widget build is automatically written to the wwwroot/dist folder:
dashboard-api/
├── wwwroot/
│ └── dist/
│ └── widget.min.js ← Created automaticallyDevelopment: widget.js (readable) Release/Publish: widget.min.js (minified)
Program.cs Requirement
Static Files Middleware is required to serve the widget:
csharp
var app = builder.Build();
app.UseStaticFiles(); // Required for widget
app.Run();Configuration
.xcon/config.json
The build process uses this configuration:
json
{
"configurations": {
"provider": "web",
"id": "dashboard-widget"
},
"build": {
"entry": "widget.ts",
"sourceRoot": "src",
"outputFilename": "widget.min.js",
"outputPath": "wwwroot/dist",
"tsConfig": "tsconfig.json",
"externals": {
"axios": "axios"
}
},
"projectType": "dotnet",
"version": "1.0"
}Critical: outputPath must be wwwroot/dist.
package.json Scripts
json
{
"scripts": {
"dev": "webpack --mode development --watch",
"build": "webpack --mode production"
}
}npm run build runs automatically during Visual Studio build.
Build Process
What Happens in the Background?
- Visual Studio Build is triggered (F5, Ctrl+Shift+B, Publish)
- Pre-Build Event runs (.csproj target)
- npm run build command runs
- Webpack build (TypeScript → JavaScript)
- XCon Loader (template/style injection)
- Platform Wrapper is added
- Output:
wwwroot/dist/widget.min.js - .NET Build continues
Build Modes
Debug Mode (F5):
widget.js→ Readable code- Source maps active
- Console.log preserved
Release Mode (Publish):
widget.min.js→ Minified- No source maps
- Console.log removed
Development Workflow
Normal Usage
bash
# 1. Open in Visual Studio
dashboard-api.sln
# 2. F5 - Run
# Widget is built automatically
# Backend starts
# 3. Test in browser
https://localhost:5001
# 4. Change code
# Edit src/widget.ts
# 5. Rebuild (Ctrl+Shift+B)
# Widget is automatically rebuiltWatch Mode (Optional)
For continuous development:
bash
cd dashboard-api
npm run devAutomatically watches and rebuilds widget changes.
Troubleshooting
Build Failed
Problem: Visual Studio build failed
Check:
- Does
.xcon/config.jsonexist? - Does
src/widget.tsexist? - Was
npm installdone? - Output path:
wwwroot/dist
Widget Not Loading
Problem: 404 in browser - widget.min.js
Solution 1 - Static Files:
csharp
// Program.cs
app.UseStaticFiles(); // Must be addedSolution 2 - Build Output:
bash
# Check
ls wwwroot/dist/widget.min.js
# If not exists, manual build
cd dashboard-api
npm run buildnpm Dependencies
Problem: npm command not found
Solution:
bash
# Check if npm is installed
npm --version
# If not, install Node.js
# nodejs.orgProblem: Dependencies missing
Solution:
bash
cd dashboard-api
npm install.csproj Target Not Working
Problem: Widget build doesn't run automatically
Solution - Check .csproj:
xml
<Target Name="CompileWidget" BeforeTargets="Build">
<Exec Command="npm run build" />
</Target>Build Output Check
Visual Studio Output Window
Build started...
1>------ Build started: Project: dashboard-api ------
1> npm run build
1>
1> > dashboard-api@1.0.0 build
1> > webpack --mode production
1>
1> asset widget.min.js 14.6 KiB [compared for emit] [minimized]
1> webpack 5.101.3 compiled successfully in 3542 ms
1>dashboard-api -> bin\Debug\net8.0\dashboard-api.dll
========== Build: 1 succeeded ==========Successful Build Indicators
✅ webpack compiled successfully ✅ widget.min.js created ✅ dashboard-api.dll built
Publish Workflow
Visual Studio Publish
1. Solution Explorer → Right-click project
2. Select "Publish"
3. Select publish profile (IIS, Azure, Docker...)
4. Click "Publish"
Automatic:
→ Widget build (production mode)
→ .NET publish
→ DeployPublish Output
dashboard-api/
├── bin/
│ └── Release/
│ └── net8.0/
│ └── publish/
│ ├── dashboard-api.dll
│ ├── wwwroot/
│ │ └── dist/
│ │ └── widget.min.js ← Included
│ └── web.configWidget is automatically included in publish output.
Best Practices
1. Output Path
json
{
"build": {
"outputPath": "wwwroot/dist" // Must be under wwwroot
}
}2. .gitignore
# Build outputs
wwwroot/dist/
bin/
obj/
node_modules/3. Development
- Visual Studio build automatically builds widget
- Use
npm run devwatch mode if needed - Manual build command unnecessary
4. Production
- Visual Studio Publish automatically builds widget
- Release mode → minified output
- Deploy ready
Troubleshooting
Build Runs Every Time
Normal behavior. Pre-build event runs on every build.
If you don't want it:
xml
<!-- .csproj -->
<Target Name="CompileWidget" BeforeTargets="Build" Condition="'$(BuildingInsideVisualStudio)' != 'true'">
<Exec Command="npm run build" />
</Target>Build Too Slow
Solution - Incremental build:
json
// tsconfig.json
{
"compilerOptions": {
"incremental": true
}
}Static Files Not Working
Problem: Widget 404
Check:
csharp
// Program.cs
var app = builder.Build();
app.UseStaticFiles(); // RequiredSummary
.NET Widget Build:
✅ Automatic - Integrated with Visual Studio build/publish ✅ No manual command needed - .csproj target runs automatically ✅ Output: wwwroot/dist/widget.min.js ✅ Development: F5 → Automatic build ✅ Publish: Right-click Publish → Automatic build
Critical Point: app.UseStaticFiles() must be in Program.cs.