Microsoft has been regularly releasing and updating Single Page Application (SPA) templates for ASP.NET Core. These templates provide a great starting point if you are planning to build a Single Page Application using frameworks like Angular, React or Vue with the help of IDEs like Visual Studio.
Microsoft’s newest source code editor Visual Studio Code has been receiving an amazing response from developers everywhere, particularly from web developers. Personally, I have found VS Code a very powerful but lightweight tool and I am enjoying using it.
In this article, I will take a look at how these two play together so you can get a nice debugging experience of your SPA applications in VS Code for both client and backend code.
Using VS Code to debug ASP.NET Core apps
Setting up a new SPA project
You could create a SPA project from scratch, manually bringing and configuring all the libraries and tooling, a modern web application requires these days.
Or you could install the SPA (Single Page Application) templates provided by Microsoft and get everything wired out-of-the-box. As per their blog post announcement, installing the templates is as easy as running:
dotnet new --install Microsoft.AspNetCore.SpaTemplates::*
Now if you run dotnet new in a console, you will see different SPA templates. In its current version, this package installs templates for Vue, Angular, React, Knockout and Aurelia:
Figure 1, installed "dotnet new" templates
In this article, I will use the Vue.js template but you could easily apply the same ideas to other templates.
To create the new Vue project, simply run the following commands on the console:
dotnet new vue
This will generate a new ASP.Net Core project using the Vue SPA template. Now let’s run the project and verify everything is working.
Figure 2, the generated project in Visual Studio Code
Figure 3, running the project
At a high level, what you have is a project made of:
- An ASP.Net Core backend
- A SPA frontend using Vue 2 and Typescript
- Bootstrap 3 styling
- Webpack generating the js/css bundles ultimately send to the browser, wired for both development and production modes.
With such a setup, being able to properly debug your frontend code using the same original files in your project, will be critical!
Running from the Command Line
It is absolutely possible to run your new project directly from the command line.
- Remember to run dotnet restore && npm install after the project was created, so all the required nugget and npm dependencies are installed.
- To properly run in debug mode, you need to set the environment variable ASPNETCORE_ENVIRONMENT to “Development”. See the announcement blogpost for more details.
Then simply run dotnet run from the command line and open http://localhost:500 in your browser. Press Ctrl+C to stop it once you are done.
Debugging from Visual Studio 2017
Everything has been wired in the project template, so locally running your new application works out of the box as you would expect.
Open the project with Visual Studio 2017 and press F5.
- Nuget and npm dependencies will be restored/installed if it’s the first time you open and launch the project
- The application will be built with the Debug configuration
- Once ready, your browser will be launched and your application will be loaded.
The debugger is attached as you would expect, and that includes setting breakpoints both in the server side code and the client side typescript Vue code!
Figure 4, breakpoint on a typescript file in Visual Studio 2017
Debugging from Visual Studio Code
How well does VS Code play with our newly created Vue project?
First make sure you have the C# and the Debugger for Chrome extensions, then open the folder in Visual Studio Code:
Figure 5, the generated project in Visual Studio Code
Now let’s add some launch configurations that lets us start the project and attach the debugger. (If you have troubles, take a look at the contents of the .vscode folder from a related article’s code in GitHub)
Figure 6, adding launch configurations for .Net Core
Open the Debug panel and click on the cog icon to add new launch configurations. Since you installed the C# extension, you should see an option for .Net Core. Click it and it will generate the launch.json file that VS Code uses for defining launch configurations.
Figure 7, trying the .Net Core Launch (web) task
You should now see several launch options in the Debug panel.
If you select the .Net Core Launch (web) option and press F5 to start debugging, you will get a message saying Could not find the prelLaunchTask ‘build’.
- If you inspect the launch.json file you will notice all the generated configurations have the setting "preLaunchTask": "build"
- This basically means we need a way of running dotnet build to compile the project before it can be launched.
Figure 8, error due to missing tasks.json for .Net Core
Just click on the Configure Task Runner button next to the error message and select the .Net Core option. A new tasks.json file will be generated, telling VS Code how to run .Net Core tasks like dotnet build.
Now press F5 again, and you will see another error!
This time it says launch.json must be configured. Change 'program' to the path to the executable file that you would like to debug. What this means is that the auto-generated launch.json requires some manual changes before it can be used. If you open it, you will see the following parameter:
This must be changed into the right path to the dll of the compiled output. The target framework can be found in the .csproj file, and the project name is the same as the name of that .csproj file:
There is still one more thing to do before we can finally launch the project!
- As we will see later, the Vue template uses Webpack to generate the JS and CSS bundles instead of directly serving JS and CSS files to the browser.
- To make the development and debugging easier, dev middleware is automatically wired in Debug mode, which generates and serves the bundles on the fly. However, this still depends on the underlying Webpack npm modules.
- We just need to restore all the npm modules by running npm install, for example in the VS Code integrated terminal. Otherwise we will get an exception in the Configure method of the Startup class when running app.UseWebpackDevMiddleware .
Finally, once the required files launch.json/tasks.json were created and after running npm install, we can launch the project in debug mode selecting the .Net Core Launch (web) launch task. This will open the browser and start the project with the debugger attached:
Figure 9, debugging the project in VS Code
Bear in mind this includes debugging support for the server side code, but unlike when we run the project in VS 2017, there is no debugging out of the box for the client side Vue code.
Don’t worry, as we will see in the next section, you have a few options available, including integrated client and server debugging in VS Code.
Debugging client side in Visual Studio Code
The most straightforward option and one that will be available regardless of how you debug your server side code, is using the browser developer tools.
Since you are running the project in Debug mode, Webpack will include source code maps in its generated bundles.
This means you will be able to see the original typescript files in the browser dev tools (under dist/../../ClientApp), and you will be able to debug and set breakpoints in those files.
This way you can use Chrome to debug your client side code:
Figure 10, using Chrome to debug the client side Vue code
The other option uses the Chrome Debugger extension for VS Code and the support for composite launch configurations! It requires a few steps to setup, but is straightforward enough. It assumes you installed the Debugger for Chrome extension, so you should install it now if you didn’t.
Select the debugger tab and add a new Launch: Chrome launch configuration. This will add a new configuration like the following one to your launch.json file:
"name": "Launch Chrome",
We need to update it so it launches the same url our server will be listening to and to properly specify where to find the source code file, including how to interpret the source maps of the Webpack bundles:
"name": "Launch Chrome",
Since that task will start Chrome itself, we now need to use a task that launches the .Net Core app without also launching the browser.
If you paid attention to the launch.json file when we added the .Net Core launch tasks, you might have noticed it created different tasks including .NET Core Launch (web) and .NET Core Launch (console). The latter is going to be really handy now, if you deleted it, you can recreate it in VS Code from the Debug tab.
Let’s then update package.json with a composite launch task that includes both the Launch Chrome and the .Net Core Launch (console) tasks:
"configurations": [ ".NET Core Launch (console)", "Launch Chrome" ]
// chrome debugger
// .Net Core Launch (console)
// .Net Core Launch (web)
Then you will be able to select .Net+Browser in the Debug tab, which will start chrome, the .Net Core application and provide debugging support for both!
Figure 11, debugging client and server side in VS Code
Again, if you have any trouble creating these files, check the files in this related article’s code in GitHub.
The frontend code of a modern web application uses several different tools and libraries that need to be properly configured and wired. Debugging your code also requires an understanding on how they play together.
When using a tool like Webpack, to process your frontend source code, it is critical to properly configure developer debugging features like source maps. The configuration should be done in a way that lets you debug the code using the original files, independently on whether that is debugging on the browser or in your editor.
Thankfully the SPA templates have taken care of configuring these libraries and tools for you. This means for example in Visual Studio 2017 you get full debugging experience after the template was created.
Visual Studio Code, being a lightweight editor rather than a full IDE, requires a few manual steps and some extensions installed. Hopefully in this article I have demonstrated this is not that complicated and is mostly guided or assisted by VS Code itself.
At the end of the day, you can use the editor that you prefer and still have a good debugging experience.