Circular Dependancy Error - Node Modules Build

37 Views Asked by At

Can anyone tell me why I'm getting a 'circular dependancy' error when trying to build a project?

Main JS file imports Custom Scroll JS file:

 // import Smooth scroll custom JS file
 import './custom/smooth-scroll';

Smooth Scroll custom JS file importing Smooth Scroll from Node_Modules at root of project:

//Smooth scroll
    import SmoothScroll from 'smooth-scroll';

    var scroll = new SmoothScroll('a[href*="#"]', {
    speed: 700,
    speedAsDuration: true
});

    export default {
    SmoothScroll
}

Smooth Scroll JS file in Node_Module

/*!
 * smooth-scroll v16.1.3
 * Animate scrolling to anchor links
 * (c) 2020 Chris Ferdinandi
 * MIT License
 * http://github.com/cferdinandi/smooth-scroll
 */

/**
 * closest() polyfill
 * @link https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill
 */
if (window.Element && !Element.prototype.closest) {
    Element.prototype.closest = function(s) {
        var matches = (this.document || this.ownerDocument).querySelectorAll(s),
        i,
        el = this;
        do {
            i = matches.length;
            while (--i >= 0 && matches.item(i) !== el) {}
        } while ((i < 0) && (el = el.parentElement));
    return el;
};
}

/**
 * CustomEvent() polyfill
 * https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
 */
(function () {

    if (typeof window.CustomEvent === "function") return false;

    function CustomEvent(event, params) {
        params = params || { bubbles: false, cancelable: false, detail: undefined };
        var evt = document.createEvent('CustomEvent');
        evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
        return evt;
    }

    CustomEvent.prototype = window.Event.prototype;

    window.CustomEvent = CustomEvent;
})();
/**
 * requestAnimationFrame() polyfill
 * By Erik Möller. Fixes from Paul Irish and Tino Zijdel.
 * @link http://paulirish.com/2011/requestanimationframe-for-smart-animating/
 * @link http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
 * @license MIT
 */
(function() {
    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] ||
        window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame) {
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout((function() { callback(currTime + timeToCall); }),
                timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };
    }

    if (!window.cancelAnimationFrame) {
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
    }
}());

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define([], (function () {
            return factory(root);
        }));
    } else if (typeof exports === 'object') {
        module.exports = factory(root);
    } else {
        root.SmoothScroll = factory(root);
    }
})(typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : this, (function (window) {

    'use strict';

    //
    // Default settings
    //

    var defaults = {

        // Selectors
        ignore: '[data-scroll-ignore]',
        header: null,
        topOnEmptyHash: true,

        // Speed & Duration
        speed: 500,
        speedAsDuration: false,
        durationMax: null,
        durationMin: null,
        clip: true,
        offset: 0,

        // Easing
        easing: 'easeInOutCubic',
        customEasing: null,

        // History
        updateURL: true,
        popstate: true,

        // Custom Events
        emitEvents: true

    };


    //
    // Utility Methods
    //

    /**
     * Check if browser supports required methods
     * @return {Boolean} Returns true if all required methods are supported
     */
    var supports = function () {
        return (
            'querySelector' in document &&
            'addEventListener' in window &&
            'requestAnimationFrame' in window &&
            'closest' in window.Element.prototype
            );
    };

    /**
     * Merge two or more objects together.
     * @param   {Object}   objects  The objects to merge together
     * @returns {Object}            Merged values of defaults and options
     */
    var extend = function () {
        var merged = {};
        Array.prototype.forEach.call(arguments, (function (obj) {
            for (var key in obj) {
                if (!obj.hasOwnProperty(key)) return;
                merged[key] = obj[key];
            }
        }));
        return merged;
    };

    /**
     * Check to see if user prefers reduced motion
     * @param  {Object} settings Script settings
     */
    var reduceMotion = function () {
        if ('matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches) {
            return true;
        }
        return false;
    };

    /**
     * Get the height of an element.
     * @param  {Node} elem The element to get the height of
     * @return {Number}    The element's height in pixels
     */
    var getHeight = function (elem) {
        return parseInt(window.getComputedStyle(elem).height, 10);
    };

    /**
     * Escape special characters for use with querySelector
     * @author Mathias Bynens
     * @link https://github.com/mathiasbynens/CSS.escape
     * @param {String} id The anchor ID to escape
     */
    var escapeCharacters = function (id) {

        // Remove leading hash
        if (id.charAt(0) === '#') {
            id = id.substr(1);
        }

        var string = String(id);
        var length = string.length;
        var index = -1;
        var codeUnit;
        var result = '';
        var firstCodeUnit = string.charCodeAt(0);
        while (++index < length) {
            codeUnit = string.charCodeAt(index);
            // Note: there’s no need to special-case astral symbols, surrogate
            // pairs, or lone surrogates.

            // If the character is NULL (U+0000), then throw an
            // `InvalidCharacterError` exception and terminate these steps.
            if (codeUnit === 0x0000) {
                throw new InvalidCharacterError(
                    'Invalid character: the input contains U+0000.'
                    );
            }

            if (
                // If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
                // U+007F, […]
                (codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F ||
                // If the character is the first character and is in the range [0-9]
                // (U+0030 to U+0039), […]
                (index === 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) ||
                // If the character is the second character and is in the range [0-9]
                // (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
                (
                    index === 1 &&
                    codeUnit >= 0x0030 && codeUnit <= 0x0039 &&
                    firstCodeUnit === 0x002D
                    )
                ) {
                // http://dev.w3.org/csswg/cssom/#escape-a-character-as-code-point
                result += '\\' + codeUnit.toString(16) + ' ';
            continue;
        }

            // If the character is not handled by one of the above rules and is
            // greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or
            // is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to
            // U+005A), or [a-z] (U+0061 to U+007A), […]
        if (
            codeUnit >= 0x0080 ||
            codeUnit === 0x002D ||
            codeUnit === 0x005F ||
            codeUnit >= 0x0030 && codeUnit <= 0x0039 ||
            codeUnit >= 0x0041 && codeUnit <= 0x005A ||
            codeUnit >= 0x0061 && codeUnit <= 0x007A
            ) {
                // the character itself
            result += string.charAt(index);
        continue;
    }

            // Otherwise, the escaped character.
            // http://dev.w3.org/csswg/cssom/#escape-a-character
    result += '\\' + string.charAt(index);

}

        // Return sanitized hash
return '#' + result;

};

    /**
     * Calculate the easing pattern
     * @link https://gist.github.com/gre/1650294
     * @param {String} type Easing pattern
     * @param {Number} time Time animation should take to complete
     * @returns {Number}
     */
var easingPattern = function (settings, time) {
    var pattern;

        // Default Easing Patterns
        if (settings.easing === 'easeInQuad') pattern = time * time; // accelerating from zero velocity
        if (settings.easing === 'easeOutQuad') pattern = time * (2 - time); // decelerating to zero velocity
        if (settings.easing === 'easeInOutQuad') pattern = time < 0.5 ? 2 * time * time : -1 + (4 - 2 * time) * time; // acceleration until halfway, then deceleration
        if (settings.easing === 'easeInCubic') pattern = time * time * time; // accelerating from zero velocity
        if (settings.easing === 'easeOutCubic') pattern = (--time) * time * time + 1; // decelerating to zero velocity
        if (settings.easing === 'easeInOutCubic') pattern = time < 0.5 ? 4 * time * time * time : (time - 1) * (2 * time - 2) * (2 * time - 2) + 1; // acceleration until halfway, then deceleration
        if (settings.easing === 'easeInQuart') pattern = time * time * time * time; // accelerating from zero velocity
        if (settings.easing === 'easeOutQuart') pattern = 1 - (--time) * time * time * time; // decelerating to zero velocity
        if (settings.easing === 'easeInOutQuart') pattern = time < 0.5 ? 8 * time * time * time * time : 1 - 8 * (--time) * time * time * time; // acceleration until halfway, then deceleration
        if (settings.easing === 'easeInQuint') pattern = time * time * time * time * time; // accelerating from zero velocity
        if (settings.easing === 'easeOutQuint') pattern = 1 + (--time) * time * time * time * time; // decelerating to zero velocity
        if (settings.easing === 'easeInOutQuint') pattern = time < 0.5 ? 16 * time * time * time * time * time : 1 + 16 * (--time) * time * time * time * time; // acceleration until halfway, then deceleration

        // Custom Easing Patterns
        if (!!settings.customEasing) pattern = settings.customEasing(time);

        return pattern || time; // no easing, no acceleration
    };

    /**
     * Determine the document's height
     * @returns {Number}
     */
    var getDocumentHeight = function () {
        return Math.max(
            document.body.scrollHeight, document.documentElement.scrollHeight,
            document.body.offsetHeight, document.documentElement.offsetHeight,
            document.body.clientHeight, document.documentElement.clientHeight
            );
    };

    /**
     * Calculate how far to scroll
     * Clip support added by robjtede - https://github.com/cferdinandi/smooth-scroll/issues/405
     * @param {Element} anchor       The anchor element to scroll to
     * @param {Number}  headerHeight Height of a fixed header, if any
     * @param {Number}  offset       Number of pixels by which to offset scroll
     * @param {Boolean} clip         If true, adjust scroll distance to prevent abrupt stops near the bottom of the page
     * @returns {Number}
     */
    var getEndLocation = function (anchor, headerHeight, offset, clip) {
        var location = 0;
        if (anchor.offsetParent) {
            do {
                location += anchor.offsetTop;
                anchor = anchor.offsetParent;
            } while (anchor);
        }
        location = Math.max(location - headerHeight - offset, 0);
        if (clip) {
            location = Math.min(location, getDocumentHeight() - window.innerHeight);
        }
        return location;
    };

    /**
     * Get the height of the fixed header
     * @param  {Node}   header The header
     * @return {Number}        The height of the header
     */
    var getHeaderHeight = function (header) {
        return !header ? 0 : (getHeight(header) + header.offsetTop);
    };

    /**
     * Calculate the speed to use for the animation
     * @param  {Number} distance The distance to travel
     * @param  {Object} settings The plugin settings
     * @return {Number}          How fast to animate
     */
    var getSpeed = function (distance, settings) {
        var speed = settings.speedAsDuration ? settings.speed : Math.abs(distance / 1000 * settings.speed);
        if (settings.durationMax && speed > settings.durationMax) return settings.durationMax;
        if (settings.durationMin && speed < settings.durationMin) return settings.durationMin;
        return parseInt(speed, 10);
    };

    var setHistory = function (options) {

        // Make sure this should run
        if (!history.replaceState || !options.updateURL || history.state) return;

        // Get the hash to use
        var hash = window.location.hash;
        hash = hash ? hash : '';

        // Set a default history
        history.replaceState(
        {
            smoothScroll: JSON.stringify(options),
            anchor: hash ? hash : window.pageYOffset
        },
        document.title,
        hash ? hash : window.location.href
        );

    };

    /**
     * Update the URL
     * @param  {Node}    anchor  The anchor that was scrolled to
     * @param  {Boolean} isNum   If true, anchor is a number
     * @param  {Object}  options Settings for Smooth Scroll
     */
    var updateURL = function (anchor, isNum, options) {

        // Bail if the anchor is a number
        if (isNum) return;

        // Verify that pushState is supported and the updateURL option is enabled
        if (!history.pushState || !options.updateURL) return;

        // Update URL
        history.pushState(
        {
            smoothScroll: JSON.stringify(options),
            anchor: anchor.id
        },
        document.title,
        anchor === document.documentElement ? '#top' : '#' + anchor.id
        );

    };

    /**
     * Bring the anchored element into focus
     * @param {Node}     anchor      The anchor element
     * @param {Number}   endLocation The end location to scroll to
     * @param {Boolean}  isNum       If true, scroll is to a position rather than an element
     */
    var adjustFocus = function (anchor, endLocation, isNum) {

        // Is scrolling to top of page, blur
        if (anchor === 0) {
            document.body.focus();
        }

        // Don't run if scrolling to a number on the page
        if (isNum) return;

        // Otherwise, bring anchor element into focus
        anchor.focus();
        if (document.activeElement !== anchor) {
            anchor.setAttribute('tabindex', '-1');
            anchor.focus();
            anchor.style.outline = 'none';
        }
        window.scrollTo(0 , endLocation);

    };

    /**
     * Emit a custom event
     * @param  {String} type    The event type
     * @param  {Object} options The settings object
     * @param  {Node}   anchor  The anchor element
     * @param  {Node}   toggle  The toggle element
     */
    var emitEvent = function (type, options, anchor, toggle) {
        if (!options.emitEvents || typeof window.CustomEvent !== 'function') return;
        var event = new CustomEvent(type, {
            bubbles: true,
            detail: {
                anchor: anchor,
                toggle: toggle
            }
        });
        document.dispatchEvent(event);
    };


    //
    // SmoothScroll Constructor
    //

    var SmoothScroll = function (selector, options) {

        //
        // Variables
        //

        var smoothScroll = {}; // Object for public APIs
        var settings, anchor, toggle, fixedHeader, eventTimeout, animationInterval;


        //
        // Methods
        //

        /**
         * Cancel a scroll-in-progress
         */
        smoothScroll.cancelScroll = function (noEvent) {
            cancelAnimationFrame(animationInterval);
            animationInterval = null;
            if (noEvent) return;
            emitEvent('scrollCancel', settings);
        };

        /**
         * Start/stop the scrolling animation
         * @param {Node|Number} anchor  The element or position to scroll to
         * @param {Element}     toggle  The element that toggled the scroll event
         * @param {Object}      options
         */
        smoothScroll.animateScroll = function (anchor, toggle, options) {

            // Cancel any in progress scrolls
            smoothScroll.cancelScroll();

            // Local settings
            var _settings = extend(settings || defaults, options || {}); // Merge user options with defaults

            // Selectors and variables
            var isNum = Object.prototype.toString.call(anchor) === '[object Number]' ? true : false;
            var anchorElem = isNum || !anchor.tagName ? null : anchor;
            if (!isNum && !anchorElem) return;
            var startLocation = window.pageYOffset; // Current location on the page
            if (_settings.header && !fixedHeader) {
                // Get the fixed header if not already set
                fixedHeader = document.querySelector(_settings.header);
            }
            var headerHeight = getHeaderHeight(fixedHeader);
            var endLocation = isNum ? anchor : getEndLocation(anchorElem, headerHeight, parseInt((typeof _settings.offset === 'function' ? _settings.offset(anchor, toggle) : _settings.offset), 10), _settings.clip); // Location to scroll to
            var distance = endLocation - startLocation; // distance to travel
            var documentHeight = getDocumentHeight();
            var timeLapsed = 0;
            var speed = getSpeed(distance, _settings);
            var start, percentage, position;

            /**
             * Stop the scroll animation when it reaches its target (or the bottom/top of page)
             * @param {Number} position Current position on the page
             * @param {Number} endLocation Scroll to location
             * @param {Number} animationInterval How much to scroll on this loop
             */
            var stopAnimateScroll = function (position, endLocation) {

                // Get the current location
                var currentLocation = window.pageYOffset;

                // Check if the end location has been reached yet (or we've hit the end of the document)
                if (position == endLocation || currentLocation == endLocation || ((startLocation < endLocation && window.innerHeight + currentLocation) >= documentHeight)) {

                    // Clear the animation timer
                    smoothScroll.cancelScroll(true);

                    // Bring the anchored element into focus
                    adjustFocus(anchor, endLocation, isNum);

                    // Emit a custom event
                    emitEvent('scrollStop', _settings, anchor, toggle);

                    // Reset start
                    start = null;
                    animationInterval = null;

                    return true;

                }
            };

            /**
             * Loop scrolling animation
             */
            var loopAnimateScroll = function (timestamp) {
                if (!start) { start = timestamp; }
                timeLapsed += timestamp - start;
                percentage = speed === 0 ? 0 : (timeLapsed / speed);
                percentage = (percentage > 1) ? 1 : percentage;
                position = startLocation + (distance * easingPattern(_settings, percentage));
                window.scrollTo(0, Math.floor(position));
                if (!stopAnimateScroll(position, endLocation)) {
                    animationInterval = window.requestAnimationFrame(loopAnimateScroll);
                    start = timestamp;
                }
            };

            /**
             * Reset position to fix weird iOS bug
             * @link https://github.com/cferdinandi/smooth-scroll/issues/45
             */
            if (window.pageYOffset === 0) {
                window.scrollTo(0, 0);
            }

            // Update the URL
            updateURL(anchor, isNum, _settings);

            // If the user prefers reduced motion, jump to location
            if (reduceMotion()) {
                adjustFocus(anchor, Math.floor(endLocation), false);
                return;
            }

            // Emit a custom event
            emitEvent('scrollStart', _settings, anchor, toggle);

            // Start scrolling animation
            smoothScroll.cancelScroll(true);
            window.requestAnimationFrame(loopAnimateScroll);

        };

        /**
         * If smooth scroll element clicked, animate scroll
         */
        var clickHandler = function (event) {

            // Don't run if event was canceled but still bubbled up
            // By @mgreter - https://github.com/cferdinandi/smooth-scroll/pull/462/
            if (event.defaultPrevented) return;

            // Don't run if right-click or command/control + click or shift + click
            if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey) return;

            // Check if event.target has closest() method
            // By @totegi - https://github.com/cferdinandi/smooth-scroll/pull/401/
            if (!('closest' in event.target)) return;

            // Check if a smooth scroll link was clicked
            toggle = event.target.closest(selector);
            if (!toggle || toggle.tagName.toLowerCase() !== 'a' || event.target.closest(settings.ignore)) return;

            // Only run if link is an anchor and points to the current page
            if (toggle.hostname !== window.location.hostname || toggle.pathname !== window.location.pathname || !/#/.test(toggle.href)) return;

            // Get an escaped version of the hash
            var hash;
            try {
                hash = escapeCharacters(decodeURIComponent(toggle.hash));
            } catch(e) {
                hash = escapeCharacters(toggle.hash);
            }

            // Get the anchored element
            var anchor;
            if (hash === '#') {
                if (!settings.topOnEmptyHash) return;
                anchor = document.documentElement;
            } else {
                anchor = document.querySelector(hash);
            }
            anchor = !anchor && hash === '#top' ? document.documentElement : anchor;

            // If anchored element exists, scroll to it
            if (!anchor) return;
            event.preventDefault();
            setHistory(settings);
            smoothScroll.animateScroll(anchor, toggle);

        };

        /**
         * Animate scroll on popstate events
         */
        var popstateHandler = function (event) {

            // Stop if history.state doesn't exist (ex. if clicking on a broken anchor link).
            // fixes `Cannot read property 'smoothScroll' of null` error getting thrown.
            if (history.state === null) return;

            // Only run if state is a popstate record for this instantiation
            if (!history.state.smoothScroll || history.state.smoothScroll !== JSON.stringify(settings)) return;

            // Only run if state includes an anchor

            // if (!history.state.anchor && history.state.anchor !== 0) return;

            // Get the anchor
            var anchor = history.state.anchor;
            if (typeof anchor === 'string' && anchor) {
                anchor = document.querySelector(escapeCharacters(history.state.anchor));
                if (!anchor) return;
            }

            // Animate scroll to anchor link
            smoothScroll.animateScroll(anchor, null, {updateURL: false});

        };

        /**
         * Destroy the current initialization.
         */
        smoothScroll.destroy = function () {

            // If plugin isn't already initialized, stop
            if (!settings) return;

            // Remove event listeners
            document.removeEventListener('click', clickHandler, false);
            window.removeEventListener('popstate', popstateHandler, false);

            // Cancel any scrolls-in-progress
            smoothScroll.cancelScroll();

            // Reset variables
            settings = null;
            anchor = null;
            toggle = null;
            fixedHeader = null;
            eventTimeout = null;
            animationInterval = null;

        };

        /**
         * Initialize Smooth Scroll
         * @param {Object} options User settings
         */
        var init = function () {

            // feature test
            if (!supports()) throw 'Smooth Scroll: This browser does not support the required JavaScript methods and browser APIs.';

            // Destroy any existing initializations
            smoothScroll.destroy();

            // Selectors and variables
            settings = extend(defaults, options || {}); // Merge user options with defaults
            fixedHeader = settings.header ? document.querySelector(settings.header) : null; // Get the fixed header

            // When a toggle is clicked, run the click handler
            document.addEventListener('click', clickHandler, false);

            // If updateURL and popState are enabled, listen for pop events
            if (settings.updateURL && settings.popstate) {
                window.addEventListener('popstate', popstateHandler, false);
            }

        };


        //
        // Initialize plugin
        //

        init();


        //
        // Public APIs
        //

        return smoothScroll;

    };

    return SmoothScroll;

}));

Error Message:

Bundled and transpiled successfully, but with warnings: Circular dependency: custom/smooth-scroll.js -> custom/smooth-scroll.js

FYI - I use Codekit to build/compile but I don't think that is relevant to my question as I'm assuming other dev tools 'Grunt, Gulp' etc would identify the same circular dependencies (although they may still allow the build to proceed).

0

There are 0 best solutions below