Why importing from and exporting to the same javascript file gives type not function error?

Supposed I have the following 2 Javascript files:

1) File 1:

const { fun2 } = require('./file2');
console.log(fun2());

exports.fun1 = () => {
   return 'abc';
};

2) File 2:

const { fun1 } = require('./file1');
console.log(fun1());

exports.fun2 = () => {
   return 'xyz';
};

If I run file1, I get the following error:

TypeError: fun1 is not a function

If I run file2, I get the following error:

TypeError: fun2 is not a function

What is the problem with importing from and exporting to the same file? Is there a solution? I'm using NodeJS

The reason this is happening is because fun2 is an object that looks like this:

{
    fun2: function(){
        return "xyz";
    };
}

When you import things from file2 into file1, you aren't just importing the fun2 function. You importing an object that has the fun2 function in it.

Possible Solutions There are many different ways to fix this

  1. Call fun2.fun2() in file1

Do something like this instead

console.log(fun2.fun2());
  1. Require only the fun2 function. When you require the module, just use the fun2 function from that module.
const { fun2 } = require('./file2').fun2;
  1. Export only the fun2 function in file2 Instead of doing exports.fun2 = (insert function here), do module.exports = (insert function here). This will export only the fun2 function, so when you do require('./file1') it will give you a function.

Export and Import, Please note that export before a class or a function does not make it a function expression. It's still a In practice, there are mainly two kinds of modules. Actually, code navigation becomes easier if files are well-named and structured into folders. Without default , such an export would give an error:. Such oddities of re-exporting the default export are one of the reasons why some developers don’t like them. Summary. Here are all types of export that we covered in this and previous articles. You can check yourself by reading them and recalling what they mean: Before declaration of a class/function/…: export [default] class/function

This is called as circular dependency. To fix the issue, try the following.

// file 1
exports.fun1 = () => {
  return "abc";
};

const { fun2 } = require("./file2");
console.log(fun2());

and

// file 2
exports.fun2 = () => {
  return "xyz";
};

const { fun1 } = require("./file1");
console.log(fun1());

export, The export statement is used when creating JavaScript modules to export also class, function* export default function name1(…) a <script> element of type=" module", so that it gets recognised as a module and dealt with appropriately. You can't run JS modules via a file:// URL — you'll get CORS errors. The use case of knowing whether an export is a function or a class was an example of the type of problems I’ve encountered. It is not the only problem I’ve found named exports solve for me. The problems I’ve encountered don’t just happen with files in my own projects, they also happen with importing library and utility modules that I

try

exports.fun1 = function() {
   return 'abc';
};

import, There is also a function-like dynamic import() , which does not The name parameter is the name of the "module object" which will be used as a kind of namespace to refer to the exports. the exports from the module in the file located in /modules/my-module.js . When used this way, it returns a promise. I think there are a lot of solutions to this. And as has been answered, there's no wildcard export. But, you can 'wildcard' the import. So, I much prefer the one putting export before each of the functions you want to expose from the file: //myfile.js export function fn1() {} export function fn2() {} and then import it like so:

Understanding module.exports and exports in Node.js, As JavaScript originally had no concept of modules, a variety of competing formats Then in the index.js file, we're importing this function and executing it. We can export multiple methods and values in the same way: Notice how the name we give the exported dateOfBirth variable can be anything we� Exporting without default means it's a "named export". You can have multiple named exports in a single file. So if you do this, class Template {} class AnotherTemplate {} export { Template, AnotherTemplate }

Why I've stopped exporting defaults from my JavaScript modules , Importing a default export has grown to feel like a guessing game The use case of knowing whether an export is a function or a class was an example of the type of I'm saying that in modules I'm writing, I will choose not to use default ES6 favors the single/default export style, and gives the sweetest� All other files, such as .js, will be interpreted as a CommonJS, which is a default if the type is not defined in package.json. Conclusion. Here are all types of import-export in Javascript. Export Before the declaration of a class/function/…: export [default] class/function/variable … Standalone export: export {x [as y], …}. Re-export:

Importing defaults with es6 syntax doesn't work � Issue #5565 , Syntax: import name from "module-name"; doesnt work in my project with Typescript 1.6. The imported 1.8.0-beta: ts.transpile now errors for .js files # 6766. Closed Gets _jspdf2.default is not a constructor error MrRio/jsPDF#783. Closed Fix TypeScript type definitions snabbdom/snabbdom-to-html#23. The import statement cannot be used in embedded scripts unless such script has a type="module". Bindings imported are called live bindings because they are updated by the module that exported the binding. There is also a function-like dynamic import(), which does not require scripts of type="module".

Comments
  • You're calling the function before you are defining it.
  • Thanks for your input. The only solution that works is the third but I can't use it because I need to export multiple functions not one so can't add it directly as the only export. This is just a simplified demo. Other solutions give the same error
  • It turns out even the third solution does not work after testing
  • Neither of these solve the problem. I'm not even sure your explanation is correct.
  • What exactly does const { fun2 } = require('./file2'); do? I don't use the brackets around the fun2. Try doing this along with either of the solutions in my answer: const fun2 = require('./file2'); (without the brackets)
  • You are correct that this is a circular dependency, but that is not the root cause of the problem. The root cause, as already explained in the answer fro @programmerRaj is that the export is an object containing the function, not just the function itself.
  • @EJK Making the export the function itself won't help.
  • @EJK This answer here doesn't change the exported object or the circular dependency, it just fixes the order in which statements are evaluated. It works, and is the correct solution. It might need a better explanation of the issue, though.
  • @EJK I read that circular dependencies should be avoided as much as possible as they indicate a bad code design. My real code has a model/controller design. I can avoid this circular thing altogether by having both functions in the same module which would be the controller in the actual code but the imported function belongs to another model. Is it ok in MVC to control some functions of the model from another controller or is it a bad practice?
  • @MichaelSamuel Sure, it's best to avoid the circular dependency altogether, but sometimes there are good reasons to have it. We can't judge your use case. If you do have one in your code, you just need to make sure that you never use/access any of the exports before both modules finished exporting all their functions. That includes function calls as well as destructuring. Make sure to read the docs on dependency cycles.
  • What if I have multiple functions to export? This is just a simplified version of the script
  • That's actually a totally irrelevant answer! My syntax is correct so syntax is not the problem