or similar (you can obviously tighten this code up, too; I'm just being very explicit). Tada, you're injecting your test stubs in place of the real library when running in test.
For the actual production use that a DI framework gives you, you can do similar, or manually set things up, or create a layer of indirection yourself, that only applies where you need it (say an IIFE that has the logic to determine which implementation to pull in, and return that function/module as appropriate).
There's also stuff like rewire [0], which lets you change required values inside modules. Although every time I've tried it, I found it created more problems than it was solving.
For the actual production use that a DI framework gives you, you can do similar, or manually set things up, or create a layer of indirection yourself, that only applies where you need it (say an IIFE that has the logic to determine which implementation to pull in, and return that function/module as appropriate).
But this is, as you say, largely tangential.