Search code examples
node.jsreactjsimportimporterrormodule.exports

customHooks module.exports not importing with es6 style


I have an app that I ran this same architecture and it works no problem. I am trying to duplicate in a CRA with React 17.0.2. This is just a file that holds my custom hooks in an organized fashion using module.exports. Here is my file: customHooks.js

import { useCallback, useEffect, useRef, useState } from "react";

module.exports = {
    usePrevious: (stateValue) => {
        const ref = useRef();
        useEffect(() => {
            ref.current = stateValue;
        })
        return ref.current
    },
    getUrlVars: (url) => {
        let vars = {};
        if (url) {
            let parts = url.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
                vars[key] = value;
            });
        } else {
            console.error('No url specified')
        }

        return vars;
    },
    setCookieManually: async (cname, cvalue, exdays) => {
        const d = new Date();
        d.setTime(d.getTime() + (exdays*24*60*60*1000));
        let expires = "expires="+ d.toUTCString();
        document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
    },
    removeCookieManually: async (cname) => {
        document.cookie = `${cname}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`
    },
    useSetState: (initialValue) => {
        let [val, setVal] = useState(initialValue);
        let cbRef = useRef(null);
        let first = useRef(true);

        useEffect(() => {
            if (first.current) {
                first.current = false;
                return;
            }

            if (typeof cbRef.current === "function") {
                console.log("calling cb");
                cbRef.current();
            }
        }, [val]);

        let setValCB = useCallback((newVal, cb) => {
            console.log("setValCB", newVal);
            cbRef.current = cb;
            setVal(newVal);
        }, []);

        /*
        * USAGE:
        * let [selected, setSelected] = useSetState("");
        *
        * setSelected(title, () => {
        *   console.log("onRowSelected", title);
        *   props.onRowSelected(title);
        * });
        *
        * */

        return [val, setValCB];
    }
}

I am just trying to import like this:

import { usePrevious } from '..customHooks'

Yet I keep getting an error: Attempted import error: 'usePrevious' is not exported from '../customHooks.js'.

Note: I have done this successfully with a NextJs project no problem.

  • Is there something that my IDE doesn't like?
  • Is it Bable?

Let me know what you think the issue is.

I have tried to change it from import to require() and it resolves the error but then says: TypeError: Cannot assign to read only property 'exports' of object '#<Object>'

What does this mean?

Thank you!


Solution

  • Update: Node Version 14 and after may run into this problem


    To solve this issue the module.exports had to be removed. Seems after node 14 things get weird with it.

    Now I had to write out each function then export that function in structure.

    
    import { useCallback, useEffect, useRef, useState } from "react";
    
       const usePrevious = (stateValue) => {
            const ref = useRef();
            useEffect(() => {
                ref.current = stateValue;
            })
            return ref.current
        }
    
       const getUrlVars = (url) => {
            let vars = {};
            if (url) {
                let parts = url.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
                    vars[key] = value;
                });
            } else {
                console.error('No url specified')
            }
    
            return vars;
        }
    
       const setCookieManually = async (cname, cvalue, exdays) => {
            const d = new Date();
            d.setTime(d.getTime() + (exdays*24*60*60*1000));
            let expires = "expires="+ d.toUTCString();
            document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
        }
    
       const removeCookieManually = async (cname) => {
            document.cookie = `${cname}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`
        }
    
       const useSetState = (initialValue) => {
            let [val, setVal] = useState(initialValue);
            let cbRef = useRef(null);
            let first = useRef(true);
    
            useEffect(() => {
                if (first.current) {
                    first.current = false;
                    return;
                }
    
                if (typeof cbRef.current === "function") {
                    console.log("calling cb");
                    cbRef.current();
                }
            }, [val]);
    
            let setValCB = useCallback((newVal, cb) => {
                console.log("setValCB", newVal);
                cbRef.current = cb;
                setVal(newVal);
            }, []);
    
            /*
            * USAGE:
            * let [selected, setSelected] = useSetState("");
            *
            * setSelected(title, () => {
            *   console.log("onRowSelected", title);
            *   props.onRowSelected(title);
            * });
            *
            * */
    
            return [val, setValCB];
        }
    
    export {
        usePrevious,
        getUrlVars,
        setCookieManually,
        removeCookieManually,
        useSetState,
    }
    
    

    This then allowed all my imports to work with the destructuring:

    import { usePrevious } from '../utils/customHooks'