Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

module: allow passing a directory to createRequireFromPath #23818

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/api/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,7 @@ added: v10.12.0

```js
const { createRequireFromPath } = require('module');
const requireUtil = createRequireFromPath('../src/utils');
const requireUtil = createRequireFromPath('../src/utils/');

// Require `../src/utils/some-tool`
requireUtil('./some-tool');
Expand Down
15 changes: 12 additions & 3 deletions lib/internal/modules/cjs/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -825,9 +825,18 @@ Module.runMain = function() {
};

Module.createRequireFromPath = (filename) => {
const m = new Module(filename);
m.filename = filename;
m.paths = Module._nodeModulePaths(path.dirname(filename));
// Allow a directory to be passed as the filename
const trailingSlash =
filename.endsWith(path.sep) || path.sep !== '/' && filename.endsWith('\\');

const proxyPath = trailingSlash ?
path.join(filename, 'noop.js') :
guybedford marked this conversation as resolved.
Show resolved Hide resolved
filename;

const m = new Module(proxyPath);
m.filename = proxyPath;

m.paths = Module._nodeModulePaths(m.path);
return makeRequireFunction(m);
};

Expand Down
18 changes: 18 additions & 0 deletions test/parallel/test-module-create-require-from-directory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';

require('../common');
const assert = require('assert');
const path = require('path');

const { createRequireFromPath } = require('module');

const fixPath = path.resolve(__dirname, '..', 'fixtures');
const p = path.join(fixPath, path.sep);

const req = createRequireFromPath(p);
const reqFromNotDir = createRequireFromPath(fixPath);

assert.strictEqual(req('./baz'), 'perhaps I work');
assert.throws(() => {
reqFromNotDir('./baz');
}, { code: 'MODULE_NOT_FOUND' });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd expect both of this to pass. fixtures  is a directory, so they should both work IMHO. This probably requires adding a round-trip to OS, but I don't think it could be avoided.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be a very different approach to this function, but it could work. //cc @devsnek

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to change the implementation to call stat.isDirectory() if that's the way we want to move this forward :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to get this merged, I'd suggest we stick with the current behaviour which matches the behaviour of path resolution.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to sticking to behavior that matches path... we should change this behavior in the path module if we want to fix it imho

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally think calling stat is a good idea in this case. createRequireFromPath is IMO special enough to work differently from the rest of Module.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to land this to improve the behavior and introduce the stat separately in a follow up. Is that reasonable for you @BridgeAR ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has three different open comments at the moment (actually four but two are about using stat). I personally would not land this but I won't block it either.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BridgeAR afaict all open comments are about stat, which I think should be an incremental improvement discussed separately.

Did I miss any other open comments?