Showing posts with label c#. Show all posts
Showing posts with label c#. Show all posts

Sunday, February 26, 2017

Configuring React in Visual Studio 2015 / ASP.NET Core with Webpack and NodeJs/Typescript tools

So I haven't blogged in a while...or much ever to be honest...but it looks like it's been 6 years...yikes! Guess its time for a new post.

I'm working on a side project and decided to use React for the front end. My project is an ASP.NET Core Web Application running against .NET framework. It wasn't too hard to get react working initially. First I added it as a Bower package, referenced the react.js files in my Layout view, added a couple of NPM packages for Babel and React and configured a gulp task to transpile my JSX files into javascript.  Took and hour or two to figure it all out but it worked. Not too bad to get a Hello World up and running.

BUT BUT BUT then I tried to split up my React components and import/export them as modules and this is where everything went to hell. My code still compiled with Gulp, but i got an error in the browser.

require is not defined

OK. I realized I needed to use a module loader to get this thing working the way I want and split up my components. Now let me preface this post by saying I don't have a lot of experience with Gulp or Babel or Webpack or Node or Browserify or Grunt or any of the other 5,000 front end Javascript precompilation/bundling/task running programs. But it wasn't to hard to get React up and running, it shouldn't be too hard to get the modules working either, right? Wrong.

It took me about 2 days of absolute frustration to get the JSX files working in Visual Studio the way I wanted. My hope here is to save someone else the time, as there seems to be little on the web about getting React working correctly in Visual Studio.

First let me tell you what didn't work. I tried to get the modules working using Gulp since that is what is already running by default in my project. There may be a way to do this...but I couldn't figure it out. I tried using some Browserify and Rollup plug-ins and some other stuff in my Gulp script to no avail. The documentation on this stuff is sparse and there are 500 npm packages and plugins that might or might not work or are deprecated, and for most of them I couldn't find a good recipe that worked how I wanted with my project.

I also tried using Typescript TSX files. I wasn't too keen on this as the tsx syntax is a little different like forcing you to use a generic version of React.Component with a Typescript interface. Frankly I just wanted to use the vanilla syntax, and even though it kind-of worked for a simple file i was still getting strange errors on the import statements in the text editor. I tried every possible combination of settings in the typescript config file to no avail. So, this is how I finally got everything playing nicely.

Step 1

Make sure you have the following two Visual Studio extensions installed. These packages will give you better intellisense and tooling for your javascript coding.  I'm not entirely sure both are required to make this work, but I couldn't get some of the module errors to go away until I had them installed and started using the respective editors.

Node JS Tools for Visual Studio

Typescript for Visual Studio 2015

Step 2

Next go to Tools -> Options -> Text Editor -> File Extension and set .jsx files to use the TypeScript editor. This is the only way I could get the module import/export errors to disappear in the text editor. I also set my js files to use the Node editor.



Step 3

Were going to use Webpack to build the JSX files and do the module loading. The thing is...there is no webpack support in the default Core Web App project so we have to add everything manually. The wonderful article below helped me get over the hump, although its not specific to .NET so I had to tweak a couple of things.

Setting up React with Babel and Webpack

I installed Webpack with

npm install -g webpack@2.1.0-beta21

Why not use the latest version? Well...I tried that initially and maybe it will work with the configuration in the tutorial link above, but it did NOT work with some other examples I found such as this one. Apparently there are breaking changes in the latest version of Webpack that conflict with several of the configs I found online. So feel free to try the latest version at your own risk, but 2.1.0-beta21 worked for me so I'm sticking with that for now.

Step 4

Add the following npm packages to your package.json file. Also "path" if its not already there. These will be used by Webpack. (I just add these in my package.json but you can use the command line as well.)

npm i babel-loader babel-preset-es2015 babel-preset-react -S

Step 5

Create a webpack config in your root project directory. This file is called

webpack.config.js

I configured mine as follows. In my root web project directory I added a folder called "app" and one below that called "components" for my React components. I also added an "app" folder in wwwroot. This configuration will build "./app/index.jsx" to ".'wwwroot/app/bundle.js".

var path = require('path');
 
var BUILD_DIR = path.resolve(__dirname, 'wwwroot/app');
var APP_DIR = path.resolve(__dirname, 'app');
 
var config = {
    entry: APP_DIR + '/index.jsx',
    output: {
        path: BUILD_DIR,
        filename: 'bundle.js'
    },
    module : {
        loaders : [
            {
                test : /\.jsx?/,
                include : APP_DIR,
                loader : 'babel'
            }
        ]
    }
};
 
module.exports = config;

Step 6

Add a file called .babelrc in the root projectd directory. This is the babel configuration. I used the following code from the tutorial linked above.

{
  "presets" : ["es2015""react"]
}

Step 7

Create your JSX files. At this point you have a couple of options since module loading is now set up. One is you can just add script references to React to your HTML from the wwwroot/lib folder from a Bower install. Then you just have to import other React components to your JSX files.  Make sure you give a relative path to your other JSX components as they aren't NPM installs and otherwise Webpack will not know where to look.




The other option is to install the React NPM packages and then import the React and ReactDOM modules into your JSX files. The libraries will be compiled out to your bundle.js files and then you don't need the react script references or the Bower install.



Step 8

Open a command prompt and navigate to your project directory. Run the Webpack command below. This will build your JSX to a bundle.js file in wwwroot.

>webpack -d

Step 9

Add the bundle.js file to your HTML.

@section Scripts
{
    
    
    <script src="~/app/bundle.js"></script>
   
}

Step 10

Run your project. Boom! Your React app should be up and running!

Conclusion

At this point you would have to run the webpack build every time you change a JSX file which is a little annoying. However the React tutorial shows how to set up a watch with NPM to get it to auto-build on file changes.

Let me know if this doesn't work for you or if you have any other suggestions. I'm still not getting any JSX intellisense, but at least I'm not getting build errors. I would love to know how to get this working with Gulp so that I only have to deal with one task runner. Below is a screenshot of my package.json to show the versions I am using in my project. If this setup doesn't work for anyone happy to edit the post or see if I can help diagnose the issue.






















Thursday, July 23, 2009

The breakpoint will not currently be hit. No symbols have been loaded ... CHECK YOUR PROCESSES!

Ok its been a while since i posted on this blog but i'm going to try and start doing better. It doesn't help that the web filter at my new job blocks the blogger.com site. By the time i get home my thoughts seem to dissipate as i take care of my 18 month old till bedtime. Anyway...

So today i got the infamous "The breakpoint will not currently be hit." message in my project. To be specific, the project I'm working on is an n-tier enterprise app containing some C# interop user controls that are gradually replacing the functionality in an older VB6 application. Basically when debugging i would run the VB6 application, attach the the VB6.exe process from visual studio 2008, and break in the user control as needed.

Well, two days ago i started getting the "No Symbols" error. I tried all the solutions that you will find when googling the problem: deleting bin directories, rebuilding the project, playing with configuration properties etc etc. Basically crossing my fingers and praying it would go away. But it didnt.

Research led me to discover the "Modules" window, which is available from the debug menu when debugging. This is where it gets interesting. The modules window, as you will find discussed in many blog posts and forums, shows if the debug symbols have been successfully loaded for your assemblies. It also allows you to load symbols manually and see what location items are being loaded from. The problem is, the dlls i was trying to break in weren't even in the modules window. How do i get them there??

What i came to realize (and this may be apparent to veteran programmers, but it wasn't to me) is that the Modules window shows all of the assemblies that are loaded into the processes that visual studio is attached to. I needed to see exactly what assemblies were loaded as i was running my project, so i downloaded the Process Explorer app from Technet (link below). This handy tool lets you select a running process and view all of the assemblies in that process. Sure enough i booted up VB6, ran the tool, and my project assemblies weren't there!

This is when the light came on in my dense skull. How could the VB6 run my interop controls if it hadn't loaded the assemblies?? It couldn't. Once i clicked on the form containing the controls, my project dlls showed up in the process explorer window. It wasn't loading the assemblies until they were needed. Once the process had the right dlls loaded, i could attach to VB6 from visual studio and set the breakpoints. (Important to note, if you have this similar issue you must detach and reattach the debugger for it grab the just loaded dlls.) Furthermore, once the assemblies are loaded the first time you can start and re-start the VB6 project and they will remail loaded.

You may notice a similar issue if you are running a web or WCF service locally while debugging. When i started working on the project i could set a break anywhere, but once i started having this issue, i had to manually go in and attach to the WCF service to set breaks in the bottom tiers. I've yet to figure out exactly what changed that started the whole "No Symbols" problem, and i probably won't pursue it at this point...i'm just happy to be able to finish my work.



http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx