Vue.js and ASP.NET MVC

Nowadays, there are a lot of options to chose from when implementing a new web application: React, Angular, Vue, Polymer and the list can go on and on. These frameworks play very nicely with REST services or web applications as Single Page apps. This is all great, but many web applications are still built on top of MVC architectures which makes it kind of hard to integrate some of the JavaScript frameworks menioned above.

Vue.js positions itself as “The Progressive JavaScript Framework” which means that you can pretty much start using it as jQuery like in the example below:

This is a very good starting point, but as we all now, apps grow in size very fast and managing scripts inside Views tends to get messy, not testable and very hard to read. Above that, it would be kind of nice to use NPM and some sweet ES6 features.

There are a couple of articles, such as this one on how to integrate Vue.js in .NET MVC projects in such a way so you can use NPM, but the setup is kind of complicated. The setup from the article above uses gulp, browserify and has some limitations such as supporting only require syntax for handling assets.

We will try to bring together a pretty basic webpack setup and see how we can integrate it inside our MVC app. Webpack is the most popular module bundler these days and there are a lot of cool things you can do with it!

Project setup

We will start with a clean MVC project, without any css or javascript files like so:

You can also find the sources inside this Github repo. When running it, we shall see 2 text messages like so:

Let’s add a package.json and a webpack.config.js and then run npm install inside the directory where package.json is located.

It might seem that the webpack.config is quite a long file and it’s probably hard to understand, but don’t worry. It actually does a lot for it’s size. Let’s go through the most important parts of it so we can understand what part does what.

Webpack configuration explanation

We will start with the first function

This function aims to generate a set of entries for webpack so webpack can process them. It basically loops through folders inside Scripts/app and tries to add every index.js file that it finds there. Let’s see how that folder looks actually

Now, every folder inside our app folder which contains an index.js can be processed by webpack.

We will jump to the next section of our config which is the output section

We specified here that, upon build we want each entry to be copied inside Scripts/bundle folder with the exact name of the entry. This means that if we have a home folder, it will provide a home.js output inside the bundle folder.

Let’s run npm run build to actually see the result. You should see a similar result to the one bellow.

So based, on the 2 folders we have inside app , webpack generated us 2 javascript files which are compressed and minified.

We will skip the next section which references some loaders. We, reference 4 loaders (vue, scss, css and js) so we can use .vue (single file components) as well as javascript and css imports. You can read more about loaders here.

We have 2 more sections to cover, and the next one is the most magical thing which you might not get at first.

Webpack uses webpack-dev-server for development which is basically a node.js based server which serves assets (javascript, css etc) that our browsers can interpret. Usually these assets include some development friendly features like Hot Reload. These assets are not minified and are quite different from the ones generated when building for production.

If you run npm run dev inside the folder where package.json is located, you should see an output simillar to this one:

Don’t worry about the big warnings. These files are used in development mode only and their size doesn’t really matter for now.

If you go to http://localhost:8086/Scripts/bundle/home.js , you should receive a javascript file. Getting back to our dev server proxy,

webpack-dev-server has a feature which can proxy requests from one url to another. In this case, every request from http://localhost:5001 will be proxied to our http://localhost:8086 . So, if we run our MVC app on http://localhost:5001 and run npm run dev , on port 8086 we should see the same output as from our MVC app.

Let’s actually try that:

Now, make sure the url we have specified in our proxy config, is the exact url your MVC web application is running on in order to make this work. You might ask yourself “Why do I need that?”. Well the answer is that if we want to reference scripts easily inside Views and also have Hot Reload which means that whenever you change some css or js files your changes will be automatically pushed to your page without the need to REFRESH it!

Time to go through our last webpack config part which is the following one:

This part minifies and optimizes our javascript bundles as well as replaces vue with a production version of it (basically vue.min ) through NODE_ENV: '"production"'

Time to CODE!

Let’s start by adding our HomeController

And then the View for it

We will display 2 messages inside the view. One which is sent from the controller and one rendered with Vue We reference the script to be pointing at the bundle folder, which, if you remember is specified in our webpack config:

path: path.resolve(__dirname, './Scripts/bundle/'),
publicPath: '/Scripts/bundle/',

This means that our assets will be served by webpack-dev-server to this path Scripts/bundle in development and will be copied to the same path while building assets for production.

Let’s add our javascript file inside Scripts/app/home/index.js

If you go to http://localhost:8086 , you should see something simillar now:

Try to change the message inside our javascript file and see some auto-reload magic on your page. Let’s add a Vue component. I called it FirstComponent.vue

We can now import it inside our index.js file and use it inside our View.

The Home View should look like this now

And the output would be something like this:

That’s pretty much it! We have now support for .vue components, hot-reload and ES6 support with a single webpack config!

Bonus: Bootstrap + Sweet-Modal

As a bonus, we will add bootstrap and Sweet Modal vue component. Let’s get started by

npm install --save bootstrap sweet-modal-vue

Next, we will create a new folder inside our app named layout together with an index.js file where we will import bootstrap like so

import 'bootstrap/dist/css/bootstrap.css'

And then add the new script to our _Layout.cshtml like so

@Scripts.Render("~/Scripts/bundle/layout.js")

Make sure you restart webpack npm run dev , whenever you add new folders with index.js files.

We will modify our home/index.js file to use SweetModal

And then adjust our View a little bit

The output should be something simillar to the image bellow, upon clicking the button

Conclusion

We ended up using Vue.js combined with server data and all the neat features such as Single File Components , ES6 features, Hot-Reload, asset minification, sass support and NPM.

Note that this configuration is not limited to .NET MVC. You can use a similar setup in any other MVC project such as PHP Laravel, Ruby on Rails and so on. Hope you found this useful and will have more confidence when thinking about Vue and MVC projects !