Adding React to ASP.NET Core with Webpack & Typescript
- Posted by Jamie Sangerman
- On September 5, 2019
- 0 Comments
This blog post will cover, in detail, how to add React support to a ASP.NET Core web application with Webpack and Typescript. If you’re working with .NET 4.X instead of .NET Core, take a look at this post.
The full source code for this post is available on GitHub.
Starting Point
This blog post assumes you already have a .NET Core web app that you want to add react support to. If you don’t then you can create a new .NET Core app by following these steps:
- Open Visual Studio IDE (We use Visual Studio Community 2019)
- Choose File > New > Project
- Find the “ASP.NET Core Web Application” option.
- Be sure to select the “Web Application (Model-View-Controller)” template type.
You may notice these steps to be quite similar to those outlined in our last post, but with a few modifications. Ultimately, these directions should work with any .NET Core project.
Make sure that you have Node and NPM installed. If not, download it from here.
Installing Packages
In order to use reactjs.net in this application, we need to add a few packages from nuget. The packages you should add are:
React.AspNet
JavaScriptEngineSwitcher.ChakraCore
JavaScriptEngineSwitcher.ChakraCore.Native.win-x64
JavaScriptEngineSwitcher.ChakraCore.Native.win-x86
JavaScriptEngineSwitcher.Extensions.MsDependencyInjection
Modifying Startup.cs
to Use React
In addition to installing the package, we also need to modify Startup.cs
to initialize reactjs.net in our project. Navigate to Startup.cs
, located in the root directory of the project.
Directly above the line starting with services.AddMvc()
, add the following snippet of code:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddReact();
services.AddJsEngineSwitcher(options => options.DefaultEngineName = ChakraCoreJsEngine.EngineName)
.AddChakraCore();
Then, directly above the line of code app.UseStaticFiles();
, add the snippet:
app.UseReact(config =>
{
config
.AddScript("~/dist/runtime.js")
.AddScript("~/dist/vendor.js")
.AddScript("~/dist/components.js");
});
In order to use these methods, you’ll want to make sure you have the following using statements at the top of this file:
using JavaScriptEngineSwitcher.ChakraCore;
using JavaScriptEngineSwitcher.Extensions.MsDependencyInjection;
using React.AspNet;
Finally, we add the following snippet to the beginning of Views/_ViewImports.cshtml
:
@using React.AspNet
Add Webpack Support
In order to support Webpack, you’ll need to install it in your project. Open a terminal window and navigate to the directory of your .NET Core project. From there, run the following commands to install webpack.
npm init -y
npm install webpack --save-dev
npm install webpack-cli --save-dev
In Visual Studio, include the package.json and package-lock.json files that were added by the above commands in your project. To do so, right click the project and select Add > Existing Item and select these two files.
In Visual Studio add a new file to your project called “webpack.config.js”. Copy the following code into the webpack config file:
const path = require('path');
module.exports = {
entry: {
components: './wwwroot/react/expose-components.ts',
},
output: {
filename: '[name].js',
globalObject: 'this',
path: path.resolve(__dirname, 'wwwroot/dist'),
publicPath: 'dist/'
},
mode: "production",
optimization: {
runtimeChunk: {
name: 'runtime', // necessary when using multiple entrypoints on the same page
},
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
name: 'vendor',
chunks: 'all',
},
},
},
},
module: {
rules: [
{
test: /\.ts(x?)$/,
exclude: /node_modules/,
use: [
{
loader: "ts-loader"
}
]
},
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{
enforce: "pre",
test: /\.js$/,
loader: "source-map-loader"
}
]
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
}
};
To add support for the loaders from this config, in your terminal window, run the following commands:
Open the package.json file and replace the “scripts” section with the following:
npm install ts-loader source-map-loader --save-dev
"scripts": {
"build": "webpack --config webpack.config.js",
"watch": "webpack --watch --config webpack.config.js"
},
Add Typescript Support
In order to include Typescript support in your application, open a terminal window and navigate to your project folder. Within the project folder, execute the following command:
npm install typescript --save-dev
From within Visual Studio, create a new file in your project called “tsconfig.json” and add the following configuration:
{
"compilerOptions": {
"noImplicitAny": false,
"module": "commonjs",
"target": "es6",
"jsx": "react",
"esModuleInterop": true,
"types": [ "./types" ],
"lib": [ "es2015", "dom" ]
},
"include": [ "./wwwroot/react/**/*" ]
}
From within Visual Studio create a new folder in your project called “types” and within that folder add a file called “index.d.ts”. Paste the following code into the index.d.ts file:
import _React from 'react';
import _PropTypes from 'prop-types';
declare global {
const React: typeof _React;
const PropTypes: typeof _PropTypes;
}
Install the type definitions for react by opening a terminal window in your project directory and running the following command:
npm install --save-dev @types/react
In order to get Typescript checking on build, you’ll need to modify your project file. In Visual Studio, right click the project and choose “Unload Project”. Make sure to save any pending changes. Right click the unloaded project again and choose “Edit xxx.csproj”.
Below the reference to the <Project> element on the first line, add the following build target:
<Target Name="Typecheck" AfterTargets="AfterBuild">
<Exec WorkingDirectory="$(MSBuildProjectDirectory)" Command="node_modules/.bin/tsc" />
</Target>
Right click the unloaded project again and choose load project.
Add a React Component
You are now ready to add your first react component. First add references to react and react-dom by opening your project folder in a terminal window and running the following:
npm install react react-dom --save
In your project > wwwroot directory, add a new folder called “react”. Within this new directory, create a file called “expose-components.ts” and add the following code:
import React from "react";
import ReactDOM from "react-dom";
import ReactDOMServer from "react-dom/server";
declare var global: any;
global["React"] = React;
global["ReactDOM"] = ReactDOM;
global["ReactDOMServer"] = ReactDOMServer;
Add a new folder for your component under Project > wwwroot > react called “testComponent” and within that folder add a file called “test.tsx”.
You could write any react component you like here, but for simplicity sake we’ll just create a text box and paragraph that echos what we input. Place the following code in test.tsx:
import * as React from "react";
export class Props { }
export class State
{
name:string
}
export default class TestComponent extends React.Component<Props, State>{
constructor(props) {
super(props);
this.state = { name: ""}
}
handleChange = (ev) => {
this.setState({ name: ev.target.value });
}
render() {
return (
Hello, {this.state.name}!
);
}
}
Modify the expose-components.ts file you created earlier to export this component as well. Modify it to look like this:
import React from "react";
import ReactDOM from "react-dom";
import ReactDOMServer from "react-dom/server";
import TestComponent from "./testComponent/test";
declare var global: any;
global["React"] = React;
global["ReactDOM"] = ReactDOM;
global["ReactDOMServer"] = ReactDOMServer;
global["TestComponent"] = TestComponent;
For any additional components we’d like to add in the future, we would follow these same steps.
Add the React Component to a View
The final step is to add the react component to an MVC view. For the simple case, we’re just going to add the component to the Home/Index view but you could put it anywhere.
In the view, wherever you want the component to be rendered, add the following code:
@Html.React("TestComponent", new { })
At the bottom of the view, add the following lines:
http://~/dist/runtime.js http://~/dist/vendor.js http://~/dist/components.js <!-- Render the code to initialise the component --> @Html.ReactInitJavaScript()
Test Your Work
To test that your integration worked, first open a terminal window pointed at your project directory. Within the terminal, execute the following code:
npm run watch
This will create a build of your react component and watch the files for any changes. If there are any errors at this step resolve them before moving on.
Start your project from within Visual Studio with or without debugging. Navigate to the view where you added your react component and if everything worked out, you’ll see a textbox that you can modify and a <p> tag that updates as you change the input.
Wrapping Up
This can obviously get a lot more complicated, and in a real world application it would. You can follow just about any React paradigm that you’re used to, to continue from here. You can add packages and reference them, you can create sub-components and just about anything else you’d like.
The one thing to keep in mind is that any other top level components you add, be sure to expose them in your expose-components.ts file.
Once again, if you’re interested in the source code for this post, take a look at our Github repository.
If you have any custom software development needs, reach out to us. We’d love to hear about what you’re working on and see if we can help!
0 Comments