How do I set up ASP.NET Core + Vue.js?
I need to integrate Vue.js with some ASP.NET Core MVC views. I picked Vue.js over other alternatives because it seemed to be simpler – "just add it via a <script>
tag", they said. No need to learn Gulp/Grunt/Webpack/Browserify/etc.
That turned out to be false. At my first attempt to handle dates I tried some extensions like vue-moment
and vue-datetime-picker
, taken from this official curated list of awesome things related to Vue.js but I hit a wall here. While the first does not mandate using the require()
JS syntax (CommonJS?), the second one doesn't work without it. Other extensions happen to 'use babel'
and imports
/exports
which is ECMAScript 6 that needs to be compiled. So, most Vue.js libraries and toolings indeed need a compiler, plus the require()
syntax, and all that stuff from the Node world?
How should I set up my project to work with ASP.NET Core MVC + Vue.js, in a way that I can develop many small Vue apps using Vue plugins (that can require(stuff)
)?
Solution 1:
I was totally lost when I asked the above question. I’ve spent a few days and I still don’t have a complete picture. What I am pretty sure is that 2016 is a hard year to learn JavaScript.
I wanted to use Vue.js because it’s simpler than the alternatives. Less ceremony, fewer boilerplates, less code. It's branded as the Progressive Framework... Right! But only to a point. Vue.js does not solve the JavaScript ecosystem fragmentation problem with build systems.
So, you will have to pick a side: Do you need JavaScript modules and a build system?
Option 1: Keep it simple: Avoid JS modules and build systems.
Reasons to follow this path:
- You don’t have many days to learn A LOT of stuff. (Configuring bundler, npm+package dependencies hell, ES6 stuff.)
- You do not want to make a bleeding-edge single-page application. Embedding Vue.js inside a few HTML pages seems enough.
- HTTP/2 is becoming mainstream, so bundlers like Webpack or Browserify will provide fewer benefits, at least on performance.
- Eventually ES6 modules will be supported directly in the browser, so we won’t need to build whatever the latest JavaScript is into browser-compatible JavaScript.
You will save many days by not spending time learning stuff that will probably be obsolete in a few years.
If you follow this path, a few recommendations:
- Just add JS libraries using the
<script>
tag. - Only use browser-ready JavaScript libraries. Code that uses
require()
or the UMD prefix(function (root, factory) {
requires you set up modules (therefore it is not browser-ready unless you set up CommonJS). JS files withimport
/export
statements are written in ES6 so avoid them too. - Use Bower to download browser-ready libs. Avoid NPM (which implies having a module system in place).
Caveat: You will not be able to use advanced Vue.js features like single-file components or Vue Router, but that is OK. You will have to do a few things manually.
Option 2: Learn JavaScript modules + build systems.
Prepare a few days to learn and not code. I will only explain briefly how Webpack worked for me. Browserify also works, but I haven't tried it.
I recommend you spend some time learning what JavaScript modules are. Then learn to build them and pack them: I used Webpack. Its documentation is not great, so what worked for me was to follow its tutorial step by step.
At this point, you may have heard that Webpack ALSO has a built-in web server with "hot module reloading". This is a web server for static files to be used only for development. Its benefit is that whenever you edit a JS module, the browser will automatically apply the change without refreshing. This is a very nice, but optional, feature. The problem: this built-in web-server competes with our web server (Kestrel). So, if you want to try this feature during development use the Webpack ASP.NET Core middleware provided at Microsoft’s JavaScriptServices repo. There you will find the WebApplicationBasic template that I am currently using. I dissected it, removed most of its parts and by trying to use it I slowly understood what each part was originally for.
When using Webpack you will mostly use 3 workflows:
- Built-in development mode: Creates huge files, easy for debugging. Use it together with ‘watch-mode’ so whenever you modify a file, a new Webpack build is triggered.
- Built-in production mode: Creates small minified files. Useful for ‘dotnet publish’.
- Using Webpack's web server and hot module reloading with the Webpack ASP.NET Core middleware means your app will run Webpack in the background, build, and watch the source files for changes. The compilation output is not written to disk and only kept in memory and served via HTTP. The JavaScriptServices middleware forwards requests from Kestrel to Webpack's web server to make this work.
Whatever Webpack config you go with, you have to include ‘vue-loader’ in your Webpack config. You may be inspired by Vue’s webpack-simple template.
I haven’t covered everything that I wanted to, but this topic is too extensive and I need to go back to coding. Please leave some feedback.
Solution 2:
I'm late to the party but there is now a template available for .NET Core that you can build with a single command. On a Windows box with .NET Core installed just create an empty folder and in that folder run this command to show a list of available templates:
dotnet new
If you don't have all the templates, you just need to run this to install the SPA templates:
dotnet new --install Microsoft.AspNetCore.SpaTemplates::*
And this to scaffold a new Vue app:
dotnet new vue
In milliseconds a complete new Vue.js single-page web app is built with a working .NET Core back end with controllers, views etc. It's brilliant. Just open the project in VS or VS Code and you're away.
There are also templates for Aurelia, Angular, Knockout and React! You can build them all and compare how each solves the same problem. The Angular one even does server side pre-rendering out of the box!
I know .NET Core has a way to go but it's becoming more and more awesome by the day!
Solution 3:
First, a disclaimer: I couldn't find anything that really fit what I needed, so I put together a solution from scratch. See the end.
You ask about including Vue via the <script>
tag (in that case the CDN build).
However, you also mention using Babel and the ES6 modules feature. In that case I would recommend using Webpack for the client-side app, which will compile your ES6 with Babel, allow you to use modules and components, and work with a template! You also get hot module reloading (edit your source and see changes in the client app in real time!) and Webpack will bundle your SPA into a static HTML5 app.
The official Vue.js docs point to their own Webpack template.
So you can run the Webpack dev server and your ASP.NET Core app independently, if that suits your needs, but there's a better solution that makes development even more streamlined:
Microsoft's open-source JavaScriptServices lets you execute Node.js from ASP.NET Core, and they have some Webpack middleware that integrates the Webpack dev server into your app during debug builds.
They provide official templates for Angular 2, and even a template labeled Vue.js, but the Vue template is just the official Webpack template without any integration with .NET; this is just like the standalone server.
I couldn't find any templates that did this for Vue.js, so I put together a sample ASP.NET Core application that loads the Webpack dev middleware with a Vue.js Webpack app. When the .NET Core server is running in dev mode, you can edit the Vue source, and the changes will be reflected with quick incremental patches without needing to rebuild the entire application. In release mode, .NET Core will use the prebuilt Webpack output. You can find it on GitHub:
https://github.com/0xFireball/YetAnotherShrinker
The repository linked above has a full application demo that uses NancyFx, axios, Vue.js, and Vue Material, and is a simple URL shortener. If you want steps for a more minimal setup that can easily be added to an existing app, check out this blog post of mine.
Obligatory disclosure: I wrote that blog post.
Solution 4:
Maybe someone will find this information helpful.
Here are some starter templates you can use for a quick project setup.
The first one gives you a multi-project solution with some predefined architecture. This template more closely matches real-world projects than the JavaScriptServices solution which was already mentioned here. It provides a domain layer, repository layer, etc. Note that this is a Yeoman generator and it uses TypeScript. https://github.com/vue-typed/generator-vue-net-core
The second is just a project on GitHub and you should clone it if you want to use it. It is not a Yeoman generator and I think this is regrettable, but I found the structure in this template better than in the first one. Also, it has a lot of nice little things like some exception filters, that you, most likely, will still do anyway. And if you are a beginner, this template will be just a godsend. This template is recommended on the awesome-vue page. Here's the link: https://github.com/mrellipse/toucan