The ServiceStackVS VS.NET extension contains a pre-configured Single Page App VS.NET template for each of the popular JavaScript frameworks:
The Single Page App (SPA) project templates can also be created using the dotnet-new command line tool:
$ npm install -g @servicestack/cli
$ dotnet-new <template-name> ProjectName
Click on the template name below to view a Live Demo and contents of each project template:
.NET Core C# Templates | |
---|---|
angular-spa | .NET 6.0 Angular CLI Bootstrap App |
react-spa | .NET 6.0 React Create App CLI Bootstrap App |
vue-nuxt | .NET 6.0 Nuxt.js SPA App with Bootstrap |
vue-spa | .NET 6.0 Vue CLI Bootstrap App |
The .NET 6.0 project templates utilizes MSBuild's newer and human-friendly format which can be developed using your preferred C# IDE of VS.NET, VS Code or Rider.
.NET Framework C# Templates | |
---|---|
angular-spa-netfx | .NET Framework Angular Bootstrap cli.angular.io App |
aurelia-spa-netfx | .NET Framework Aurelia Bootstrap Webpack App |
react-desktop-apps-netfx | .NET Framework React Desktop Apps |
react-spa-netfx | .NET Framework React Bootstrap Webpack App |
vue-nuxt-netfx | .NET Framework Vue Nuxt.js SPA Web App |
vue-spa-netfx | .NET Framework Vue Bootstrap Webpack App |
vuetify-nuxt-netfx | .NET Framework Vuetify Material Nuxt.js SPA Web App |
vuetify-spa-netfx | .NET Framework Vuetify Material Webpack App |
ASP.NET Core Framework Templates | |
---|---|
react-lite-corefx | .NET Framework ASP.NET Core lite (npm-free) React SPA using TypeScript |
vue-lite-corefx | .NET Framework ASP.NET Core lite (npm-free) Vue SPA using TypeScript |
.NET Framework Templates utilize MSBuild's classic project format which can be developed using either VS.NET or Rider.
Please refer to the documentation in each Project Template for info, scripts and features that's specific to each project template. We'll cover common features available in most SPA Templates.
Available SPA Project Templates have been bootstrapped with latest CLI tools and are each pre-configured with npm scripts which takes care of all packaging and bundling requirements. Gulp is primarily used to provide a GUI to run the templates npm scripts in VS.NET's Task Runner Explorer so all templates features can be accessed without leaving VS.NET, or if preferred each npm script can also be run on the command-line with:
$ npm run {script name}
All templates also follow our Recommended Physical Project Structure ensuring ServiceStack projects starts off from an optimal logical project layout, laying the foundation for growing into a more maintainable, cohesive and reusable code-base.
End-to-end Typed APIs​
Each template is seamlessly integrated with ServiceStack's TypeScript Add Reference and generic TypeScript @servicestack/client to provide an end-to-end Typed API to call your Services that can be synced with your Server DTOs by running the npm (or Gulp) dtos
script.
The Typed API request below uses the Server Generated
dtos.ts and generic JsonServiceClient
to display a Welcome message on each key-press:
import { client } from '../shared';
import { Hello } from '../dtos';
async nameChanged(name: string) {
if (name) {
let request = new Hello();
request.name = name;
let r = await client.get(request);
this.result = r.result;
} else {
this.result = '';
}
}
The imported client
is an instance of JsonServiceClient
declared in shared.ts module, configured with the BaseUrl at /
:
export var client = new JsonServiceClient(global.BaseUrl || '/');
The global.BaseUrl
is defined in package.json and injected by Jest or Karma in order to be able to run end-to-end Integration tests.
Angular 5 HTTP Client​
The Angular 5 template is also configured to use Angular's built-in Rx-enabled HTTP Client with ServiceStack's ambient TypeScript declarations, as it's often preferable to utilize Angular's built-in dependencies when available.
ServiceStack's ambient TypeScript interfaces are leveraged to enable a Typed API, whilst the createUrl(route,args)
helper lets you reuse your APIs Route definitions (emitted in comments above each Request DTO) to provide a pleasant UX for making API calls using Angular's HTTP Client:
import { createUrl } from '@servicestack/client';
...
this.http.get<HelloResponse>(createUrl('/hello/{Name}', { name })).subscribe(r => {
this.result = r.result;
});
TypeScript and Sass​
All templates are configured with TypeScript which we believe provides the greatest value in enabling a highly-productive and maintainable code-base. TypeScript lets you utilize the latest ES6/7 features including terse ES6 modules and async/await support whilst being able to target down-level browsers. Other benefits include better documented typed APIs, instant compiler feedback, rich intellisense and refactoring support in a graceful superset of JavaScript that scales well to be able develop prototypes quickly then easily go back to harden existing code-bases with optional Type information, catching common errors at compile-time whilst annotating modules with valuable documentation other developers can benefit from.
Whilst CSS is a powerful language for styling Web Apps it lacks many of the DRY and reuse features we take for granted in a general purpose programming language. SASS is designed to close that gap with a number of useful extensions to CSS aimed at enabling a highly-maintainable, modular and configurable css code-base. If you prefer to avoid learning SASS you can continue using vanilla css which has been enhanced with autoprefixer online version and precss support.
Optimal Dev Workflow with Hot Reloading​
The templates include a hot-reload feature which works similar to Sharp Pages hot-reloading where in DebugMode it will long poll the server to watch for any modified files in /wwwroot
and automatically refresh the page.
Hot Reloading works by leveraging ServiceStack Sharp Pages which works seamlessly with Webpack's generated index.html
where it evaluates server Template Expressions when returning the SPA home page. This is leveraged to enable Hot Reloading support by including the expression:
<i hidden>{{ '/js/hot-fileloader.js' | ifDebugIncludeScript }}</i>
Which renders the contents of /js/hot-fileloader.js when running the Web App during development.
Although optional, #Script
is useful whenever you need to render any server logic in the SPA home page, e.g:
<div>Copyright © {{ now | dateFormat('yyyy') }}</div>
Will be evaluated on the server and render the expected:
Copyright © 2022
Quick tour of Webpack​
Most SPA projects are pre-configured with tooling to manage their own Webpack app builds, but if you want to learn more please see the Tour of Webpack.
Watched .NET Core builds​
.NET Core projects can also benefit from Live Coding using dotnet watch which performs a "watched build" where it automatically stops, recompiles and restarts your .NET Core App when it detects source file changes. You can start a watched build from the command-line with:
$ dotnet watch run
Single Page App Features​
Our goals with the Single Page Templates is to provide a highly productive base that's ideal for developing small to medium-sized JavaScript Web Apps including just the core essentials that pack the most productive punch whilst adding minimal complexity and required configuration, whilst still remaining open-ended to easily plug-in other tools into your Webpack configuration you believe will improve your development workflow.
With these goals in mind we've hand-picked and integrated a number of simple best-of-breed technologies so you'll be immediately productive:
Integrated UI framework and Vector Icons​
Vue, React, Angular 5 and Aurelia are pre-configured with Bootstrap v4 and font-awesome vector font icons whilst Angular 4 is preconfigured to use Material Design Lite and Material Design Icons providing a solution for utilizing resources which are all developed and maintained by Google.
Updating Server TypeScript DTOs​
To get the latest Server DTOs, build the ASP.NET Web App then either right-click on dtos.ts
and select Update ServiceStack Reference from the Context Menu:
Or alternatively you can run the dtos
Gulp task in Task Runner Explorer GUI, or if preferred, run the script on the command-line with:
$ npm run dtos
Routing Enabled, Multi-page Layout​
All templates have multiple views with Routing enabled so they're all setup to develop multi-page navigable Single Page Apps out-of-the-gate. All templates are designed to be functionally equivalent utilizing a 3 page tabbed layout but implemented using their own idiomatic style so you'll be able to easily inspect and compare the structure and ergonomics of each JavaScript framework to evaluate the one you like best.
Deep linkable Pretty URLs​
All Single Page Apps are configured to use Pretty URLs (i.e. without #!
) and are deep-linkable so they behave similarly to server-generated websites in that they support the back button and full-page reloads to refresh the current page. This works behind the scenes using a [FallbackRoute]
to have all unknown routes return the home page so the route can be handled on the client to load the appropriate view.
JavaScript Unit Testing​
Aurelia, React and React Desktop Apps are configured to use Facebook's Jest Testing Framework with the React Templates configured to use Airbnb's enzyme virtual React DOM to enable fast, browser-less tests and includes a few different examples of client/server integration tests.
Angular and Vue are configured to use the Karma test runner with the headless phantomjs WebKit browser so the behavior of Components are tested in a real browser.
Tests can be run with the tests-run
gulp task, or on the command-line using any of npm's testing conventions:
$ npm test
$ npm t
Live Testing​
Each template also includes support for Live Testing which can be run in the background by clicking the tests-watch
Gulp task or on the command-line with:
$ npm run test-watch
Live testing automatically re-runs JavaScript tests after each change to provide instant feedback to detect when changes causes existing tests to fail.
Track progress whilst templates are being created​
The Single Page App templates sources their client dependencies from npm which can take up to few minutes to finish downloading and installing. You'll be able to see its progress by looking at the Bower/npm
Output Window in VS.NET:
You'll be able to detect when it's finished by waiting for the original contents of wwwroot/index.html:
<!-- auto-generated by webpack -->
to be replaced with a Webpack generated html template.
Keep Desktop node and VS.NET in sync​
Unfortunately VS.NET 2017 ships with an outdated version of node.exe which can be problematic when trying to run scripts from the command-line with a locally installed version of node as native module packages like node-sass are coupled to the specific node version and platform they were installed with. This can easily be resolved by configuring VS.NET to use your Desktop version of node instead by adding its the C:\Program Files\nodejs folder as the first path in:
Tools > Options > Projects and Solutions > External Web Tools
SPA Project Templates Overview​
All templates can be installed using our dotnet-new tool, which if not already can be installed with:
$ dotnet tool install --global x
The SPA Project Templates below have been bootstrapped with the latest CLI tools from their respective JS Frameworks:
vue-spa​
Bootstrapped with Vue CLI 3.
Create new Vue 2.5 Project for .NET 6.0:
$ x new vue-spa ProjectName
Create new Vue 2.5 Project for .NET Framework:
$ x new vue-spa-netfx ProjectName
react-spa​
Bootstrapped with create-react-app.
Create new React 16 Project for .NET 6.0:
$ x new react-spa ProjectName
Create new React 16 Project for .NET Framework:
$ x new react-spa-netfx ProjectName
angular-spa​
Bootstrapped with Angular CLI.
Create new Angular Project for .NET 6.0:
$ x new angular-spa ProjectName
Create new Angular Project for .NET Framework:
$ x new angular-spa-netfx ProjectName
vuetify-spa​
Bootstrapped with Vue CLI 3 and the vuetify cli plugin.
Create new Vuetify Project for .NET 6.0:
$ x new vuetify-spa ProjectName
Create new Vuetify Project for .NET Framework:
$ x new vuetify-spa-netfx ProjectName
vue-nuxt​
Bootstrapped with Nuxt.js starter template.
Create new Nuxt.js v1.4.2 Project for .NET 6.0:
$ x new vue-nuxt ProjectName
Create new Nuxt.js v1.4.2 Project for .NET Framework:
$ x new vue-nuxt-netfx ProjectName
vuetify-nuxt​
Bootstrapped with Nuxt.js + Vuetify.js starter template.
Create new Nuxt Vuetify Project for .NET 6.0:
$ x new vuetify-nuxt ProjectName
Create new Nuxt Vuetify Project for .NET Framework:
$ x new vuetify-nuxt-netfx ProjectName
SPA Project Templates Dev Workflow​
Whilst the client Application has been generated by the official CLI tool from each project, all templates continue to enjoy seamless integration with ServiceStack and follows its recommended Physical Project Structure. As the npm scripts vary slightly between projects, you'll need to refer to the documentation in the GitHub project of each template for the functionality available, but they all typically share the same functionality below to manage your projects development lifecycle:
Start a watched client build which will recompile and reload web assets on save:
$ npm run dev
Start a watched .NET Core build which will recompile C# .cs
source files on save and restart the ServiceStack .NET Core App:
$ dotnet watch run
Leaving the above 2 commands running takes care of most of the development workflow which handles recompilation of both modified client and server source code.
Regenerate your client TypeScript DTOs after making a change to any Services:
$ npm run dtos
Create an optimized client and package a Release build of your App:
$ npm run publish
Which will publish your App to bin/Release/netcoreapp3.1/publish
ready for deployment.
Testing​
The major JS Framework Templates are also pre-configured with their preferred unit testing solution which are run with npm's test
command:
$ npm test
Whilst Vue and Angular also include support for running end-to-end integration tests in a browser:
$ npm run e2e
This also highlights one of the benefits of utilizing npm's vibrant ecosystem where it benefits from significant investments like cypress.io which provides a complete solution for running integration tests:
Parcel SPA Template​
Create new Parcel Template:
$ x new parcel ProjectName
Parcel aims to provide the simplest out-of-the-box development experience for creating modern npm-powered Web Apps by getting out of your way and letting you develop Websites without regard for a bundling solution or JS Framework.
To enlist its functionality you just point parcel
to your home page:
$ parcel index.html
This starts a Live Hot Reload Server which inspects all linked *.html
, script and stylesheet resources to find all dependencies which it automatically
monitors for changes where it will automatically rebuild and reload your webpage. Then when it's time for deployment you can perform a production build
for your website with the build
command:
$ parcel build index.html
Where it creates an optimized bundle using advanced minification, compilation and bundling techniques. Despite its instant utility and zero configuration, it comes pre-configured with popular auto transforms for developing modern Web Apps which lets you utilize PostCSS transforms and advanced transpilers like TypeScript which the new Parcel Template takes advantage of to enable a pleasant development experience by enabling access to the latest ES7/TypeScript language features.
This template starts from a clean slate and does not use any of the popular JavaScript frameworks making it ideal when wanting to use any other micro JS libraries that can be referenced using a simple script include - reminiscent of simpler times.
Or develop without a JS framework, e.g. index.ts below uses TypeScript and the native HTML DOM APIs for its functionality:
import { client } from "./shared";
import { Hello } from "./dtos";
const result = document.querySelector("#result")!;
document.querySelector("#Name")!.addEventListener("input", async e => {
const value = (e.target as HTMLInputElement).value;
if (value != "") {
const request = new Hello();
request.name = value;
const response = await client.get(request);
result.innerHTML = response.result;
} else {
result.innerHTML = "";
}
});
The Parcel Template also includes customizations to integrate it with .NET Core Project conventions and
Sharp Pages Website enabling access to additional flexibility like dynamic Web Pages and server-side rendering
when needed. See the Parcel Template docs for information on the
available dev
, build
, dtos
and publish
npm scripts used to manage the Development workflow.
Seamless Parcel integration is another example of the benefits of #Script
layered approach and non-intrusive handlebars syntax which
can be cleanly embedded in existing .html
pages without interfering with static HTML analyzers like parcel and Webpack HTML plugins and their
resulting HTML minification in optimized production builds - enabling simplified development workflows and integration that's not possible with Razor.
Running .NET Core Templates in Visual Studio IIS Express​
Currently VS.NET doesn't support .NET 6.0 multiple bindings i.e. http://localhost:5000/;https://localhost:5001/
which all .NET Core Templates
are configured with. To run in IIS Express change it to specify only 1 binding:
Also if you wanted to re-use an existing registered port like 5000
you will need to run VS.NET in Administrator mode where it will let you override
any existing registrations, alternatively you can replace the port with an unused port number which will let you run it as normal.