Vue.js has recently got many attentions as it is relatively easier to learn and lighter in size, comparing to other popular frameworks like Angular 1, Angular 2 or React. By providing a middleware, ASP.NET Core supports those front-end frameworks such as Angular2, Aurelia, React, Knockout, etc, while Vue has been excluded out-of-the-box. Even though we can find many good articles and code samples to integrate Vue and ASP.NET Core, as they don’t use the basic template that Vue is providing, it’s a little difficult for developers to apply at their first glance, who want to use both Vue and ASP.NET Core with minimum integration efforts. In this post, we are going to integrate Vue.js and ASP.NET Core using their basic templates, with minimum modification.
The code sample used in this post can be found at here.
Microsoft.AspNetCore.SpaServices
In order to support front-end development in ASP.NET Core, Visual Studio uses Bower. However, as we are already aware how fast front-end development environment changes, another option like Webpack helps developers work a lot easier by offering bundling, moduling and so forth. ASP.NET Core, of course supports Webpack as a separate extension. Microsoft.AspNetCore.SpaServices
helps developers integrate front-end frameworks using Webpack with ease.
Prerequisites
Throughout this post, we need some preparations:
We can also use Visual Studio Code (VSC), but we’re assuming to use VS for this post.
Creating ASP.NET Core Web Application
Open Visual Studio and create a new ASP.NET Core web application project. As this web application likely uses .NET Core version 1.0.1, we need to update it to 1.1 by updating global.json
:
Also, update project.json
so that all NuGet packages in the web application can be complied to .NET Core 1.1:
As mentioned earlier, we’re using Webpack instead of Bower, so remove Bower-related configuration files as well as ASP.NET Core native bundling & minification setting files:
.bowerrc
bower.json
bundleconfig.json
And finally, all directories and files under the wwwroot
directory need to be deleted. We’re all set now at the ASP.NET Core application side. Let’s add Vue.
Installing Vue.js
We can use Vue as a stand-alone library by simply including the script from CDN. However, if we want to use its powerful features especially for componentising, module bundlers like Webpack should be considered. In order to use Webpack for Vue.js, if node.js
and npm
have already been installed, install vue-cli
:
Then, install the basic template by running the following command:
During installation, just leave all the question as default value and finally template gets installed. Now, run the following command to install all npm packages and run the Vue app:
Since Vue uses the port number of 8080
, we can see the result as expected. However, this is just a Vue app running independently, not the one integrated with ASP.NET Core. Let’s move on.
UPDATE on March 6th, 2017: when we run
vue-cli
using the commandvue init webpack
, it installsvue@2.2.1
. If the version of VueJs is earlier than that, please update as VueJs has some breaking changes on 2.2.x.
Integrating Vue.js with ASP.NET Core
This is the main part of this post. We need to touch configurations at both sides.
Configuring Vue.js
First things first. We need to install the npm package, aspnet-webpack
, to enable communication between front-end framework and back-end application through Webpack:
Once installed, update config/index.js
to setup the root directory:
And finally, create webpack.config.js
and save it to the root directory of the ASP.NET Core project:
We now got Vue.js setup done. What’s next?
Configuring ASP.NET Core
aspnet-webpack
corresponding package in the ASP.NET Core side is Microsoft.AspNetCore.SpaServices
. Install it through NuGet package manager and register a middleware at Startup.cs
:
We also need to add a routing configuration for SPA like above. Is the ASP.NET Core side relatively simple? Let’s punch the F5 key to run the app and see how it’s going.
We now can see a different port number that is handled by the ASP.NET Core app. So, technically we completed integration between Vue.js and ASP.NET Core! How can we ensure if they are actually working together? Let’s implement a basic AJAX call to see whether they get along with each other. Of course further modification is required. Who can stop us?
Handling AJAX Request/Response
As Vue.js core is lightweight, if we want to implement more sophisticated works like handling AJAX request/response, we need to install another npm extension called vue-resource
.
Once installed, add it to the Vue instance for use. Update src/main.js
like:
Now we need to implement AJAX request/response codes. Open /src/components/Hello.vue
and modify it like:
What we can expect from this change is the message Welcome to Your Vue.js App
will be replaced with the value from res.body.message
. Now we need to implement the Web API. Here’s the Web API controller and action:
All good. Build the app, press the F5 key and confirm the result.
We can see Hello World
, instead of the original message.
Side note: Another benefit of using Webpack is Hot Module Replacement (HMR). As long as the app is up and running on our local machine, we can instantly change something and check the result with no time, without reloading the page. Of course, if we install .NET Core Watcher tool, we don’t even need to rebuild and rerun the app itself either.
Deploying App to Azure
We’ve built an ASP.NET Core web application with Vue.js. Now it’s time for deployment. We don’t use View features provided by ASP.NET Core. Instead we just use a static(?) wwwroot/index.html
. In our local development, we don’t really have to worry about that as our development environment automatically detects that. However, in a production environment, we have to specify we’re using the static index.html
page; otherwise Azure web app can’t recognise it. To enable this feature, we need to update Startup.cs
:
Make sure that the UseDefaultFiles()
method must always come before the UseStaticFiles()
method. Finally update deployment/publish related settings in project.json
for Vue.js:
Everything is done! Deploy this web app to Azure and see the result. Can we see it as expected?
So far, we have installed Vue.js, integrated it with ASP.NET Core, implemented whether both are working together or not, and deployed the app to Azure web app instance. Some may think this looks too complicated, but actually, it’s not that tricky. Rather, we’ve got another option on ASP.NET Core application development using a different front-end framework. As long as a new front-end framework emerges and it supports Webpack, we can make it working like this approach. The next post will discuss how to write VueJs apps in TypeScript, running on ASP.NET Core.
hi,
I was flow this post and it run success. but I met a new question, when I edit the codes in Hello.vue and save it, it can not render on the browser.
the chrome debugger show follow info:
Uncaught RangeError: Maximum call stack size exceeded
at webpackHotUpdateCallback (app.js:7)
at webpackHotUpdateCallback (app.js:9)
at webpackHotUpdateCallback (app.js:9)
at webpackHotUpdateCallback (app.js:9)
at webpackHotUpdateCallback (app.js:9)
at webpackHotUpdateCallback (app.js:9)
at webpackHotUpdateCallback (app.js:9)
at webpackHotUpdateCallback (app.js:9)
at webpackHotUpdateCallback (app.js:9)
at webpackHotUpdateCallback (app.js:9)
app.js:
/**1****/ (function(modules) { // webpackBootstrap
/***2***/ function hotDisposeChunk(chunkId) {
/***3***/ delete installedChunks[chunkId];
/***4***/ }
/***5***/ var parentHotUpdateCallback = this[“webpackHotUpdate”];
/***6***/ this[“webpackHotUpdate”] =
/***7***/ function webpackHotUpdateCallback(chunkId, moreModules) { // eslint-disable-line no-unused-vars
/***8***/ hotAddUpdateChunk(chunkId, moreModules);
/***9***/ if(parentHotUpdateCallback) parentHotUpdateCallback(chunkId, moreModules);
/***10***/ } ;
…..
is seems endless loop on line 9.
i have no idea for this.
@zhao Thanks for your comment. You can simply reload the page and the issue you’re facing will disappear. Not sure it’s the issue on VueJs side or ASP.NET Core side. Can you reproduce the same issue without ASP.NET Core being wired up?
I initially thought it is on ASP.NET Core side, when I run the vue front-end project by ‘ npm run dev ‘ , the problem was gone.
It just show while run by visual studio.
@zhao If this only occurs when you run VueJs app through ASP.NET Core, I would suspect it comes from the NuGet package, Microsoft.AspNetCore.SpaServices, especially the HMR part. Let’s have a look.
@zhao It seems to be the issue on the NuGet package, Microsoft.AspNetCore.SpaServices.
* https://github.com/aspnet/JavaScriptServices/issues/757
* https://github.com/aspnet/JavaScriptServices/issues/764
I also raised a new issue on that. Will see how it’s going.
Hi,
Whenever I run “npm run dev” the server never boots completely. The page just keeps on loading and on the console there is no log saying that the server is listening on port 8080.
Please Help.
Thanks in advance
@Nimzy I’m not quite sure what your situation is facing. Did you use my code sample or on your own? If you use your code sample, please provide details how to reproduce the error?
With VS2017 ASP.NET Core there is no project.json file created by default. Is the process different?
@CodeGrue Thanks for the comment.
VS2015 uses .xproj with project.json, while VS2017 uses .csproj that embraces all bits & pieces of project.json, more specifically all NuGet packages and build steps, etc. This post is targeting VS2015, rather than VS2017, because at the time of this writing VS2017 RTM was not publicly released
Therefore, if you want to add NuGet packages, you might need to use either PS cmdlet, Install-Package, or GUI. If you update build or publish options, you might need to use the project property GUI menu.
HTH
I think this in your csproj will do the same thing
@Russ Probably, yes. I haven’t tried VS2017 yet because of a few limitations on my use – particularly for TypeScript 2.2.x support.
Hi,
I run “vue init webpack” command in vs2015 ASP.NET Core Project Directory
like C:\Users\xxx\Documents\Visual Studio 2015\Projects\wb1\src\wb1
but nothing happen and no error message
seems like install pause and can’t break
plz help
@Allen Thanks for your comment.
Can you reduce the depth of your project folder? Windows has a path length limitation of 256 characters. It might cause your issue.
Other than that, if you can run the same command on another location and it works fine, that should be fine within your ASP.NET Core project, too.
1. npm install -g yo generator-aspnetcore-spa
2. npm install -g webpack
3. Create directory and execute the next step
4. I aspnetcore-spa, choose the framework to use: Angular, React, VueJs, etc.
5. Then to run the application we write: dotnet run
6. Use localhost: 5000 to view the in the browser
7. Open the Visual Studio application.
@Alberto Thanks for the comment.
You’re right. At the time of this writing, the Yeoman Generator didn’t include VueJs template. Now it’s possible. 🙂 The VueJs template even includes TypeSript support using av-ts.
https://github.com/aspnet/JavaScriptServices/tree/dev/templates/VueSpa
If you like to use TypeScript support with av-ts, I would recommend using that Yeoman Generator, which makes our lives easier.
fix Line 4.
4. YO aspnetcore-spa, choose the framework to use: Angular, React, VueJs, etc.
Thanks for your “tutorial” , but i have an issue at the end , when i try to add the ajax call , i get the error:
[Vue warn]: Error in created hook: “TypeError: Cannot read property ‘get’ of undefined”
found in
—> at path\WebApp\src\components\Hello.vue
at pathWebApp\src\App.vue
any idea ?
@Dashell Thanks for your comment.
It seems that vue-resource is not properly imported to invoke the AJAX call. Can you double check for this?
I had the same problem and I have fixed it with the following code:
import VueResource from ‘vue-resource’
Vue.use(VueResource)
Import vue-resource and use it.
Hi,
I add final step with created() in Hello.vue and api controller, everything seems to compile well and the page is displayed, but I do not get “Hello world” string, also method in the controller is not executed. What can be the reason?
Thanks,
@Pasch Thanks for your comment!
Seems that your code didn’t send the AJAX request properly. Would you double check with that?
Hi, yes it did not, I wonder what may be the reason?
I replaced it with axios and it works fine:
created () {
axios
.get(‘/api/hello’)
.then((res) => {
this.msg = res.data.message
})
}
@Pasch Yeah, it would be a good idea to replace vue-resource with axios as officially Vue.js recommends using axios for AJAX handling.
Actually in the other post of mine, https://blog.kloud.com.au/2017/02/24/writing-vuejs-apps-in-typescript-on-aspnet-core/, I’ve mentioned axios to replace vue-resource.
In main.js change the vue-resource reference to:
import VueResource from ‘vue-resource’
Vue.use(VueResource)
As you might be aware, axios is better than vue-resource, and axios has been officially recommended by Evan.
when I modified some files , that always show :
“Uncaught RangeError: Maximum call stack size exceeded” n chrome console .
But if I use “npm run dev” ,it is ok .
What happen?
@jjb That’s because HMR has been called twice.
https://github.com/aspnet/JavaScriptServices/issues/764#issuecomment-286949195
Nice article!
This article helps you by providing code which has really help me Running Vue.js on aspdotnet core application.
Thanks for sharing!
@Tushar Thanks for your comment!
Thanks for the wonderful article!
This https://github.com/aspnet/JavaScriptServices/tree/dev/templates/VueSpa package has only with TypeScript integration. Is there any option/pacakge to use Vue js with ES6 for ASP.NET Core SPA?
@Hussain Thanks for your comment!
At the time of writing this post, the package wasn’t rolled out. As you mentioned, the package assumes to use TypeScript, so if you want to avoid TypeScript, just try my approach. Please bear in mind that this post might be working differently, against the latest version of Vue.js.
Better way to do this now is to use the template from:
“`
dotnet new –install Microsoft.AspNetCore.SpaTemplates::*
“`
How to integrate one of existing admin templates to .net core like CoreUI or AdminLTE+vue?
Your method does not work for them (It seems that they also were made using vue cli)
@Edgar Thanks for your comment!
To be honest, I’ve never used those libraries. Just bear this in mind that this post was written in Feb, 2017. It may not work well with the newer version of vue-cli.
Regardless of those libraries, this post provides a general approach to integrate Vue with ASP.NET Core. It would be great if you ask the maintainer of those libraries.
May I ask you one more question? Did you create Home controller and index action in that?
The problem is that I get blank page when I refresh vue page (only root route is working).
So what is the problem with this configuration below:
// Setup additional routing for SPA
routes.MapSpaFallbackRoute(
name: “spa-fallback”,
defaults: new { controller = “Home”, action = “Index” });
});
I tried to create Home controller and Index Action also and it seems that it fires when I try to refresh, but it can’t find index.html in wwwroot folder (tried to return file);
I also tried adding
app.UseDefaultFiles();
before UseStaticFiles();
Nothing helps
@Edgar I’m not quite sure what you were trying to achieve. If you just try my sample code linked in the post, it should work well and you may start from there. At the time of this writing, I had no problem for routing.
Hello @justin – I like this simple file structure better than the Single Page App template from .net core. Nice blog post.
I am having troubles deploying the application to aws through elastic beanstalk. I even tried your sample projects in the git repo and had no success. Everything works fine locally. I am probably bundling / zipping up the project incorrectly. Could you provide some guidance.
Thanks in advance
@Boum Thanks for your comment!
As I’ve never used AWS Elastic Beanstalk, I’m afraid I can’t help here, but I’m interested in details of the difficulty you’ve been experiencing on.
The difficulty lies in the fact that using the AWS ElasticBeanstalk service you need to zip your .net core application in a certain way for the deployment to be successful.
The difference with the SPA templates .NET core provides is that the client side code is not located at the root of the repository. Every deployment I have done so far have been unsuccessful – I will dig some more and provide an update comment when I successfully deploy.
How can we pass an object and get this object as action parameter in controller