Web-pack Task Runner Explorer is used to compile and bundle the JS files, whereas NPM Task Runner Explorer is used to install/update the dependencies packages.
This is required when you want to install/update 3rd party packages in the application manually. The “package.json” file is used to save the packages list and working with the Node.js and NPM. In this file, you may add the dependencies so the package name and version look like the following manner:
“devDependencies”: {“PackageName”: “VersionNumber”}
How Web-Pack Works
Let's see the following situation.
- End-User: Eva, I like your T-Shirt. Where did you get this? I want to buy one.
- Eva.js: John gifted me this one.
- End-User: Okay, talk to John and ask him where he got it.
- Eva.js: Hey John, last Christmas, from where did you buy the T-Shirt that you gave me?
- John.js: I have bought it from ABC store at IN.
So, the end-user sends one more Http-requests to get the expected result. This means that there is a dependency graph where Eva.js calls John.js. Now if you want to merge both of these JS files into one bundle, then a single http-request is okay to find the file. So, you need the Web-Pack to make those bundles. You can concat, minify and/or uglify your JS files using the Web-Pack. (Concatenation is appending all of the files into one large file; Minification is removing unnecessary whitespace and character without changing the functionality; Uglification is converting the code in such a format that it will be difficult to understand.)
Why Need Web-Pack Task Runner?
In short, considering the above situation we can say that you need the Web-Pack Task Runner to compile and bundle the JS files.
The "webpack.config.js" file pulls all of the configuration and has an entry point to bring all of the JS files configuration to where the bundler starts. Then it uses output to get the path and file name configuration to generate the bundle.
- module.exports = {
- entry: { app: './wwwroot/js/app.js' },
- output: {
- publicPath: "/dest/js/",
- path: path.join(__dirname, '/wwwroot/dest/js/'),
- filename: '[name].bundle.js'
- }
- }
Integrating Vue.JS with ASP.NET Core MVC Web Application
Project Creation
Assuming that you can create a new project “ASP.NET Core Web Application>Web Application (Model-View-Controller)”. If you don’t want to use the default jQuery library, then you can remove the files and folder from the “wwwroot>lib”, although this is optional.
Template Design
You can modify the default site.css and site.js file according to your requirements.
Adding Bootstrap into the App.js file of the project
Within the "wwwroot/css" directory, I added the app.css file for the CSS. Within the "wwwroot/js" directory, I added the app.js file to register the “Bootstrap” plugin to use material icons. I ended up with the following:
- import $ from 'jquery';
-
-
- import 'bootstrap-material-design/dist/css/bootstrap-material-design.min.css';
- import 'bootstrap-material-design/dist/js/bootstrap-material-design.min.js';
- import 'material-design-colors/dist/material-design.min.css';
-
-
- import '../css/app.css';
-
-
- $(document).ready(function () {
- $('body').bootstrapMaterialDesign
- $('[data-toggle="popover"]').popover
Note: I add this file just for an example. In this project, I avoid the design/material-icon and focus on the configuration.
Adding NPM Packages into the package.json
You may need Vue, babel, WebPack, bootstrap etc. packages. Babel is a JavaScript transpiler that compiles and converts old ES5 JavaScript to make browser compatible. All of the packages are saved into the “package.json” file. Now you can install/update these packages using Package-Manager-Console or Task Runner Explorer. For example, I added some packages and ended up with the following:
- {
- "name": "HR.App.Web",
- "version": "1.1.1",
- "private": true,
- "devDependencies": {
- "babel-core": "^6.26.3",
- "babel-loader": "^7.1.5",
- "babel-preset-env": "^1.7.0",
- "babel-preset-es2017": "^6.24.1",
- "bootstrap": "^4.1.3",
- "bootstrap-material-design": "^4.1.1",
- "css-loader": "^1.0.0",
- "fuse.js": "^3.2.1",
- "jquery": "^3.3.1",
- "material-design-colors": "^1.0.2",
- "style-loader": "^0.19.0",
- "uglifyjs-webpack-plugin": "^1.3.0",
- "url-loader": "^0.6.2",
- "vue": "^2.6.10",
- "vue-loader": "^15.4.2",
- "vue-template-compiler": "^2.5.17",
- "webpack": "^4.20.2",
- "webpack-cli": "^3.1.1",
- "webpack-dev-server": "^3.1.9"
- },
- "dependencies": {}
- }
If you want to install/update the packages from the package.json file using NPM Task Runner Explorer, then make use of the NPM Task Runner Explorer. If you don’t see the Task Runner Explorer, then select the Package.json and click on the right button of the mouse. Now from the Task Runner Explorer, select the install from the package.json and click on the right button of the mouse as shown in the below image. As a result, all of the packages will be installed.
The WebPack configuration and bundling the JS files
The Web-Pack Task Runner automatically triggers when it finds webpack.config.js file. The file ends up with following:
- "use strict";
- const { VueLoaderPlugin } = require('vue-loader');
- const path = require('path');
- const webpack = require('webpack');
- const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
-
- module.exports = {
- entry: {
- app: './wwwroot/js/app.js',
- home: './Views/Home/Index.cshtml.js',
- errorDetail: './Views/Home/ErrorDetail.cshtml.js'
- },
- plugins: [
- new webpack.ProvidePlugin({
- '$': 'jquery',
- jQuery: 'jquery',
- 'window.jQuery': 'jquery',
- Popper: ['popper.js', 'default']
- }),
- new VueLoaderPlugin()
- ],
-
- optimization: {
- minimizer: [
- new UglifyJsPlugin({
- cache: true,
- parallel: true,
- uglifyOptions: {
- compress: false,
- ecma: 6,
- mangle: true
- },
- sourceMap: true
- })
- ]
- },
- output: {
- publicPath: "/dest/js/",
- path: path.join(__dirname, '/wwwroot/dest/js/'),
- filename: '[name].bundle.js'
- },
- module: {
- rules: [
- {
- test: /\.js$/,
- loader: 'babel-loader',
- exclude: /(node_modules)/,
- query: {
- presets: ['es2017']
- }
- },
- {
- test: /\.css$/,
- loaders: ['style-loader', 'css-loader']
- },
- {
- test: /\.(png|jpg|gif)$/,
- use: {
- loader: 'url-loader',
- options: {
- limit: 8192
- }
- }
- },
- {
- test: /\.vue$/,
- loader: 'vue-loader'
- }
- ]
- },
- resolve: {
- alias: {
- vue: 'vue/dist/vue.js'
- },
- extensions: ['.js', '.vue']
- }
- };
I already explained that on the top we need “Entry” to configure the source of the js files with the path to get the bundle later.
- entry: { app: './wwwroot/js/app.js', home: './Views/Home/Index.cshtml.js'}
Output: This is the configuration of the output path and bundle name of compiled JavaScript files.
- output: { publicPath: "/dest/js/", path: path.join(__dirname, '/wwwroot/dest/js/'),
- filename: '[name].bundle.js'}
If you want to compile and bundle the JS files using web-pack Task Runner Explorer, then make use of the Web-Pack Task Runner Explorer. If you don’t see the Task Runner Explorer, then select the webpack.config.js and click on the right mouse button. From the Task Runner Explorer, select Run in the webpack.config.js and click on the right button of the mouse as shown in the below image. As a result, all of the JS files will be built to the output directory (wwwroot\dest\js).
Why Drop-Zone?
It is easy to drag and drop a file onto it as well as to upload the file to the server. Lightweight JavaScript library and minimum code requires that you use it.
Adding Drop-Zone and configuring it in the JS and view file,
- To install dropzone package, add the dropzone into the devDependencies of the package.json file. "devDependencies": {vue2-dropzone": "2.0.0" }
- If you open the webpack.config.js file then you will find that I already add the JavaScript source file with the path into the entry. entry: {home: './Views/Home/Index.cshtml.js'}
- In this project, find the ‘Index.cshtml’ View page and ‘Index.cshtml.js’ file in the View>Home directory. Open the Index.cshtml and add the dropzone and Javascript bundle file. Once added, you end up with following
In the dropzone,
- url: is used to send the posted file and it requires the path of the controller with the action method (“/Home/SubmitFile”).
- use-custom-dropzone-options: will be true if you want to customize the option; (I add the “useUploadOptions” variable in the Index.cshtml.js file.)
- dropzone-options: here you can customize the maxfiles, maxFileSizeInMB, acceptedFiles, dictDefaultMessage. (Find the “uploadOptions” in the Index.cshtml.js)
- v-on:vdropzone-success: This method is used after successfully uploading the file.
- v-on:vdropzone-error: This method is used if the upload has failed.
The Index.cshtml.js file is used for the Index.cshtml with the bundle named home.bundle.js. You end up with the following:
- import Vue from 'vue';
- import Dropzone from 'vue2-dropzone';
-
- document.addEventListener('DOMContentLoaded', function (event) {
- let view = new Vue({
- el: document.getElementById('view'),
- components: {
- "dropzone": Dropzone
- },
- data: {
- message: 'This is the index page',
- useUploadOptions: true,
- uploadOptions: {
- acceptedFiles: '.png,.jpg,.pdf',
- dictDefaultMessage: 'To upload the file click here. Or, drop a file here.',
- maxFiles: 1,
- maxFileSizeInMB: 20,
- addRemoveLinks: true
- }
- },
- methods: {
- onUploaded: function (file, response) {
- if (response.status === "OK" || response.status === "200") {
- console.log('Successfully uploaded!');
- }
- else {
- this.isVisible = false;
- console.log(response.message);
- }
- },
- onUploadError: function (file, message, xhr) {
- console.log("Message ====> " + JSON.stringify(message));
- }
- }
- });
- });
Go
to the home controller file and add the following code:
- [HttpPost("/Home/SubmitFile")]
- public async Task<ActionResult> SubmitFile(IFormFile file)
- {
- try
- {
-
-
- string webRootPath = hostingEnvironment.WebRootPath;
- string fileLandingPath = Path.Combine(webRootPath, folderName);
-
- StreamReader stream = new StreamReader(file.OpenReadStream());
-
- if (!Directory.Exists(fileLandingPath))
- {
- Directory.CreateDirectory(fileLandingPath);
- }
-
- string filePath = string.Format("{0}\\{1}{2}", fileLandingPath,
- Path.GetFileNameWithoutExtension(file.FileName), Path.GetExtension(file.FileName));
-
- using (var fileStream = new FileStream(filePath, FileMode.Create))
- {
- await file.CopyToAsync(fileStream);
- }
-
- var jsonResult = Json(new { status = "OK" });
- return jsonResult;
- }
- catch (Exception ex)
- {
- return Json(new { status = "Error", message = ex.Message });
- }
- }
Now Select the Web-pack Task Runner to compile and bundle the JS files. Select Run and right click on the mouse button, then you will find the run and Bindings options. Click on the Run. Wait few seconds, and you will get the results in the “wwwroot\dest\js” directory.
Now you are ready to run the application. After running, you will find the following upload control:
Note
In this article, I primarily focus on configuration and setup. So, I didn’t care about the latest version of the packages. You should use the latest version of the packages.