Skip to content

Instantly share code, notes, and snippets.

@yetanotherchris
Last active December 21, 2023 18:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yetanotherchris/9f2107fd5380596546649772346c760f to your computer and use it in GitHub Desktop.
Save yetanotherchris/9f2107fd5380596546649772346c760f to your computer and use it in GitHub Desktop.
Vue JS with ASP.NET Core - basic example

Vue JS with ASP.NET Core

These notes come with much appreciation from Packt's ASP.NET Core 2 and Vue.js, adapted for my use.

.NET Core currently (2.2) only ships with a React and Angular project template. There is a Vue one but it uses Typescript and for some unknown reason doesn't compile when you perform a "dotnet run".

Install the dotnet template

  • dotnet new --install Microsoft.AspNetCore.SpaTemplates::*
  • dotnet new vue

Cleanup package.json

Remove some NPM packages (Typescript, BootStrap, jQuery (!)) from package.json so it looks like this:

{
  "name": "temp",
  "private": true,
  "version": "0.0.0",
  "devDependencies": {
    "aspnet-webpack": "^2.0.1",
    "css-loader": "^0.25.0",
    "event-source-polyfill": "^0.0.7",
    "extract-text-webpack-plugin": "^2.0.0-rc",
    "file-loader": "^0.9.0",
    "isomorphic-fetch": "^2.2.1",
    "style-loader": "^0.13.1",
    "url-loader": "^0.5.7",
    "vue": "^2.2.2",
    "vue-loader": "^11.1.4",
    "vue-router": "^2.3.0",
    "vue-template-compiler": "^2.2.2",
    "webpack": "^2.2.0",
    "webpack-hot-middleware": "^2.12.2"
  }
}

Update webpack.config.js

Change webpack.config.js to remove Typescript stuff, so it looks like this:

const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const bundleOutputDir = './wwwroot/dist';

module.exports = (env) => {
    const isDevBuild = !(env && env.prod);

    return [{
        stats: { modules: false },
        context: __dirname,
        resolve: { extensions: [ '.js' ] },
        entry: { 'main': './ClientApp/boot.js' },
        module: {
            rules: [
                { test: /\.vue$/, include: /ClientApp/, loader: 'vue-loader' },
                { test: /\.css$/, use: isDevBuild ? [ 'style-loader', 'css-loader' ] : ExtractTextPlugin.extract({ use: 'css-loader?minimize' }) },
                { test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
            ]
        },
        output: {
            path: path.join(__dirname, bundleOutputDir),
            filename: '[name].js',
            publicPath: 'dist/'
        },
        plugins: [
            new webpack.DefinePlugin({
                'process.env': {
                    NODE_ENV: JSON.stringify(isDevBuild ? 'development' : 'production')
                }
            }),
            new webpack.DllReferencePlugin({
                context: __dirname,
                manifest: require('./wwwroot/dist/vendor-manifest.json')
            })
        ].concat(isDevBuild ? [
            // Plugins that apply in development builds only
            new webpack.SourceMapDevToolPlugin({
                filename: '[file].map', // Remove this line if you prefer inline source maps
                moduleFilenameTemplate: path.relative(bundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
            })
        ] : [
            // Plugins that apply in production builds only
            new webpack.optimize.UglifyJsPlugin(),
            new ExtractTextPlugin('site.css')
        ])
    }];
};

Update webpack.config.vendor.js

Remove bootstrap and jQuery from the vendor: [ section

Update App.vue

  • Delete everything inside /ClientApp except components/App.vue.
  • Change App.vue to something like this:
<template>
       <div>
           <h1>Hello world</h1>
           <p>
               Welcome {{ message }}
           </p>
       </div>
   </template>

<script>
export default {
    name: 'app',
    data () {
        return {
            message: "Mystery customer #3123123"
        } 
    }
}
</script>

Update the entry point JS file

  • Delete tsconfig.json
  • Rename ClientApp/boot.ts to boot.js.
  • Change boot.js so it looks like this:
import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

const routes = [
];

new Vue({
    el: '#app-root',
    router: new VueRouter({ mode: 'history', routes: routes }),
    render: h => h(require('./components/App.vue'))
});

Tidy up the MVC views

They have some broken JS files for development.

Now run dotnet run

Updating webpack vendor file

The template doesn't do this automatically, also some libraries are broken.

  1. yarn remove extract-text-webpack-plugin
  2. yarn add mini-css-extract-plugin

Update the webpack config files:

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const bundleOutputDir = './wwwroot/dist';

module.exports = (env) => {
    const isDevBuild = !(env && env.prod);
    const extractPlugin = new MiniCssExtractPlugin({filename: `site.css` });

    return [{
        stats: { modules: false },
        context: __dirname,
        resolve: { extensions: [ '.js' ] },
        entry: { 'main': './ClientApp/boot.js' },
        module: {
            rules: [
                { test: /\.vue$/, include: /ClientApp/, loader: 'vue-loader' },
                { test: /\.css$/, use: [ { loader: MiniCssExtractPlugin.loader }, "css-loader" ] },
                { test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
            ]
        },
        output: {
            path: path.join(__dirname, bundleOutputDir),
            filename: '[name].js',
            publicPath: 'dist/'
        },
        plugins: [
            extractPlugin,
            new webpack.DefinePlugin({
                'process.env': {
                    NODE_ENV: JSON.stringify(isDevBuild ? 'development' : 'production')
                }
            }),
            new webpack.DllReferencePlugin({
                context: __dirname,
                manifest: require('./wwwroot/dist/vendor-manifest.json')
            })
        ].concat(isDevBuild ? [
            // Plugins that apply in development builds only
            new webpack.SourceMapDevToolPlugin({
                filename: '[file].map', // Remove this line if you prefer inline source maps
                moduleFilenameTemplate: path.relative(bundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
            })
        ] : [
            // Plugins that apply in production builds only
            new webpack.optimize.UglifyJsPlugin(),
            new ExtractTextPlugin('site.css')
        ])
    }];
};

webpack.config.vendor.js

const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = (env) => {
    const isDevBuild = !(env && env.prod);
    const extractPlugin = new MiniCssExtractPlugin({filename: `vendor.css` });

    return [{
        stats: { modules: false },
        resolve: { extensions: [ '.js' ] },
        entry: {
            vendor: [
                'event-source-polyfill',
                'isomorphic-fetch',
                'vue',
                'vue-router',
                'ant-design-vue'
            ]
        },
        module: {
            rules: [
                { test: /\.css$/, use: [ { loader: MiniCssExtractPlugin.loader }, "css-loader" ] },
                { test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, use: 'url-loader?limit=100000' }
            ]
        },
        output: { 
            path: path.join(__dirname, 'wwwroot', 'dist'),
            publicPath: 'dist/',
            filename: '[name].js',
            library: '[name]_[hash]'
        },
        plugins: [
            extractPlugin,
            new webpack.DefinePlugin({
                'process.env.NODE_ENV': isDevBuild ? '"development"' : '"production"'
            }),
            new webpack.DllPlugin({
                path: path.join(__dirname, 'wwwroot', 'dist', '[name]-manifest.json'),
                name: '[name]_[hash]'
            })
        ].concat(isDevBuild ? [] : [
            new webpack.optimize.UglifyJsPlugin()
        ])
    }];
};

Finally, run webpack --config webpack.config.vendor.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment