Adding WebPack to an MVC website
This post covers setting up js and css bundling in a boilerplate Asp.net MVC project (not core).
1 - Setup NPM
This step installs webpack and configures it to build an empty javascript file.
- Open Terminal window for the web project
npm init -y
npm install webpack webpack-cli --save-dev
-
create an empty
app.js
in the scripts folder, assuming the MVC project convention for script location. The location isn’t too important, you just need somewhere to put your scripts. - create
webpack.config.js
- Replace the
scripts
section in the package.json file with the following:
npm run dev
will do a development build of the scripts, and watch for any changesnpm run build
will do a production build of the scripts
This will now run a build and create dist/bundle.js
. It will be empty as there’s no javascript in app.js
.
Webpack Config Documentation Webpack CLI Documentation
2 - Bundling in 3rd party libraries
This step removes the default javascript bundling for the default libraries (jQuery and bootstrap). They are then re-added via NPM and included in the script created by webpack.
- Remove the jquery, jqueryval and bootstrap javascript bundles from
App_start/BundleConfig.cs
and_Layout.cshtml
. Any css bundles can be left in place for the moment. - Add a script reference to
dist/bundle.js
in the_Layout.cshtml
npm install jquery jquery-validation bootstrap@3 --save
(MVC projects have bootstrap 3 by default)- Add the following to the
app.js
:
- Add the following to the webpack.config.js. This is required to handle the setup of the jQuery globals so that they can be used in scripts
Provide Plugin example for jQuery Using Bootstrap with Webpack Note: This is using different versions of webpack/bootstrap and doesn’t match exactly
3 - Dev/Production Configs
This step splits the webpack configuration to allow for different options for production and development
- Rename
webpack.config.js
towebpack.common.js
- npm install webpack-merge –save-dev
- create
webpack.dev.js
- create
webpack.production.js
- Update scripts section of
package.json
to:
Webpack production config guide Webpack-merge plugin
4 - Bundling CSS
This step includes the site CSS in the webpack process, and shows two different ways that it can be bundled. The two ways this can be done are inclusion in the loaded javascript module, or output as a seperate file. For this I’ve opted for bundling into the module for dev and creating a seperate file for the css bundle in production.
npm install css-loader file-loader style-loader mini-css-extract-plugin optimize-css-assets-webpack-plugin --save-dev
mini-css-extract-plugin
extracts the the css to it’s own fileoptimize-css-assets-webpack-plugin
minifies the css
- Remove the style bundle from the BundleConfig.cs
- Replace the bundle reference in
_Layout.cshtml
with a refernce todist/styles.css
- Add imports for styles into the
app.js
- Update
webpack.common.js
to handle the font and image assets referenced in the styles:
- Update
webpack.dev.js
to bundle in the styles
- Update
webpack.prod.js
to generate a seperate bundle file for the css
css-loader style-loader file-loader mini-css-extract-plugin Webpack docs for mini-css-extract-plugin
5 - Injecting script names
Webpack can inject the names of the files it generates into a html (or cshtml) file. This allows the use of dynamic files names based on the file hash or compile time to ensure that the client is loading the latest scripts. This example just inserts into the body or head of the template, but it is possible to define specific locations for insertion: Custom Insertion
- Rename
_Layout.cshtml
to_Layout_Template.cshtml
(This does create the risk of another developer editing the wrong file) - npm install html-webpack-plugin –save-dev
- Add the plugin configuration to
webpack.common.js
html-webpack-plugin Webpack docs for html-webpack-plugin
Step 6 - Adding an AngularJs application
- Install AngularJs npm install angular@1.7.8
- Create
app.module.js
in the same directory asapp.js
. This allows us to import the module into other javascript files.
- Create
scripts/controllers/homeController.js
- Add into
Views\Home\Index.html
, so that it appears on the home page
- Import the controller script into the
app.js
. It is also possible to create a file specifically for things like controller imports ie.app.controllers.js
, then import that inapp.js
;