D
D
Dmitry2018-03-07 07:46:08
Node.js
Dmitry, 2018-03-07 07:46:08

How to split a large file in node.js into several smaller ones?

I have a file with 900 lines. there are logically independent sections that I would like to put into separate files. But the problem is that all these sections require a lot of variables declared in the main file. If you take them out into separate modules, then you will need to transfer 10 parameters to them. You can make them global, but I don't like this way. You can make one global object where to dump these variables, which is also somehow not beautiful. How to do it right? (I'm new to node.js). Is there something like include "file_name.php" as in php, when called, the code from the file is "inserted" into the call site?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
T
Timur Shemsedinov, 2018-03-07
@Dimoncha

This question is more general than your case with node.js, and even more general than JavaScript in general. It is good to divide your code into parts, highlight abstractions, give them names and combine them into one whole - this is one of the main tasks of a programmer in any language.
I will first answer a specific question about Node.js and JavaScript, and then I will explain this topic in more depth. For Node.js, there is a require, with which you can import from other modules. This is the implementation Dependency Lookup, i.e. we have several modules and each of them knows which ones it depends on and can ask the dependency manager to give a link to what another module (in this case, a file) exports. For example, we can do require('./matrix.js')or require('./lib/matrix.js')and thus get a link to what is exported matrix.jsviamodule.exports = { ... };. Code example with import: names.js
In this one module.exportswe give a reference to a function or to an object or array that contains whatever we want to export (you can also export a scalar value, but this is practically not necessary). In the vast majority of cases, they export an object (using it as a reference for exported identifiers), a little less often one function (sometimes a factory or a wrapper function) or a prototype (or class) constructor. Code example with export: lib/submodule2.js
But you can import dependencies in whole arrays, for example here: main.js If you look a little wider than the node, in JavaScript, there is a way to import / export through the keywords importand export. Examples: import.mjs andexport.mjs You can
read the documentation here:
1. Modules for Node.js via require/module.exports: https://nodejs.org/api/modules.html
2. Modules for Node.js via import/export: https:/ /nodejs.org/api/esm.html
3. Modules for JavaScript via import/export: https://developer.mozilla.org/en-US/docs/Web/JavaS... and https://developer.mozilla .org/en-US/docs/Web/JavaS...
But this is all technical implementation, much more important is how we break our code into modules or abstractions. Here you need to introduce the concept of binding and classify the methods of binding (parts of code):
1. Through common data (the most rigid binding)
2. Through calls (usually between modules with export and import)
3. Through events (the easiest, between loosely coupled software components)
If from different functions, prototypes and classes (their methods) you access the same data, and even more so, change them, then this is very bad. There may be common identifiers, but these are only constants that do not change from different places. There may be groups of functions that need to see one variable and change it, but they need to be combined with each other through closures and partial application. And such constructions connected through data (strongly connected) should be located only inside one file. Changing the same data from different places can lead to the formation of a complex and unpredictable state, and ultimately to situations where the combinatorial explosion of the state cannot be adequately processed by the program, all cases are simply not covered by conditions and we cannot even imagine and take into account all cases in the code.
Calls are a much safer way for software components to interact, which is why we use them to interface between modules and between classes and prototypes. We export/import collections of functions (APIs) or collections of classes, which assumes that all interaction between them will be through calls (even access to properties can be intercepted by getters and setters). I have already said a lot about this method of linking modules above.
The least rigid way of binding is through events. Here, one software component (module, class, prototype, functor) can subscribe to the events of another or cause events in itself or in another without expecting that there are subscribers there. Of course, there may be problems with event contracts, ie. names and data formats, they are not strictly specified and there can be many errors. This is a very flexible way, but it has potential compatibility issues. So, where you can get by with calls, it is better not to use events.
There is another middle way between calls and events, this is callback (and listener). With the help of it, events are made, practically, into a method.on(name, callback)(or its analogues) the callback function is passed as an argument. Asynchronous programming is built on this method, including such binding methods as asynchronous serial composition and asynchronous parallel composition of functions, chaining and promises.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question