You can, of course, publish your own npm module, and manage that module with
npm, but you should avoid editing things directly in node_modules!
Customizing Modules with Function Modules
Modules most commonly export objects, and sometimes a single function. There’s
another very common pattern: a module that exports a function that’s intended to be
invoked immediately. It’s the return value of that function (which can be a function
itself) that’s intended to be used (in other words, you don’t use the function that’s
returned; you invoke that function and use whatever it returns). This pattern is used
when the module needs to be customized somehow or receive information about the
enclosing context. Let’s consider the real-world npm package
debug
. When you
import
debug
, it takes a string that will be used as a log prefix so logging for different
parts of your program can be distinguished. It’s used like this:
const
debug
=
require
(
'debug'
)(
'main'
);
// note that we immediately call the
// function that the module returns
debug
(
"starting"
);
// will log "main starting +0ms"
// if debugging is enabled
To enable debugging with the debug library, set an environment
variable called DEBUG. For our example, we would set DEBUG=main.
You can also set DEBUG=* to enable all debug messages.
It’s clear from this example that the
debug
module returns a function (because we
immediately call it as a function)…and that function itself returns a function that
“remembers” the string from the first function. In essence, we have “baked in” a value
to that module. Let’s see how we might implement our own
debug
module:
let
lastMessage
;
module
.
exports
=
function
(
prefix
) {
return
function
(
message
) {
const
now
=
Date
.
now
();
const
sinceLastMessage
=
now
-
(
lastMessage
||
now
);
console.log(
`
${
prefix
}
${
message
}
+
${
sinceLastMessage
}
ms`
);
lastMessage
=
now
;
}
}
This module is exporting a function that is designed to be called right away so that
the value for
prefix
can be baked into the module. Note we also have another value,
lastMessage
, which is the timestamp of the last message that was logged; we use that
to calculate the time between messages.
Customizing Modules with Function Modules | 287