visual-studiowebpackvisual-studio-2015pug-loader

Using Pug with Visual Studio 2015 and Webpack


I am relatively new to using Visual Studio but the project I am working on is a website with multiple pages in .cshtml files. I have set up Webpack as the front end build tool and want to start using Pug as the templating engine. It makes more sense to me to have the build tool compile the Pug templates into HTML and keep my dependencies low, rather than Visual Studio compiling them (using something like PugViewEngine).

Should I create a /pug folder and start re-building the views out there as .pug files with any Razor syntax as plain text - then use Webpack to compile to HTML with a .cshtml file extension and dump it back in the /Views folder of the Visual Studio project - or is there a better way to approach this?


Solution

  • I managed to get this working by utilising html-webpack-plugin, pug-loader and copy-webpack-plugin.

    1) Make sure to require the 2 plug-ins at the top of your webpack.config.js:

    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const CopyWebpackPlugin = require('copy-webpack-plugin');
    

    2) Then have html-webpack-plugin reference your index.pug template in your /src folder:

    plugins: [
      new HtmlWebpackPlugin({
        template: './src/index.pug',
      })
    ]
    

    3) Then have the pug-loader module handle your .pug files:

    module:  {
     rules: [
       {
        test: /\.pug$/,
        use: 'pug-loader'
       }
     ]
    }
    

    4) Then use the copy-webpack-plugin to move the compiled HTML file from your /dist folder into the /Views/ folder that Visual Studio will be refrencing. Change the filename to whatever you please and the file extension to .cshtml:

    plugins: [
     new CopyWebpackPlugin([
      {
       from: 'dist/index.html',
       to: '../../Views/Shared/_layout.cshtml'
      }
     ])
    ]
    

    5) Any razor syntax in your .pug templates you can treat as plain text with the | symbol:

    | @Html.AntiForgeryToken();
    

    There might be a cleaner way to do it but once set up it's pretty straightforward and works for my project now, as we transition to a cleaner front end process.