Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicates Class Definition Leading to "Identifier has already been declared" Error #549

Closed
Nicholas-Westby opened this issue Jan 6, 2020 · 3 comments

Comments

@Nicholas-Westby
Copy link

Bug report

I have this JavaScript class:

/**
 * Manages the "See Inside" tour in the location detail widget.
 */
class Tour {

    /**
     * Constructor.
     * @param {HTMLElement} tourEl The DOM node for the tour element.
     */
    constructor(tourEl) {
        this.element = tourEl;
        this.modal = this.element.closest('[data-js-modal-wrapper]');
        this.listenForModalOpen();
    }

    /**
     * Initializes all the tours on the page.
     */
    static initializeAllTours() {
        let maps = document.querySelectorAll('[data-js-see-inside-src]');
        maps.forEach(x => {
            new Tour(x);
        });
    }

    /**
     * Adds the event listener for when the modal dialog opens.
     */
    listenForModalOpen() {

        // Page speed optimization: only set the "src" once the modal opens.
        this.modal.addEventListener('slideout.open', this.setSrc.bind(this));

    }

    /**
     * Sets the "src" element of the iframe.
     */
    setSrc() {
        let src = this.element.getAttribute('data-js-see-inside-src');
        if (src) {
            this.element.setAttribute('src', src);
            this.element.removeAttribute('data-js-see-inside-src');
        }
    }

}

// Export the class.
export default Tour;

Here's what Terser 4.5.1 turns that into:

class e{constructor(e){this.element=e,this.modal=this.element.closest("[data-js-modal-wrapper]"),this.listenForModalOpen()}static initializeAllTours(){document.querySelectorAll("[data-js-see-inside-src]").forEach(t=>{new e(t)})}listenForModalOpen(){this.modal.addEventListener("slideout.open",this.setSrc.bind(this))}setSrc(){let e=this.element.getAttribute("data-js-see-inside-src");e&&(this.element.setAttribute("src",e),this.element.removeAttribute("data-js-see-inside-src"))}}export default e;

Here's what Terser 4.6.0 turns that into:

class Tour{constructor(e){this.element=e,this.modal=this.element.closest("[data-js-modal-wrapper]"),this.listenForModalOpen()}static initializeAllTours(){document.querySelectorAll("[data-js-see-inside-src]").forEach(e=>{new Tour(e)})}listenForModalOpen(){this.modal.addEventListener("slideout.open",this.setSrc.bind(this))}setSrc(){let e=this.element.getAttribute("data-js-see-inside-src");e&&(this.element.setAttribute("src",e),this.element.removeAttribute("data-js-see-inside-src"))}}export default class Tour{constructor(e){this.element=e,this.modal=this.element.closest("[data-js-modal-wrapper]"),this.listenForModalOpen()}static initializeAllTours(){document.querySelectorAll("[data-js-see-inside-src]").forEach(e=>{new Tour(e)})}listenForModalOpen(){this.modal.addEventListener("slideout.open",this.setSrc.bind(this))}setSrc(){let e=this.element.getAttribute("data-js-see-inside-src");e&&(this.element.setAttribute("src",e),this.element.removeAttribute("data-js-see-inside-src"))}}

Note that the Tour class is defined twice in the version produced by Terser 4.6.0 (it should not be doing that).

My workaround is to integrate the export default with the initial class definition (rather than placing it at the end of the file), though this should not be necessary.

Some further info:

  • It looks like Terser 4.6.0 is producing longer names than 4.5.1 (e.g., "Tour" rather than "e").
  • Windows 10.
  • Node 10.18.0.

Complete CLI command or minify() options used

Here is the Node JavaScript I'm using:

minified = terser.minify(fileContents, {
    module: isModule
});

The isModule variable is set to true in this case.

@Nicholas-Westby
Copy link
Author

Oh, and I should have mentioned that it's the browser (Chrome in my case) that says "Identifier 'Tour' has already been declared".

@fabiosantoscode
Copy link
Collaborator

This is pretty bad. I'm onto it.

@fabiosantoscode
Copy link
Collaborator

Version 4.6.1 coming out in a few minutes. Terser won't be moving the class over to the export, but that's on my list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants