Webpack Visual Studio



Launch Visual Studio. At the start window, select Continue without code. Navigate to Tools Options Projects and Solutions Web Package Management External Web Tools. Search results for 'webpack', Visual Studio on marketplace.visualstudio.com.

Webpack Snippets for VS Code. This extension adds snippets for Webpack configuration file. Type part of a snippet, press enter. Snippets wpstart // Build an empty webpack configuration content. Wprequire // Require webpack lib. Wprex // Require Extract Plugin. Wprule // Add a new loader wpochunk // Generate webpack.optimize.CommonsChunkPlugin code. Wpougf // Generate webpack.optimize. When you save the file, Visual Studio adds the package under the Dependencies / npm node in Solution Explorer. If you don't see the node, right-click package.json and choose Restore Packages. In some scenarios, Solution Explorer may not show the correct status for installed npm packages.

There are quite a bit of web applications built with and still running on ASP.NET Web Forms. Even though it may not be the new shinny toy to play with, there is no reason why Web Forms projects can't leverage some of the latest tools in the front-end development space.

In this post, you'll see how you can integrate webpack into an ASP.NET Web Forms project where we will set it up to transpile and bundle some TypeScript code.

At the time of writing, the current version of webpack is at 3.2.0, TypeScript is at version 2.4.1, and I'm using NodeJS 7.2.1.

I'll be using Visual Studio 2017 with the free Web Essentials 2017 extension installed. If you you're doing any web development in Visual Studio and you haven't checked out Web Essentials yet, go install it now. You'll thank me later. While you're at it, make sure you have a current version of NodeJS installed and available on your path. We're going to start off with a new Web Forms project created using the default template in Visual Studio.

Installing Webpack and TypeScript

Webpack is a NodeJS package so we can install it using npm. If you don't feel like opening up the command line, Web Essentials adds a useful feature that makes installing packages fairly easy. If you use the shortcut SHIFT-ALT-0, it will open a package install dialog that can be used to work with front-end package managers. Just select npm from the drop down and enter the packages you want to install, i.e. webpack. While we're here, let's install the TypeScript package and the ts-loader package too.

Once that's completed, you should notice that a package.json file was added to your project. We'll come back to that later on.

Run Webpack

Let's add some code

There's should be a Scripts folder that got created by default whenever you generated the Web Forms project. Inside that Scripts folder, add two sub folders named src and dist. The src is where the 'raw' TypeScript files are going to go and the transpiled JavaScript will go in dist. If you prefer to keep your TypeScript and JavaScript files together, that's totally fine. I prefer to separate them.

Webpack Visual Studio

We'll add these two simple scripts below.

At the root of the project, we'll also add a TypeScript configuration file (tsconfig.json) that we'll use to tweak the compiler settings. You can use the Add New Item dialog in Visual Studio to create one for you. Here are the settings I'll be using.

Optional Visual Studio 2017 comes with some built in support for TypeScript. Since we're going to be using the version of webpack and TypeScript we installed via npm, you might want to turn the TypeScript build feature off. To do that, simply add a TypeScriptCompileBlocked element to a PropertyGroup in your .csproj file and give it a value of true.

Adding Webpack configuration

By default, webpack will look for a webpack.config.js file in the current directory. Since there's no template for creating the configuration file, we can just add one manually.

Let's break down what's going on in this file.

  • context - This sets the base directory where webpack should look for files. Here we're setting it to the 'Script/src' folder we created earlier.
  • resolve.extensions - This lists the file extensions webpack should use to resolve modules. In our example, we're only looking for .ts files.
  • entry - This specifies the root modules for the application. In our case, main.ts is the root. Since it imports greeter.ts as a dependency, webpack will include both files when generating the bundle.
  • output - Here is where we tell webpack to send the final bundles. If you look at the config above, the bundles will be sent to the Scripts/dist folder. The [name] token in the filename setting will be replaced with the name of our entry point, so we should expect a bundle with a name of main.build.js.
  • module - Out of the box, webpack only knows how to work with JavaScript files. To add support for bundling TypeScript files, we'll need to add a loader. Earlier on we install the ts-loader via npm. Here we'll create a rule that states any .ts files should be loaded with the ts-loader.

The last thing we're going to do to get webpack building the .ts files is to add a simple build script to the package.json file. This file should have been added to the project when we installed the npm packages earlier.

If we were to run npm run build on the command line we should see some output resembling the following screenshot.

With Web Essentials 2017 installed, you can use the ALT-SPACE shortcut to quickly bring up a command prompt in your project directory.

Take a look inside of the dist folder and you should see the bundled main.build.js file. You will have to manually include this file in your Visual Studio project. In the Solution Explorer, enable Show All Files then you can just right-click the file and select Include in Project.

Bundle on build

Having to open a command prompt and run npm run build gets annoying after a while. What we can do instead is add a MSBuild task to have Visual Studio run our webpack build whenever we hit F5.

With this task added to our .csproj file, we'll have the TypeScript and Web Forms code building together.

Registering with the ScriptManager

The Web Forms project templates come with a BundleConfig.cs file that allows you to add mappings for your client side scripts. You can do things like specify the debug file, the production file, or even a CDN path if you have one.

Webpack Visual StudioStudio

We can add the webpack bundled file to the ScriptManager like this like this.

Wait a minute! We never generated a minified version of our bundle. Let's do that now.

Minifying Webpack bundles

Webpack has built-in support for minification, so we just need to turn it on. The way we do this is by adding a plugin called UglifyJsPlugin to the configuration file. Also, let's set this up so that the plugin is only run during release builds.

Here's what the updated webpack.config.js looks like.

The first thing we did was get a reference to the webpacknpm package. Remember, webpack.config.js is just a JavaScript file.

We changed the module.exports assigment from a JavaScript object to a function that returns a JavaScript object. This allows us to accept command line parameters that we'll use to set the build environment.

We added a plugins section to our configuration. Here we're toggling the UglifyJsPlugin on or off based on if we're in production mode or not. We're also doing something similar with the filename setting in the output section.

Next we'll update the package.json file to pass the environment settings to webpack.

We now have two npm build scripts for generating bundles, so we'll have to update the .csproj file too if you want to maintain that F5 experience.

Now you can toggle between Debug and Release mode in Visual Studio, and MSBuild will kick off webpack to create your bundles.

One thing you might notice, is that the MSBuild tasks doesn't run if there haven't been any changes in your .NET code since the last successful build. You can get around this buy just running the npm scripts directly by firing up the command line or you can install the handy NPM Task Runner extension from Mads Kristensen.

Conclusion

ASP.NET Web Forms is still a viable option for creating web applications. In this post you saw how to integrate webpack into your projects. Hopefully you'll take that further and figure out how to incorporate other technologies like VueJS, Aurelia or React.

I work with Microsoft technologies in my day job. I do a lot of ASP.NET MVC related stuff, and I wanted to use React with my ASP.NET MVC application, but I wanted to have a nice development experience. The same I have when using text editors such as Sublime Text and other tools for Node.js.

I also wanted all that inside Visual Studio 2015, which is what I use at work. Not because I have to live inside VS, but because I might have a teammate that want to do so. So here's a description of what I've achieved so far using:

  • Visual Studio 2015 Community Edition (the version I have at home, at work I use the Professional Edition)
  • React
  • Webpack
  • Typescript
  • TSD

First things first, I wanted it to work from Visual Studio because not everybody using Visual Studio is comfortable or even likes to use a console. But in any case, we have to have Node.js installed. That's an easy thing to do so that I won't bother with the details of it.

Next, I have an ASP.NET MVC 5 project, using .NET 4.5. I know, ASP.NET 5 and MVC 6 are just around the corner, but that's not my reality yet and I bet it's not the reality of many people.

So let's get into it.

We're going to install one extension that is called NPM Scripts Task Runner. This extension will allow us to run an NPM task directly from Visual Studio.

Node dependencies

With that in place, we have to install the node extensions we'll be using. First I'll add a package.json file. When adding a new item to the web project, Visual Studio has a template for adding a package.json file, we just have to search for npm and add a new file.

First, I'm going to install react and react-dom. I'll add a dependencies section to the package.json file and add both packages. Another nice thing of VS2015 is that it has intellisense for adding node packages. And once the file is saved the packages are automatically installed.

With that installed, I'm going to install the dependencies needed to use TypeScript with Webpack.

Here's the result of my package.json file:

Webpack

Time to configure Webpack. If you don't know Webpack, here's what it will do for us: it will bundle all of our JavaScript or TypeScript files in a single file, and will transpile the JSX and TypeScript syntax into JavaScript that the browser will understand.

Note: Webpack does a lot more than just that, but this post is not about Webpack.

For that, we need a file called Webpack.config.js in the root of the project. Here's mine:

Here's what this file does:

  • entry: it is, of course, the entry point of the application, in my case, the App.tsx file. If App.tsx depends on other files using import statements, Webpack will bundle those files. I used a string here because I only had one file as an entry point. If you have more than one, you can use an array.
  • output: the path and name of the file that will be generated. That's the file we have to reference in the HTML file.
  • resolve: by default Webpack does no load .ts and .tsx files, we have to tell it to do so.
  • module: here's where we set up the loader responsible for transpiling our code. In this case I'm using ts-loader to transpile from TypeScript to JavaScript.

Now, all that is left to do is to find a way to transpile automatically the tsx files and refresh the page in the browser.

Watch and recompile files

Webpack Visual Studio Typescript

Running the command webpack -w from a console Webpack will launch compile the files and bundle them. The -w option stands for watch meaning that Webpack will watch for changes in my files recompile and rebundle them.

So all I have to do is launch this command from Visual Studio. The way I choose to do that is via an npm command. I'm going to add a script command in the package.json file and launch it from VS2015.

Here's the package.json modified, notice the scripts section:

I added a script called webpack that will run the command webpack -w.

Now, if I right-click the package.json file there will be an option called Task Runner, click that and you'll see the Task Runner Explorer window.

From the Task Runner Explorer window, you can right-click the webpack task and click run.

That will start Webpack and because of the -w option, the tsx files will be automatically compiled whenever they're changed.

TypeScript and typings

Because TypeScript is a typed language, it needs the types of the packages we're using. One way to add the typings for those packages is through nuget. Personally, I prefer to another tool to do that which is TSD.

Webpack Visual Studio Code

One would use tsd via the console, but because my goal here is not to leave Visual Studio, I'll be using another VS extension to add the typings using tsd.

The extension I'm going to install is Package Installer.

With that in place, in the Solution Explorer window, I can right-click the project name and click on Quick Install Package.

Now, I just have to install the React typings. I'll start by selecting TSD on the first option, and then I'll type react-global and I'll leave latest-version as the version I want.

The first time we do that a typings folder and a tsd.json file will be created. We have to include them in the project as this is not done automatically.

That's all there is to it regarding the typings for TypeScript.

Note: I don't know if there's a bug on VS2015, but I had to close the project and reopen it for the changes to take effect.

Vscode Debugging Webpack

Refreshing the page

Visual Studio does not refresh the page automatically when a JavaScript file changes. It only does refreshes portions of the page through the use of BrowserSync when some CSS or styles are changed.

Webpack Task Runner

In any case, Visual Studio does support the command Ctrl + Alt + Enter that will refresh the page, in all browser's that are connected to Visual Studio through BrowserSync.

And then the cycle is complete. We can now make changes to the JavaScript/TypeScript code, and the code will be recompiled, and we can refresh the page without ever taking our hands off the keyboard.