title: Can I remove Grunt from my webapp and only use Webpack?
body: <p>My &quot;older&quot; web application uses Grunt and Webpack, but I am wondering if I can remove Grunt completely and still have the same functionality with just Webpack? Or should I replace Grunt with another technology?  I've noticed grunt development slow to a crawl, and as new security warnings arise, I am having difficulty upgrading packages.</p>
  <p>Below is my grunt file which performs a few basic tasks and allows me to run some very handy commands like &quot;grunt dev&quot; (for packaging dev bundle), &quot;grunt dev-watch&quot; (for packaging and watching for changed files), and &quot;grunt prod&quot; (for production bundle).  Additionally, I use maven to build my web application, so I can define these commands from within the pom.xml depending on the build profile (development vs production)</p>
  <p>Below: Grunt file, Webpack (common), and Webpack (dev)</p>
  <p>gruntfile.js</p>
  <pre><code>/**
   * Grunt Settings
   *
   * Contains settings for Grunt tasks that allow for development and production environments
   *
   * Usage (in bash shell, /webapp directory):
   *      grunt dev
   *      grunt dev-watch
   *      grunt prod
   */
  
  // Define webpack configuration files
  const webpackConfig_dev  = require('./webpack.dev.js');
  const webpackConfig_prod = require('./webpack.prod.js');
  
  module.exports = function(grunt) {
  
      let baseDir = &quot;.&quot;;
  
      // Set fileVersion from command line arguments
      let fileVersion = grunt.option('fileVersion');
      if (typeof fileVersion === 'undefined') {
          fileVersion = 'dev';
      }
      fileVersion = fileVersion.trim();
  
      grunt.initConfig({
  
          // Identify which packages to load
          pkg: grunt.file.readJSON('package.json'),
  
          // Remove old files
          clean: {
              build: {
                  src: [
                      // js files
                      baseDir + '/js/dist',
                      // css files
                      baseDir + '/styles/*.css',
                      baseDir + '/styles/*.map',
                  ]
              }
          },
  
          // Crunch style files (eg *.scss)
          sass: {
                  options:{
                      implementation: require('node-sass'),
                      sourceMap: true,
                      outputStyle: 'expanded'
                  },
                  dist: {
                      files: [{
                          src: baseDir + '/styles/main.scss',
                          dest: baseDir + '/styles/main.' + fileVersion + '.css',
                      }]
                  }
          },
  
          // Modifications after main.css is created
          postcss: {
              options: {
                  map: true,
                  processors: [
                      require('autoprefixer')
                  ]
              },
              dist: {
                  src: baseDir + '/styles/main.' + fileVersion + '.css'
              }
          },
  
          // Copy jquery external library to the dist/ folder
          copy: {
              main: {
                  files: [
                      {
                          expand: true,
                          cwd: 'node_modules/jquery/dist',
                          src: 'jquery.min.js',
                          dest: baseDir + '/js/dist'
                      },
                  ],
              },
          },
  
          // Run webpack (depending on development versus production)
          webpack: {
              dev:  webpackConfig_dev(fileVersion),
              prod: webpackConfig_prod(fileVersion),
          },
  
          // Enable live reloading of js/scss files
          watch: {
              css: {
                  files: [baseDir + '/styles/**/*.scss'],
                  tasks: ['sass']
              },
              js: {
                  files: [baseDir + '/js/src/**/*.js', '!' + baseDir + '/js/src/**/*.min.js'],
                  tasks: ['webpack:dev']
              }
          }
      });
  
      grunt.loadNpmTasks('grunt-sass');
      grunt.loadNpmTasks('grunt-postcss');
      grunt.loadNpmTasks('grunt-contrib-copy');
      grunt.loadNpmTasks('grunt-webpack');
      grunt.loadNpmTasks('grunt-contrib-watch');
      grunt.loadNpmTasks('grunt-contrib-clean');
  
      // Available Grunt tasks
  
      // development
      grunt.registerTask('default',   ['dev']);
      grunt.registerTask('dev',       ['clean', 'sass', 'postcss', 'copy', 'webpack:dev']);
  
      // development (and watches for changes of .js and .css files)
      grunt.registerTask('dev-watch', ['sass', 'postcss', 'webpack:dev', 'watch']);
  
      // production ready
      grunt.registerTask('prod',      ['clean', 'sass', 'postcss', 'copy', 'webpack:prod']);
  };
  </code></pre>
  <p>webpack.common.js</p>
  <pre><code>/**
   * Webpack settings file :: Common (development &amp; production)
   */
  
  const ESLintPlugin = require('eslint-webpack-plugin');
  
  const baseDir_js = &quot;./js&quot;;
  
  module.exports = {
  
      // Define the &quot;source&quot; entry point for the application (or sub apps)
      entry: {
          main:       baseDir_js + '/src/index.js',
          admin:      baseDir_js + '/src/admin.js',
          sysAdmin:   baseDir_js + '/src/sysAdmin.js',
      },
  
      // Let grunt know we have external libraries available
      externals: {
          jquery: 'jQuery',
          google: 'google',
          Stripe: 'Stripe',
      },
  
      module: {
          rules: [
  
              // process css files
              {
                  test: /\.css$/,
                  use: [ 'style-loader', 'css-loader' ],
              },
  
              // process images/fonts -&gt; base64
              {
                  test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|svg)(\?[a-z0-9=.]+)?$/,
                  type: 'asset/inline',
              }
          ],
      },
  
      plugins: [new ESLintPlugin()],
  
  };
  </code></pre>
  <p>webpack.dev.js</p>
  <pre><code>/**
   * Webpack settings file :: Development
   */
  
  // Import common settings
  const {merge} = require('webpack-merge');
  const common = require('./webpack.common.js');
  
  const baseDir_js = &quot;./js&quot;;
  const path = require('path');
  
  // Merge settings with &quot;common&quot;
  module.exports = (fileVersion) =&gt; merge(common, {
      mode: 'development',
  
      // Use full source map
      devtool: 'inline-source-map',
  
      // Output entire code base to one file
      output: {
          filename: '[name].' + fileVersion + '.js',
          // store in &quot;dist/&quot; directory
          path: path.resolve(baseDir_js, 'dist'),
      },
  
  });
  </code></pre>