what does it mean by "debug = require('debug')('api:server')" - javascript

I was reading some code of a project to learn node.js then I found this line (debug = require('debug')('api:server')) which is enclosed in brackets. As I'm new to programming and when I don't know something I just search it on the web, but I couldn't find an answer for this one. If you are going to tell me to search on the web more aggressively then please tell me HOW too.

require returns the exports of some other module. Here, since debug is being passed into require, the debug module is being required. What this module does is:
debug exposes a function; simply pass this function the name of your module, and it will return a decorated version of console.error for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole.
So
const debug = require('debug')('api:server');
where require('debug') resolves to a function, is like:
const debug = deccorateModule('api:server');
where decorateModule carries out the functionality described above. In this case, require acts as a higher-order function: a function which returns a function. (You may likely have a module named api:server)
This results in the debug variable holding the decorated version of console.error.

Related

Making a function to return whether the current code is being run directly or being imported, without using eval

Based on this it is possible for JS module code to determine whether it is being run directly or being imported from somewhere else. This is analogous to the old way of doing it but module is not a thing anymore in the EcmaScript Modules world? Or is it?
So, I wanted to take it a step further and use this as an opportunity to learn a few things under the hood.
I tried this
#!/usr/bin/env node
import url from "url";
const code = `
console.error(
"isScript debug: x:", import.meta.url, " y:", url.pathToFileURL(process.argv[1]).href
);
return import.meta.url === url.pathToFileURL(process.argv[1]).href;
`;
const f = Function(code);
export const isScript = () => f();
... as an attempt to not use eval which is "evil". Basically I want to be able to incorporate this logic in my scripts without having to write the import.meta.url === url.pathToFileURL(process.argv[1]).href code in each place that I need it. Because of two reasons, (1) it's just difficult to remember, and (2) making ridiculously tiny "libraries" is trendy with JS. But i realize that this may be challenging due to the "special" nature of import.
Indeed this code does not run: SyntaxError: Cannot use 'import.meta' outside a module
Is this a fool's errand? I could at least still make an isScript which has to receive an import.meta.url value, right? The thing is, that'd be a mildly ~leaky abstraction~ (not sure what term to use here) and rather unsatisfactory.
By the way, eval also does not work, the code "compiles" but when importing this module and trying to run it, I get SyntaxError: Cannot use 'import.meta' outside a module from the importing code. I might be doing something silly though.

How to fix circular dependency between functions in javascript [duplicate]

Trying to find a good and proper pattern to handle a circular module dependency in Python. Usually, the solution is to remove it (through refactoring); however, in this particular case we would really like to have the functionality that requires the circular import.
EDIT: According to answers below, the usual angle of attack for this kind of issue would be a refactor. However, for the sake of this question, assume that is not an option (for whatever reason).
The problem:
The logging module requires the configuration module for some of its configuration data. However, for some of the configuration functions I would really like to use the custom logging functions that are defined in the logging module. Obviously, importing the logging module in configuration raises an error.
The possible solutions we can think of:
Don't do it. As I said before, this is not a good option, unless all other possibilities are ugly and bad.
Monkey-patch the module. This doesn't sound too bad: load the logging module dynamically into configuration after the initial import, and before any of its functions are actually used. This implies defining global, per-module variables, though.
Dependency injection. I've read and run into dependency injection alternatives (particularly in the Java Enterprise space) and they remove some of this headache; however, they may be too complicated to use and manage, which is something we'd like to avoid. I'm not aware of how the panorama is about this in Python, though.
What is a good way to enable this functionality?
Thanks very much!
As already said, there's probably some refactoring needed. According to the names, it might be ok if a logging modules uses configuration, when thinking about what things should be in configuration one think about configuration parameters, then a question arises, why is that configuration logging at all?
Chances are that the parts of the code under configuration that uses logging does not belong to the configuration module: seems like it is doing some kind of processing and logging either results or errors.
Without inner knowledge, and using only common sense, a "configuration" module should be something simple without much processing and it should be a leaf in the import tree.
Hope it helps!
Will this work for you?
# MODULE a (file a.py)
import b
HELLO = "Hello"
# MODULE b (file b.py)
try:
import a
# All the code for b goes here, for example:
print("b done",a.HELLO))
except:
if hasattr(a,'HELLO'):
raise
else:
pass
Now I can do an import b. When the circular import (caused by the import b statement in a) throws an exception, it gets caught and discarded. Of course your entire module b will have to indented one extra block spacing, and you have to have inside knowledge of where the variable HELLO is declared in a.
If you don't want to modify b.py by inserting the try:except: logic, you can move the whole b source to a new file, call it c.py, and make a simple file b.py like this:
# new Module b.py
try:
from c import *
print("b done",a.HELLO)
except:
if hasattr(a,"HELLO"):
raise
else:
pass
# The c.py file is now a copy of b.py:
import a
# All the code from the original b, for example:
print("b done",a.HELLO))
This will import the entire namespace from c to b, and paper over the circular import as well.
I realize this is gross, so don't tell anyone about it.
A cyclic module dependency is usually a code smell.
It indicates that part of the code should be re-factored so that it is external to both modules.
So if I'm reading your use case right, logging accesses configuration to get configuration data. However, configuration has some functions that, when called, require that stuff from logging be imported in configuration.
If that is the case (that is, configuration doesn't really need logging until you start calling functions), the answer is simple: in configuration, place all the imports from logging at the bottom of the file, after all the class, function and constant definitions.
Python reads things from top to bottom: when it comes across an import statement in configuration, it runs it, but at this point, configuration already exists as a module that can be imported, even if it's not fully initialized yet: it only has the attributes that were declared before the import statement was run.
I do agree with the others though, that circular imports are usually a code smell.

What is the meaning of this code "var FileStore = require('session-file-store')(session);"? [duplicate]

I was reading some code of a project to learn node.js then I found this line (debug = require('debug')('api:server')) which is enclosed in brackets. As I'm new to programming and when I don't know something I just search it on the web, but I couldn't find an answer for this one. If you are going to tell me to search on the web more aggressively then please tell me HOW too.
require returns the exports of some other module. Here, since debug is being passed into require, the debug module is being required. What this module does is:
debug exposes a function; simply pass this function the name of your module, and it will return a decorated version of console.error for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole.
So
const debug = require('debug')('api:server');
where require('debug') resolves to a function, is like:
const debug = deccorateModule('api:server');
where decorateModule carries out the functionality described above. In this case, require acts as a higher-order function: a function which returns a function. (You may likely have a module named api:server)
This results in the debug variable holding the decorated version of console.error.

Can I run jest tests as regular js files?

Jest uses describe and it and expect without you having to require them. This is okay because if you have a test file called test.spec.js, you'll never execute it directly by issuing the command node test.spec.js.
I want to execute it using node as a standard js file, without having to use jest's cli or npm test. Is it possible to do that?
For instance, I'd convert the following file:
// taken from documentation
const user = require('./users.js')
it('works with promises', () => {
expect.assertions(1);
return user.getUserName(4).then(data => expect(data).toEqual('Mark'));
});
To something like
var {describe, it, expect} = require('jest-primitives')
const user = require('./users.js')
it('works with promises', () => {
expect.assertions(1);
return user.getUserName(4).then(data => expect(data).toEqual('Mark'));
});
So that it's a self-contained js file, which can be run using just node.
A complete list of globals that jest provides is given here.
Is it technically possible? Yes.
Should you? Probably not. (But there are better ways - tl;dr use tape)
Background
Jest is a test harness.
Jest is not the only test harness to use describe() and it(). These are typical test keywords for behavior-driven development (BDD). You'll also find them used with Mocha and others.
describe() and it() are functions that interface with the test harness, telling it to add a test suite and a test case, respectively. The test harness then runs the test cases, collects the results, formats the results and outputs them.
Why you shouldn't do this with Jest
Generally, you should use technology as idiomatically as possible. This makes it easier for others to read, understand, and work with your technology.
In particular, using Jest in this way will be self-implemented, hacky, buggy and generally incomprehensible to anyone not familiar with your code. That being said, it should be possible.
How you might attempt that with Jest
Jest defines runner packages in their Jest monorepo. One is Circus, the other is Jasmine2.
Circus exports describe(), it() and some other keywords, though these are not really useful to us, as these functions only internally create the test suites and test cases but do not expose them to us or give us a way to run them.
Jasmine2 exports an executable function which returns a Promise of a test result. The code for jasmineAsyncInstall creates most of the keywords in the env or globally, and you might be able to use these.
What you'd want to do here is define it() and describe() functiions, either globally, as exports (if you'd like to use them as in the code sample in the question), or hackily by defining them inside the scope of the main module. These functions should register test cases and test suites. You'll want to either keep track of the test cases and run them later, or run them right away and keep track of the test results.
The problem now lies in determining when the test module has finished running. That is, when all of the describe() and it() have executed (whether or not the test cases themselves have executed), as well as any other incident code (code that isn't in any block). There is no good way to handle this, and here's where it may get hacky again. The easiest way is probably to add a listener to process.on('exit'.
Why that doesn't matter
A test harness is generally just a test runner and a reporter. Jest, in particular, is just a collection of components, all of which are configurable.
If we're just pulling a function here and a variable there from Jest, can we really say that we're still using it? Why do we even want to? There's really no reason to use Jest here. If you don't like the way it runs tests, you should use a different test harness instead of trying to modify it. If you like the reporter, Jest exports a package containing only the reporter.
A better way to make test files runnable
Use tap or tape. These are designed to be run the way you want, and are configurable.
Example:
const test = require('tape');
const MyClass = require('../src/my-class');
test('MyClass.doSometing should be true', (t) => {
const result = MyClass.doSomething();
if (result === true) {
t.pass('The test passed! Hooray! Our class MyClass is seemingly error-free!');
} else {
t.fail('Oh noes. Our test has failed. Why am I such a bad programmer....?');
}
t.end();
});
I had to do a lot of research to get to the right library.
The most suitable one that I found so far is Jest Lite. This guy has done a great job.
Another solution I found is a workaround with Chai.js. Install chai and import the expect from the library. Run expect statement. Unfortunately, it does not return a promise or result. You can just get the job done with a try-catch.

How to validate import functions?

I am writing a web app as a hobby using nodejs and react.
I have a file where I use some utilities functions, for example foo.
After using this function in some other files, I have decided to change the export and to wrap the function in an object, like Util.foo.
There was one file that I forgot to change the import statement to object instead of function, and I was calling foo() instead of Util.foo().
I couldn't catch it in my webpack build and not even in my unit tests, I cought it only when running the code and executing the appropriate function.
My question is, how can I avoid future mistakes like this? Are there any tools other than refactoring tools for this matter?
By the way, I am using Atom IDE.
This should have been caught by your unit tests if this part of your code is covered completely.
Calling a non-existing function will result in an error along the lines of undefined is not a function and should fail your test case.
To avoid issues like this, make sure your test coverage is exhausting. A test coverage tool like Istanbul may by helpful in determining areas for improvement.

Categories