Search code examples
vue.jswebpackmodernizrvue-cli

webpack-modernizr-loader loader with Vue CLI 3


I am in the middle of transferring a project from an older version of Webpack and Vue.js to Vue cli 3, which is working well, except I am having trouble figuring out how to get an additional loader to work. The loader is 'webpack-modernizr-loader', which loads modernizr and allows me to check if a user's browser can do promises and other modern JavaScript features.

My old webpack.config.js looks something like this:

var path = require('path')
var webpack = require('webpack')

module.exports = {
  entry: './src/main.ts',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js'
  },
  module: {
    rules: [
     ...
      {
        loader: 'webpack-modernizr-loader',
        options: {
          options: [
          ],
          'feature-detects': [
            'test/es6/promises',
            'test/audio/webaudio',
            'test/websockets'
          ]
        },
        test: /empty-alias-file\.js$/
      }
    ]
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      modernizr$: path.resolve(__dirname, './empty-alias-file.js')
    }
  },
  ...
}

With Vue cli 3 I have a vue.congfig.js file, and am unsure how to get the above translated into it. So far my most recent attempt looks like this:

var path = require('path')

module.exports = {
  ... 
  configureWebpack: {
    module: {
      rules: [
        {
          loader: 'webpack-modernizr-loader',
          options: {
            options: [
            ],
            'feature-detects': [
              'test/es6/promises',
              'test/audio/webaudio',
              'test/websockets'
            ]
          },
          test: /empty-alias-file\.js$/
        }
      ]
    },
    resolve: {
      alias: {
        'vue$': 'vue/dist/vue.esm.js',
        modernizr$: path.resolve(__dirname, './empty-alias-file.js')
      }
    }
  }
}

But that is not working. I would love a point in the right direction or an example of existing code that does something similar.

Thanks!


Solution

  • After a few hours of trying to fix this myself I ended up with this:

    1. Make sure your config is named .modernizrrc (without .js), otherwise you will get all kinds of errors.
      If I had to guess; this is probably related to it being included by babel incorrectly, and could be evaded by excluding the file somehow).

    2. Make sure you have webpack-modernizr-loader and modernizr installed.

    main.js

    import modernizr from 'modernizr'; // eslint-disable-line no-unused-vars
    

    I actually don't use modernizr in the JS code yet, but I had to include it to get the classes to render into the HTML element. That is why it is unused (and the line is disabled in eslint).

    vue.config.js:

    const path = require('path');
    process.env.VUE_APP_VERSION = require('./package.json').version;
    
    module.exports = {
      baseUrl: '/',
      configureWebpack: {
        resolve: {
          extensions: ['.js', '.vue', '.json'],
          alias: {
            '~': path.resolve(__dirname, 'src/'),
            '@': path.resolve('src/'),
            modernizr$: path.resolve(__dirname, '.modernizrrc'),
          },
        },
      },
      chainWebpack(config) {
        config.module
          .rule('vue')
          .use('vue-loader')
          .loader('vue-loader')
          .tap(options => ({
            ...options,
            compilerOptions: {
              ...options.compilerOptions,
              preserveWhitespace: true,
            },
          }));
        config.module
          .rule('modernizr')
          .test(/\.modernizrrc$/)
          .use('webpack-modernizr-loader')
          .loader('webpack-modernizr-loader');
      },
    };
    

    .modernizrrc

    (The arrays are shortened for the sake of this answers length)

    module.exports = {
        "minify": true,
        "options": [
          "mq",
          ...
          "prefixed",
        ],
        "feature-detects": [
          "test/css/all",
          ...
          "test/css/animations",
        ]
    }