Why does changing configureWebpack in vue.config.js to use an arrow function instead of an object break the configuration?

Viewed 23

I have the following vue.config.js file:

const fs = require('fs');
const util = require('util');
const webpack = require('webpack');
const CopyPlugin = require('copy-webpack-plugin');
const path = require('path');
const vtkChainWebpack = require('vtk.js/Utilities/config/chainWebpack');
const packageJson = require('./package.json');

const stat = util.promisify(fs.stat);

module.exports = {
  devServer: {
    port: 8081,
    public: process.env.PUBLIC_ADDRESS,
  },
  lintOnSave: false,
  publicPath: process.env.VUE_APP_STATIC_PATH,
  configureWebpack: {
    devtool: 'eval-source-map',
    plugins: [
      new CopyPlugin({
        patterns: [
          {
            from: path.join(__dirname, 'node_modules', 'itk'),
            to: 'itk',
            filter: async (resourcePath) => {
              const resourceStats = await stat(resourcePath);
              const resourceSize = resourceStats.size;
              return resourceSize <= (25 * 1024 * 1024);
            },
          },
        ],
      }),
      new webpack.DefinePlugin({
        'process.env': {
          VERSION: JSON.stringify(packageJson.version),
        },
      }),
    ],
    performance: {
      maxEntrypointSize: 4000000,
      maxAssetSize: 40000000,
    },
  },
  chainWebpack: (config) => {
    vtkChainWebpack(config);
  },
};

It provides an object for configureWebpack. I've tried changing it to use an arrow function like so:

configureWebpack: config => {
  config.devtool = 'eval-source-map';
  config.plugins = [
    new CopyPlugin({
      patterns: [
          {
            from: path.join(__dirname, 'node_modules', 'itk'),
            to: 'itk',
            filter: async (resourcePath) => {
              const resourceStats = await stat(resourcePath);
              const resourceSize = resourceStats.size;
              return resourceSize <= (25 * 1024 * 1024);
            },
          },
        ],
      }),
      new webpack.DefinePlugin({
        'process.env': {
          VERSION: JSON.stringify(packageJson.version),
        },
      }),
    ];
    config.performance = {
      maxEntrypointSize: 4000000,
      maxAssetSize: 40000000,
    };
  },
  chainWebpack: (config) => {
    vtkChainWebpack(config);
  },
};

When I run npm run serve (same as vue-cli-service serve) it starts webpack but then seems to hang indefinitely without displaying any of the usual messaging regarding bundling.

If I eventually try visiting the site it throws an error about being unable to parse a param for the favicon.ico. What am I missing? Thanks!

2 Answers

To answer your problem i took your code and tried to see what was not working, first of all don't forget that vue.config.js is an object who will be merged into the final webpack config using webpack-merge.

So when you do config.plugins = [] you try to override the plugins Array of webpack with his default configuration such as

VueLoaderPlugin CaseSensitivePathsPlugin FriendlyErrorsWebpackPlugin etc...

So when you do that they don't exist anymore so the loader to detect the paths understand vue files and all of it is gone so this is why you getting an error.

Remembering you choosed to use configureWebpack as a function you now need to treat as i said the plugins key as an array and push your new plugins into it or override directly the needed plugins by searching the one needed if it doesn't fit with what you want

Example who works with your configuration:

  configureWebpack: config => {
    console.log("configureWebpack", config.plugins)
    config.plugins.push(
     new webpack.DefinePlugin({
       'process.env': {
         VERSION: JSON.stringify(packageJson.version),
       },
     }),
    )
  }

Or

  configureWebpack: config => {
    console.log("configureWebpack", config.plugins)
    config.plugins = [
     ...config.plugins,
     new webpack.DefinePlugin({
       'process.env': {
         VERSION: JSON.stringify(packageJson.version),
       },
     }),
    ]
  }

Second part of the problem and maybe i'm mistaken

In your new CopyPlugin it seems you are copying a plugin named itk what i'm guessing is equal to vtk ? Maybe it's a miss spelling or a typo error so when i tried to change it to this:

        new CopyPlugin({
          patterns: [
            {
              from: path.join(__dirname, 'node_modules', 'vtk.js'),
              to: 'vtk',
              filter: async (resourcePath) => {
                const resourceStats = await stat(resourcePath);
                const resourceSize = resourceStats.size;
                return resourceSize <= (25 * 1024 * 1024);
              },
            },
          ],
        }),

It worked perfectly !

Related