javascriptwebpackvuejs2promiseuglifyjs

UglifyJsPlugin : Uncaught (in promise) TypeError: Assignment to constant variable


Context

Webapp build with webpack (framework used is vuejs, from a quick look that's not relevant here)

When webapp is in dev mode, no error thrown. When webapp is in production mode (built) an error is thrown : Uncaught (in promise) TypeError: Assignment to constant variable

In store's action.js file

import Axios from 'axios';

let isError404 = function(error){
    return (
        error.status === 404 ||
        error.toString().includes('Request failed with status code 404')
    );
};

export default{
    async remoteGet (context, {url, config={}){
        return this.axios.get(url, config).catch(async (err) => {
            const error = err.response;
            if (isError404(error)) {
                return 'error'
            }
        } 
    } 
}

Quick analyse

The error seems occurs when following function is called in a get with axios.

let isError404 = function(error){
        error.status === 404 ||
        error.toString().includes('Request failed with status code 404')
}

The error does not occur anymore when this code is replaced by

const isError404 = (error) => {
        error.status === 404 ||
        error.toString().includes('Request failed with status code 404')
}

Do you have any idea why the error occurs in first place ?

EDIT : When isError404(error) is declared like : let isError404 = function(error){ ...

I don't have an error if I console.log(isError404(error)) before the if.

It seems after searching on the net that error could be cause by the package "uglifyjs-webpack-plugin": "^1.1.1", but I don't know how I can test and be sure.

Edit 2 : Webpack 3.12.0

'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const outputFile = 'fundation-app-vuejs'
const globalName = 'fundation'

const env = process.env.NODE_ENV === 'testing'
  ? require('../config/test.env')
  : require('../config/prod.env')

const webpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true,
      usePostCSS: true
    })
  },
  devtool: config.build.productionSourceMap ? config.build.devtool : false,
  output: {
    path: config.build.assetsRoot,
    filename: outputFile + '.browser.js',
    library: globalName,
    libraryTarget: 'umd',
  },
  externals: [
    'axios',
    'element-ui',
    'email-validator',
    'generate-password',
    'moment',
    'schwartz',
    'v-lazy-image',
    'v-runtime-template',
    'vue',
    'vue-markdown',
    'vue-moment',
    'vue-resource',
    'vue-router',
    'vuex',
    'vuex-persistedstate',
    /^element-ui\/lib\/.*/
  ],
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new UglifyJsPlugin({
      uglifyOptions: {
        compress: {
          warnings: false
        }
      },
      sourceMap: config.build.productionSourceMap,
      parallel: true
    }),
    new webpack.HashedModuleIdsPlugin(),
    new webpack.optimize.ModuleConcatenationPlugin(),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'app',
      async: 'vendor-async',
      children: true,
      minChunks: 3
    }),
  ]
})

if (config.build.productionGzip) {
  const CompressionWebpackPlugin = require('compression-webpack-plugin')

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  )
}

if (config.build.bundleAnalyzerReport) {
  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig

Solution

  • I found the origin of the error : https://github.com/mishoo/UglifyJS/issues/2843

    Explanation :

    If I understand the problem UglifyJsPlugin (1.1.1) uses a version of UglifyJS which create the error when reassigning a constant with itself.

    This is caused when inline options is true (by default in this version).

    Until package update the easiest workaround is to set uglifyJsPlugin's inline option to false in webpack configuration :

        new UglifyJsPlugin({
          uglifyOptions: {
            compress: {
              warnings: false,
              inline: false,
            }
          },
          sourceMap: config.build.productionSourceMap,
          parallel: true
        }),