Skip to content

Require explicit require() registration? (And maybe local only?) #2323

Description

@aseemk

(Pun intended in title.)

Node's local module system is great because it allows local dependencies, almost eliminating worries of version conflicts or shared global state.

But one big exception is require() extension registrations, including .coffee -- any code that has require('coffee-script') affects global state for the entire running app, because CoffeeScript automatically registers its extension upon execution:

https://github.com/jashkenas/coffee-script/blob/1.3.1/src/coffee-script.coffee#L15-L21

This can and has led to version conflicts: one module depends on one version of CoffeeScript and require()s it, while another module depends on a different version of CoffeeScript and require()s it.

Unfortunately, there's no way I can think of to fix this problem today for modules that are already published. That ship has sailed.

I'm proposing we fix it going forward. At the very least, I'd like to recommend that registering CoffeeScript's require() extension handler be an explicit operation. E.g.:

// strawman 1:
require('coffee-script').register();
// strawman 2:
require('coffee-script/require');

This would at least prevent code that uses CoffeeScript's compiling API directly (e.g. connect-assets/snockets compiler middleware) from unnecessarily setting or overwriting an extension handler.

And hopefully it, along with documentation on this matter, would also make it more explicit to module authors that this affects global state.

But ideally, we could go further and ensure our require() handler only had a local effect instead of a global one. This isn't trivial to do -- require.extensions is global, and Node's module system is locked -- but I think it might be possible with some engineering.

I'll share some thoughts on how in a comment, but I wanted to get this conversation started and an issue formalized. What do you guys think of the goals, and of explicit registration in particular?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions