Update 2015-12-11
At about the same time this post was originally written, Mads Kristensen released the WebPack Task Runner extension. This post has been modified to reflect the new situation.
tl;dr
Developing ReactJS apps with an ASP.NET Web API back-end is not entirely straightforward. Most ReactJS apps use webpack to build and bundle the app and it’s also very convenient to leverage the hot module replacement abilities of the Webpack dev server. Visual Studio has no native support for webpack, but with the WebPack Task Runner or NPM Script Task Runner extensions it’s possible to integrate webpack with Visual Studio without the need to use the command-line.
An example solution can be found at https://github.com/martijnboland/VSReact.
These days, I mostly do front-end development with text editors and command-line tools. However, in some situations, especially when front-end and back-end are relatively tied together and the back-end is built with ASP.NET Web API, I find it more convenient to also use Visual Studio for front-end development because constantly switching between editors makes my head hurt.
Visual Studio 2015 and the front-end
With Visual Studio 2015, Microsoft has made a shift towards the use of more open-source tooling for front-end development. JavaScript packages are now managed via Bower instead of NuGet and the server-side bundling (System.Web.Optimization) is replaced with Gulp or Grunt. Perfect for front-end JavaScript wouldn’t you say?
ReactJS and its ecosystem
When developing apps with ReactJS and Visual Studio, you could try to keep using Bower and Gulp/Grunt but it’s hard to find good guidance. Almost the entire ReactJS ecosystem uses NPM instead of Bower and webpack instead of Gulp/Grunt. Do yourself a favor and go with the flow. NPM works fine and is probably already the number one package manager for the browser. Webpack is a bundler for scripts and static assets where Grunt/Gulp are task runners that can be configured with plugins to do the bundling. You can not say that one is better than the other(s) because they serve a slightly different purpose. Let’s just use NPM and webpack.
One issue though: how do we integrate webpack and NPM in Visual Studio? Luckily, NPM is already supported in Visual Studio 2015. No visual tooling like ‘Manage Bower Packages’ but editing the package.json file is easy with autocomplete for packages and versions and Visual Studio automatically installs the packages that are newly added or missing. That still leaves webpack.
Running webpack from Visual Studio
We want to use webpack to bundle our JavaScript files and static assets, but webpack also comes with a very nice embedded webserver for development that serves the bundles and watches for changes. After saving a file, bundles are automatically recreated and served. On top of that, webpack has hot module replacement support that replaces code in a running app in your browser.
Normally you’d execute webpack from the command line and this is still possible, but wouldn’t it be great if opening the Visual Studio solution also starts the webpack development server and you can start everything with a single F5?
Since version 2015, Visual Studio has the ‘Task Runner Explorer’. Default it comes with support for Grunt and Gulp and you can link tasks to events like ‘Opened Project’ and ‘After Build’.
The Task Runner Explorer can be extended and this is great because we now have two extension options to integrate webpack in Visual Studio.
WebPack Task Runner extension
This extension makes webpack integration super easy. The webpack configuration file (webpack.config.js) is automatically detected after opening the Task Runner Explorer (and it even detects alternative config files for different environments):
In the above example, the ‘Serve Hot’ task is bound to ‘Project Open’, in other words, when opening the Visual Studio Solution, the webpack dev server is started with hot module replacement enabled.
NPM Scripts Task Runner extension
An alternative for the WebPack Task Runner extension is the NPM Scripts Task Runner extension. Compared to the WebPack Task Runner extension, this extension is probably a little bit more flexible because you have to specify the webpack command line parameters yourself.
The extension allows us to execute the commands from the scripts section of the NPM package.json file:
"scripts": { "start": "webpack-dev-server --port 3000 --config webpack.config.js --hot --content-base build --progress --colors", "build": "webpack --config webpack.config.js --progress --profile --colors", "prod": "webpack -p --config webpack.prod.config.js --progress --colors"
start: run the webpack dev server with hot module replacement enabled
build: run webpack to create bundles with the default configuration
prod: run webpack to create optimized production bundles
The Visual Studio Task Runner Explorer:
You can see that the ‘start’ script is executed when the project is opened, which in our case means starting the webpack dev server with hot module replacement.
A complete solution
In the intro I mentioned ASP.NET Web API. Often, a Visual Studio solution consists of at least one web project for the client application and static assets and another ASP.NET Web API project as the back-end.
On GitHub, you can find an example solution (https://github.com/martijnboland/VSReact) that has these projects. It’s the well known TodoMVC app with an ASP.NET Web API backend.
VSReact.Api is the ASP.NET Web API project and VSReact.Web is the ReactJS app. Normally you would set both projects as startup projects, but in this case, VSReact.Web should not be started because the webpack dev server is already running and serving the client files.
A special note: the VSReact.Web is still based on an empty ASP.NET project although there is zero ASP.NET in it. This is mainly to keep Visual Studio happy and enable the Task Runner Explorer.
For a true ‘hit F5 and run’ experience we have to do one last thing: point the start URL of the VSReact.Api project to the webpack dev server, in our case http://localhost:3000/index.html. Then, when you hit F5 or CTRL+F5, the API project builds and runs, but the browser opens nicely with the client app:
To run the example solution, you’ll need the following prerequisites:
- Visual Studio 2015
- NodeJS 4.0 or higher
- WebPack Task Runner or NPM Scripts Task Runner
Credits
The VSReact.Web project is a copy of the example React + Redux + DevTools project and the VSReact.Api project is copied from https://github.com/mforman/todo-backend-webapi. Both with small modifications for the integration. Thanks to the original authors for the examples.
Pingback:The week in .NET - 1/19/2016 - .NET Blog - Site Home - MSDN Blogs
Pingback:The week in .NET – 1/19/2016 | TRIFORCE STUDIO
You are running two dev web-servers in this setup: IISExpress to host WebAPI and web-pack server to host web-pages. You could have client app & assets in WebAPI project and IISExpress also supports hot replacement. What do you achieve with two projects, better isolation, be able to deploy independently and easier swap back-end?
Better isolation. The web project is set up just like any other webpack-react project and can still be developed without visual studio. I strongly think that api development and client development should be separate because there is a physical boundary between these two (the network).
Besides that, I don’t think you can do hot module replacement with IISExpress just like with the webpack server. Like editing a js file and immediately see the changes reflected in the browser without losing any state
Hello… I have just this very same problem. I need to develop a react app, with webpack and all the usual stuff but I’m bound to use a .net backend. This seems promising, just one question.. do i need to set up any extra hooks to run webpack scripts for deploy or i can just use the webpack extension for VS…?
To make a deployment package, you can use the webpack task runner extension in VS with ‘Run – Production’ and an optional production webpack config file, see also the example project (webpack.prod.config.js, the output goes to the /dist folder).
For build server scenarios, it good to know that you don’t need Visual Studio. Just use the webpack or npm command line tools directly.
Pingback:주간닷넷 2016년 1월 19일 - Korea Evangelist - Site Home - MSDN Blogs
How do you set up IIS EXPRESS with hot module replacement?? Didn’t know it was possible! Do you have any links or demo github repository of doing this? I’d love to be able to use webpack with hmr and IIS!
Oh its not possible to do HMR with IIS express? =( I got excited for a second. Yet another reason why Node wins in my book =/
Great code sample. I’m more familiar with TypeScript than Babel for VS/React projects.I’ve never seen the double colon syntax used. What is it’s purpose?
It’s a shortcut for bind(), see https://github.com/zenparsing/es-function-bind. You could write it as this.handleDoubleClick.bind(this) and its purpose is to bind ‘this’ to make sure that ‘this’ really represents the component in the handleDoubleClick function.
Thank you for this great post! Being a little bit spoilt by the previous Visual Studio Experience (New Project -> F5 and it just runs) i’m a bit overwhelmed by the lots of different little tools and options, Web Development outside the Microsoft Universe offers. So i’m wondering if, when using the Webpack Development Server – is it still possible to do Full Client-to-Server Debugging within Visual Studio? I only saw i can debug the webpacked Javascript Output but this is not what i want as i would like to debug the original Source. Is there an option to omit this packing for Development purposes? Could i still run this Project with IIS Express only? Thank you for your help!
I think full client-to-server debugging in VS is not possible. However, when using the chrome debugger, it is still possible to debug the original sources but these are a little bit hidden in the webpack://. section. Webpack also has a number of ‘devtool’ options to determine if and how sourcemaps are generated.
Are there any advantages to using React with Visual Studio this way vs. using ReactJS.NET?
Yes, you don’t need the extra NuGet packages and it still allows you to develop the client ReactJS apps with only the command-line tooling without Visual Studio.
I guess that if you want to do server-side rendering with .NET, ReactJS.NET is the better option though.
Good. That’s what I was thinking too. Thanks again for this great article. It’s been very helpful for a JavaScript/React novice like me. 🙂
Hi Martijn,
Great article and very helpful github project. They helped me a lot on the journey to getting React to work with ASP.NET.
I wanted to say that I could NOT get the webpack watch to work on your project (or mine either). In the end I found this StackOverflow answer which fixed it.
I assume you didn’t have any problems, but I certainly did. Just in case any others have problems then worth knowing this trick.
I’m afraid the link doesn’t work. Curious what problem you ran into.
Fixed the link. Its about using the OldWatchingPlugin plugin.
Thanks for sharing Jon. Indeed, I did not run into this issue, but it’s good to know this can happen.
Has anybody got this working with ASP.NET 5/ASP.NET Core? I want to be able to develop in VSCode on my Mac/OSX (and other platforms)? Do all the tools work?
This blog is explicitly about Visual Studio. When using VSCode, I’d just use the command-line tooling.
i had this issue but i added –content-base ./ to the startup command
“start”: “webpack-dev-server –config webpack.config.js –content-base ./ –hot –progress –colors”
got this from: https://webpack.github.io/docs/webpack-dev-server.html#content-base
Better use the react-aspnet-boilerplate template for ASP.NET Core, React and server-side rendering.
https://github.com/pauldotknopf/react-aspnet-boilerplate
ReactJS.NET does too much magic for what little it should be doing.
Check the react-aspnet-boilerplate. https://github.com/pauldotknopf/react-aspnet-boilerplate
Hi there! Can you provide some docs for running my react+webpack project in production mode? I ran the webpack.prod.config.js, and it dumped a bundle inside “/dist”. But what do I do after that? Also, do I have to change localhost:3000 to something else in project properties? Thanks for the awesome tutorial though! It has saved me a lot of time 🙂
The bundle is just a static website that you can upload to your production environment or even run directly from the filesystem.
Thank you for the prompt response. I have some queries. What is the best way to server that static website? I’m sorry, I’m completely new to .NET environment. Do I create a new project that serves these static files inside VSReact solution? In node, I’d create an express server to serve these files. Also, why am I not able to see “build”, “dist”, “bin”, “node_modules” folders inside VSReact.Web project tree? Is there something like .gitignore thing working behind the scenes?
I can’t find the link to go to the step by step instructions of this tutorial
I’m not sure I understand the question. What link do you mean?
Where is the tutorial? You know…lesson 1, lesson 2 etc..
There is no tutorial. This is just a blog post.