ASP.NET Core + Webpack + React

By EGO Angel 4 weeks agoNo Comments
code

Prerequisites

Stuff that you need to start development:

For creating asp.net core you need to install all this stuff first.

To create a new project, open terminal or console and type

dotnet new web -o webpacktest

To navigate to this folder click File — Open Folder. And then select folder, where you project was created.

After you navigate to a folder, open a terminal at top panel and type

dotnet run

This will launch your app and you will have this at terminal

Hosting environment: Development
Content root path: C:\Users\esukhomlyn\webpacktest
Now listening on: https://localhost:5001
Now listening on: http://localhost:5000
To launch your website, enter http://localhost:5000 at Browser and , this is your website.

Adding MVC stuff to use it for some basic View

public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseMvc(routes => {
routes.MapRoute(
name: “default”,
template: “{controller=Home}/{action=Index}/{id?}”
);
});
app.Run(async (context) =>
{
await context.Response.WriteAsync(“Hello World!”);
});
}
}

After this, we need to create a controller for our page. In our case it’s Home.

On the root folder — create Controllers folder and there create the file — HomeController.cs.

Here is code for the controller

using System;
using Microsoft.AspNetCore.Mvc;
namespace alchemylab.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
}

After this create Views folder, with subfolder Home and Index.cshtml in it.

Here is code for this file

<html>
<head>
<title>Home</title>
</head>
<body>
<h2>Hello world</h2>
<div id=”root”></div>
</body>
</html>

Your project structure should be like this now

Example

Now just restart a website via dotnet run to take a look if all is great.

Javascript: Dependencies and Modules

As next step let’s add our first bit of javascript, we will keep it super simple at first. In the wwwroot folder create a folder called source.

In this folder create two files app.js

let element = document.getElementById(‘root’);
message(element, ‘hello again!’);

and message.js

function message(element, text) {
element.innerHTML = text;
}

Now we need to update our View with this code, adding references to our .js files

<html>
<head>
<title>Home</title>
</head>
<body>
<h2>Hello world</h2>
<div id=”root”></div>
</body>
<script src=”~/source/app.js”></script>
<script src=”~/source/message.js”></script>
</html>

Now your project structure is looking like this

Example2

Try to reload our View in the browser and open Developers Console

You will see this error

Screen

This is because message.js is coming after app.js.

Just swop the order and all will be ok.

There are many ways to get around this issue of having to ensure that files are added in the correct order. One would be to use javascript Modules (ES6 feature).

First, let’s export the message function from the message.js file. Update your message.js file

export default function message(element, text) {
element.innerHTML = text;
}

Now import the message function into your app.js file

import message from ‘./message.js’;
let element = document.getElementById(‘root’);
message(element, ‘hi back!’);

And then update your View

<html>
<head>
<title>Home</title>
</head>
<body>
<h2>Hello world</h2>
<div id=”root”></div>
</body>
<script src=”~/source/app.js” type=”module”></script>
</html>

Installing Webpack and setting it up

In order to support the older browsers that don’t support ES6 Modules, we can use tools such as Webpack that enable (among many other things) bundling of javascript files. Webpack can interpret the import and export commands and package our files into one javascript file.

Create the package.json file in the root folder with this code

{
“name”: “webpacktest”,
“version”: “1.0.0”,
“scripts”: {
“build”: “webpack”
}
}

Open a terminal and install webpack via this command

npm install webpack webpack-cli -D

Now your package.json file looks like this

Example3

Create the webpack.config.js file in the root folder with this code

const path = require(‘path’);
module.exports = {
mode: ‘development’,
entry: ‘./wwwroot/source/app.js’,
output: {
path: path.resolve(__dirname, ‘wwwroot/dist’),
filename: ‘bundle.js’
}
};

As you can see above, we are giving Webpack the entry point, which is our app.js file. As well as telling it where to output the bundled file.

Now we can run Webpack to bundle our javascript files

npm run build

After that, you will see a new file under /wwwroot/dist/ folder.

Update your View with this

<script src=”~/dist/bundle.js”></script>

instead of the old script row.

ES6 and Babel stuffYour header title

Let’s add some ES6 features to our web applicate. Update the message.js file to use literals.

export default function(element, text) {
element.innerHTML = `The message is: ${text}`;
}

After this, run command: npm run build, to re-run webpack and re-generate bundle.

But for IE browser, for example, we have the problem now. It doesn’t understand literals.

So you need to use Babel plugin, here is how to do it with npm

npm install “babel-loader@⁸.0.0-beta.3” @babel/core @babel/preset-env -D

Update webpack with Babel-like this and rebuild the app

module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: ‘babel-loader’,
options: {
presets: [‘@babel/preset-env’]
}
}
}
]
}

Now all are working great.

HMR aka Hot Module Replacement — auto update stuff, coming from webpack

One thing I’m sure you have noticed is that whenever there is a change to a javascript file, you need to re-run webpack and refresh your browser window.

To speed up the development time we can use hot modules to automatically do this for us.

Currently, the web application has been running in production mode, we need it to run in the development mode.

Open the launch.json file and edit this row

“env”: {
“ASPNETCORE_ENVIRONMENT”: “Development”
},

Install client-side packages for hot module reloading via this command

npm install aspnet-webpack webpack-hot-middleware webpack-dev-middleware -D

Now you need to update Startup.cs file

…
using Microsoft.AspNetCore.SpaServices.Webpack;
…
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
…
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true
});
}
…

And change the webpack config to this

Example4

Finally, update your app.js

import message from ‘./message.js’;
let element = document.getElementById(‘root’);

Adding React to our project

First, let’s install the React

npm install react react-dom -D

Then install Babel preset

npm install @babel/preset-react -D

After this, we need to add React preset to Babel. It will convert React (JSX) code to raw JavaScript

presets: ['@babel/preset-react','@babel/preset-env']

Now we can update our message component with React stuff like this

import * as React from 'react';
import * as ReactDOM from 'react-dom';
export default class Message extends React.Component {
constructor(props) {
      super(props);
      this.state = { message: '' };
      this.handleChange = this.handleChange.bind(this);
   }
handleChange(event) {
      this.setState({message: event.target.value});
   }
render() {
      return <div>
      <h3>Message: {this.state.message}</h3>
      Enter message: <input type="text" value={this.state.message} onChange={this.handleChange} />
      </div>;
   }
}

After this, we need to update our app.js file with this code. So the React component can be rendered to DOM

import React from 'react';
import ReactDOM from 'react-dom';
import Message from './message';
ReactDOM.render(
   <Message />,
   document.getElementById('root')
);
module.hot.accept();

Now Debug app and you will see, that all are working great

Done

You can find all source code at this repo.

Hope you’ll find this guide helpful. Best of luck in your future projects!

Eugene

Eugene Sukhomlyn
.NET Developer
EGO Creative Innovations

Category:
  Development
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...
this post was shared 0 times
 000

Leave a Reply

Your email address will not be published.