Troubleshooting problem related to configuration conflicts in terser-webpack-plugin parameters

I am facing an issue with my Terser configuration, causing the compressed version of my page to break. The problem arises from functional declarations in my index.js that need to be accessible from Bootstrap modal windows loaded at a later time.

For instance, in my index.js, there is a function declared as follows:

function doThis() { }

Imagine a user opens an address form in a modal window, loading a different JavaScript file called 'address-form.js'. In this form, there is a button with an onclick handler calling doThis(). While the button works fine in uncompressed index.js, it throws an error after compression stating that doThis() does not exist.

This seems to be a scoping issue, possibly due to doThis() being wrapped in parentheses within index.js. I am uncertain how to elevate the scope of doThis() to the top-level window without significant tinkering with the large file containing numerous function declarations and variables.

Changing the function declaration to an expression appears to solve the problem:

window.doThis = function() {
}

However, altering the scopes of all variables, consts, lets, and functions in the extensive file is impractical for ensuring compression works effectively.

This snippet outlines my webpack.config.js:

const TerserPlugin = require("terser-webpack-plugin")
const glob = require('glob')
const path = require('path')
const webpack = require('webpack')

module.exports = {
  entry: glob.sync('./js/Pages/*.js').reduce((object, element) => {
    object[path.parse(element).name] = element
    return object
  }, {}),
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, './js/Pages/minified')
  },
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        parallel: true,
        test: /\.js(\?.*)?$/i,
        terserOptions: {
          mangle: false,
          compress: true,
          keep_fnames: true,
          keep_classnames: true,
          ie8: false,
          safari10: false,
          toplevel: false
        }
      })
    ]
  },
  plugins: [
    new webpack.optimize.LimitChunkCountPlugin({
      maxChunks: 1
    })
  ]
}

The command I execute is:

webpack --mode=production --config webpack.config.js

SOLUTION

The accepted solution involves using terser-cli directly. I have created a script running terser on every file in a directory for anyone who may find it beneficial:

const fs = require('fs')
const path = require('path')
const exec = require('child_process').exec;
const Terser = require('terser')
const srcDir = '../js/Pages'
const destDir = '../js/Pages/minified'


function minifyPagesDir() {
  let srcFileNames = fs.readdirSync(srcDir).filter(path => path.match(/\.js$/)) || []
  let srcFilePaths = []
  
  let destFilePaths = srcFileNames.map((item, i) => {
    srcFilePaths[i] = `${srcDir}/${srcFileNames[i]}`
    return `${destDir}/${item}`
  })

  if (!fs.existsSync(destDir))
    fs.mkdirSync(destDir)
  
  srcFileNames.forEach((item, i) => {
    exec(
      `terser ${srcFilePaths[i]} -c -o ${destFilePaths[i]} --ecma 2021`,
      (error, stdout, stderr) => {
        if (error !== null)
            console.log(`RUHROH: ${error}`, ' stderr: ', stderr);
      }
    )

    console.log(`Minified '${srcFilePaths[i]}' to '${destFilePaths[i]}'!`)
  })
  console.log('Minification complete!')
}

minifyPagesDir()

Answer №1

After creating a repro project with the provided configuration, it has been confirmed that the issues faced are not due to terser but rather caused by webpack.

A test file was utilized as follows:

function doThis() { }

When minimize is disabled and no minimizer is set, building the test file with webpack yields the following output:

/******/ (() => { // webpackBootstrap
var __webpack_exports__ = {};
function doThis() { }
/******/ })()
;

Upon reformatting and omitting comments, it becomes evident that all content within the file is considered dead code. Webpack acts as a bundler and encapsulates everything within an IIFE, preventing functions from being placed in the global scope.

(() => {
  var __webpack_exports__ = {};
  function doThis() { }
})();

As there are no exports or side-effects such as assigning to window, terser rightly eliminates the content. This outcome would persist even without removal, as webpack's function output does not reach the global scope, rendering it inaccessible to handlers. Terser's compression of webpack's export through the CLI results in an empty file.

Executing the terser CLI directly on the test input file generates the desired compressed result:

function doThis(){}

If running terser via the command line led to the same difficulties experienced during bundling and compression via webpack, it is crucial to ascertain whether you ran terser on the source files or webpack's output. Utilizing terser on the source files should yield the expected output. Attempt running

terser foo/bar.js -c -o foo/bar.min.js
to determine if it resolves the issue.

For implementation with webpack, it is essential to either assign to window or shift away from using the global scope entirely.

Answer №2

Recently, I stumbled upon a new feature in webpack called the IIFE option. https://webpack.js.org/configuration/output/#outputiife

However, one downside is that it always includes unnecessary code like var __webpack_exports__ = {}.

I am currently unsure of how to remove this redundant code and would appreciate any insights or solutions on this matter.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Implementing Google Ads Code in NextJS for Automated Units

I'm currently working on a NextJS project and I need to integrate the Google AdSense code for automatic ads. The Google ad code I have is: <script async src={`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${process.env. ...

three.js canvas, sphere rotates gracefully to the right

Trying to get the sphere to turn right at a very slow pace. Here is my source code: I have created a new container with canvas inside, you can view the code below. How can I make the sphere turn slowly? You can also check out my git repository on github: s ...

Utilizing Salesforce and DocuSign: A guide to automatically filling in the recipient of my envelope through DocuSign with the contacts from my records

In my Salesforce work, I'm currently customizing the Quote object. The default button labeled "Send with DocuSign" is already included on the Quote layout. My goal is to automatically populate the recipient of the DocuSign envelope with the contact(s) ...

Can the image quality be improved gradually while zooming in on Safari Mobile?

Are there any JavaScript or jQuery plugins available that can improve the quality of large images when zooming, similar to Google Earth or Maps? I'm looking for a solution that works well in mobile browsers, but a desktop version would also be accept ...

Configuring JWT with Next.js and NextAuth seems to pose a challenge

Setting up JWT with NextAuth has been a bit of a challenge for me. I've been scouring GitHub posts and doing research, but haven't found much help. It seems like there's an error occurring when NextAuth tries to decode the JWT payload. All I ...

I am encountering difficulty loading a .gltf file for use with Three.js on my React website

I uploaded my .gltf file of a 3D model to the public folder of my project and then ran the command "npx gltfjsx filename" to convert it into a .js React component. Within that .js file, I included the following line: const { nodes, materials } = useGLTF(&a ...

Struggling to set up a Node three.js website on a server, looking for guidance on the process

I am encountering an issue with uploading my files to the public_html folder on the server. The application consists of an HTML file, a three.js JavaScript file, and other supporting files. To run the application, I need to type "npm i" and then "npm run d ...

What is the quickest way to find and add together the two smallest numbers from a given array of numbers using JavaScript?

const getSumOfTwoSmallestNumbers = (numbers) => { const sortedNumbers = numbers.sort((a, b) => a - b); return sortedNumbers[0] + sortedNumbers[1]; } I encountered this challenge on Code Wars. My function to find the sum of the two smallest num ...

Mongoose Express: Limiting increments to a maximum of 5

Currently, the essential functionality implemented is 1 click = 1 vote. The system successfully updates a vote parameter in MongoDB and increments it as expected. However, after approximately 5 votes, the incrementing process halts. Upon refreshing the bro ...

A solution for Array.includes to handle NaN values

While browsing some Javascript blogs, I stumbled upon the Array prototype methods .indexOf and .includes. I noticed that if an array includes NaN as a value, indexOf may not be able to detect it, leaving us with the option of using .includes. However, cons ...

Generating an image id upon click in ReactJS

Below is the code designed to showcase a collection of images on a webpage with React JS: this.displayedImageList = this.imageResults.map(function(picture){ return <div className="galleryBox" key={picture.toString()}><img src={picture} alt="I ...

getting a variable outside the onClick function in react components

Having trouble retrieving a list from the onClick function. If anyone has a solution, please help. You can find my full code here let abe = [] const click = (e) => { const cityy = e.target.value const checkUsername = obj => obj.city === cit ...

"Utilize a pre-defined parameter in a function and pass it to the handleSubmit function

Within my component called "MyEditDataForm," I have a redux-form where I pass a submit handling function like this: const myHandleSubmit = ({ firstInputFieldName, secondInputFieldName }) => { console.log(firstInputFieldName); console.log(secondInput ...

What steps should I take in order to ensure that NPM commands run smoothly within Eclipse?

I have a functional workflow that I'm looking to enhance. Currently, I am developing a JavaScript library and conducting smoke tests on the code by using webpack to bundle the library and save it to a file that can be included in an HTML file for test ...

The onChange event of the dropdownlist in MVC is not functioning correctly and is not properly triggering the action

Hey everyone, I'm trying to achieve a functionality where changing the selection of a dropdown list will trigger an AJAX call to a specific action with some data being passed. Below is the code I have implemented for this purpose. Despite verifying th ...

Reconfigure the Node application using Express to seamlessly access modules through route files

I recently created a basic app using npm express. After generating the app.js file, I attempted to add new modules but encountered an issue where I couldn't access them in the route files. For example, when trying to utilize the 'request' mo ...

Jade not binding correctly with Angular.ErrorMessage: Angular bindings are

Struggling with simple binding in Angular and Jade. I've tried moving JavaScript references to the end of the document based on advice from previous answers, but still no luck. Any ideas on what might be wrong? File: angular.jade extends layout blo ...

Tips for advancing to the next line in NodeJS

Today, I have just set up the Firebase NodeJs authentication trigger to send a welcome email when a user signs up for the first time. Below is an index.js file from the official documentation but with some modifications. const APP_NAME = 'Incredible ...

Switch the URL to render the view using Express 4

I am facing an issue with a post request where the views are rendering to /link/123 instead of /anotherlink. Although I could use res.redirect('/anotherlink'), I need to render different data. app.post('/link/:id',function (req, res, n ...

What is the process for extracting a nested document from an array of documents in mongodb?

I am currently facing a challenge in my project where I need to remove a nested objects array within a document. The specific scenario involves searching for the days on which an event will be held, based on its event ID. const { eventid, typesOfTicketId ...