module: add createRequire method

This is an abstraction on top of creatRequireFromPath that can accept
both paths, URL Strings, and URL Objects.

PR-URL: https://github.com/nodejs/node/pull/27405
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Jan Krems <jan.krems@gmail.com>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Rich Trott <rtrott@gmail.com>
This commit is contained in:
Myles Borins 2019-04-25 00:29:22 -04:00 committed by Myles Borins
parent 8cac945126
commit 411063c6f5
No known key found for this signature in database
GPG Key ID: 933B01F40B5CA946
4 changed files with 89 additions and 4 deletions

View File

@ -2439,6 +2439,19 @@ The `_channel` property of child process objects returned by `spawn()` and
similar functions is not intended for public use. Use `ChildProcess.channel`
instead.
<a id="DEP0130"></a>
### DEP00XX: Module.createRequireFromPath()
<!-- YAML
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/27405
description: Documentation-only.
-->
Type: Documentation-only
Module.createRequireFromPath() is deprecated. Please use [`module.createRequire()`][] instead.
[`--pending-deprecation`]: cli.html#cli_pending_deprecation
[`Buffer.allocUnsafeSlow(size)`]: buffer.html#buffer_class_method_buffer_allocunsafeslow_size
[`Buffer.from(array)`]: buffer.html#buffer_class_method_buffer_from_array
@ -2486,6 +2499,7 @@ instead.
[`http.request()`]: http.html#http_http_request_options_callback
[`https.get()`]: https.html#https_https_get_options_callback
[`https.request()`]: https.html#https_https_request_options_callback
[`module.createRequire()`]: modules.html#modules_module_createrequire_filename
[`os.networkInterfaces()`]: os.html#os_os_networkinterfaces
[`os.tmpdir()`]: os.html#os_os_tmpdir
[`process.env`]: process.html#process_process_env

View File

@ -905,15 +905,36 @@ by the [module wrapper][]. To access it, require the `Module` module:
const builtin = require('module').builtinModules;
```
### module.createRequire(filename)
<!-- YAML
added: REPLACEME
-->
* `filename` {string|URL} Filename to be used to construct the require
function. Must be a file URL object, file URL string, or absolute path
string.
* Returns: {require} Require function
```js
const { createRequire } = require('module');
const requireUtil = createRequire(require.resolve('../src/utils/'));
// Require `../src/utils/some-tool`
requireUtil('./some-tool');
```
### module.createRequireFromPath(filename)
<!-- YAML
added: v10.12.0
deprecated: REPLACEME
-->
* `filename` {string} Filename to be used to construct the relative require
function.
* Returns: {require} Require function
> Stability: 0 - Deprecated: Please use [`createRequire()`][] instead.
```js
const { createRequireFromPath } = require('module');
const requireUtil = createRequireFromPath('../src/utils/');
@ -926,6 +947,7 @@ requireUtil('./some-tool');
[`Error`]: errors.html#errors_class_error
[`__dirname`]: #modules_dirname
[`__filename`]: #modules_filename
[`createRequire()`]: #modules_module_createrequire_filename
[`module` object]: #modules_the_module_object
[`path.dirname()`]: path.html#path_path_dirname_path
[exports shortcut]: #modules_exports_shortcut

View File

@ -24,7 +24,7 @@
const { JSON, Object, Reflect } = primordials;
const { NativeModule } = require('internal/bootstrap/loaders');
const { pathToFileURL } = require('internal/url');
const { pathToFileURL, fileURLToPath, URL } = require('internal/url');
const { deprecate } = require('internal/util');
const vm = require('vm');
const assert = require('internal/assert');
@ -824,7 +824,7 @@ Module.runMain = function() {
Module._load(process.argv[1], null, true);
};
Module.createRequireFromPath = (filename) => {
function createRequireFromPath(filename) {
// Allow a directory to be passed as the filename
const trailingSlash =
filename.endsWith(path.sep) || path.sep !== '/' && filename.endsWith('\\');
@ -838,7 +838,34 @@ Module.createRequireFromPath = (filename) => {
m.paths = Module._nodeModulePaths(m.path);
return makeRequireFunction(m);
};
}
Module.createRequireFromPath = createRequireFromPath;
const createRequireError = 'must be a file URL object, file URL string, or' +
'absolute path string';
function createRequire(filename) {
let filepath;
if (typeof filename === 'object' && !(filename instanceof URL)) {
throw new ERR_INVALID_ARG_VALUE('filename', filename, createRequireError);
} else if (typeof filename === 'object' ||
typeof filename === 'string' && !path.isAbsolute(filename)) {
try {
filepath = fileURLToPath(filename);
} catch {
throw new ERR_INVALID_ARG_VALUE('filename', filename,
createRequireError);
}
} else if (typeof filename !== 'string') {
throw new ERR_INVALID_ARG_VALUE('filename', filename, createRequireError);
} else {
filepath = filename;
}
return createRequireFromPath(filepath);
}
Module.createRequire = createRequire;
Module._initPaths = function() {
var homeDir;

View File

@ -4,9 +4,31 @@ require('../common');
const assert = require('assert');
const path = require('path');
const { createRequireFromPath } = require('module');
const { createRequire, createRequireFromPath } = require('module');
const p = path.resolve(__dirname, '..', 'fixtures', 'fake.js');
const u = new URL(`file://${p}`);
const req = createRequireFromPath(p);
assert.strictEqual(req('./baz'), 'perhaps I work');
const reqToo = createRequire(u);
assert.deepStrictEqual(reqToo('./experimental'), { ofLife: 42 });
assert.throws(() => {
createRequire('https://github.com/nodejs/node/pull/27405/');
}, {
code: 'ERR_INVALID_ARG_VALUE'
});
assert.throws(() => {
createRequire('../');
}, {
code: 'ERR_INVALID_ARG_VALUE'
});
assert.throws(() => {
createRequire({});
}, {
code: 'ERR_INVALID_ARG_VALUE'
});