mirror of https://github.com/nodejs/node.git
module: fix `--preserve-symlinks-main`
Fixes resolving main module when the `argv[1]` was pointing to a symlink without its file extension. PR-URL: https://github.com/nodejs/node/pull/51312 Fixes: https://github.com/nodejs/node/issues/41000 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>pull/51432/head
parent
e0b159ee82
commit
d0e455044e
|
@ -469,15 +469,15 @@ function tryPackage(requestPath, exts, isMain, originalPath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the file exists and is not a directory if using `--preserve-symlinks` and `isMain` is false, keep symlinks
|
* Check if the file exists and is not a directory if using `--preserve-symlinks` and `isMain` is false or
|
||||||
* intact, otherwise resolve to the absolute realpath.
|
* `--preserve-symlinks-main` and `isMain` is true , keep symlinks intact, otherwise resolve to the absolute realpath.
|
||||||
* @param {string} requestPath The path to the file to load.
|
* @param {string} requestPath The path to the file to load.
|
||||||
* @param {boolean} isMain Whether the file is the main module.
|
* @param {boolean} isMain Whether the file is the main module.
|
||||||
*/
|
*/
|
||||||
function tryFile(requestPath, isMain) {
|
function tryFile(requestPath, isMain) {
|
||||||
const rc = _stat(requestPath);
|
const rc = _stat(requestPath);
|
||||||
if (rc !== 0) { return; }
|
if (rc !== 0) { return; }
|
||||||
if (getOptionValue('--preserve-symlinks') && !isMain) {
|
if (getOptionValue(isMain ? '--preserve-symlinks-main' : '--preserve-symlinks')) {
|
||||||
return path.resolve(requestPath);
|
return path.resolve(requestPath);
|
||||||
}
|
}
|
||||||
return toRealPath(requestPath);
|
return toRealPath(requestPath);
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const common = require('../common');
|
const { spawnPromisified, skip } = require('../common');
|
||||||
const { spawn } = require('child_process');
|
|
||||||
const assert = require('assert');
|
|
||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
const tmpdir = require('../common/tmpdir');
|
const tmpdir = require('../common/tmpdir');
|
||||||
|
|
||||||
|
// Invoke the main file via a symlink. In this case --preserve-symlinks-main
|
||||||
|
// dictates that it'll resolve relative imports in the main file relative to
|
||||||
|
// the symlink, and not relative to the symlink target; the file structure set
|
||||||
|
// up below requires this to not crash when loading ./submodule_link.js
|
||||||
|
|
||||||
|
const assert = require('node:assert');
|
||||||
|
const fs = require('node:fs');
|
||||||
|
const path = require('node:path');
|
||||||
|
const { execPath } = require('node:process');
|
||||||
|
const { describe, it } = require('node:test');
|
||||||
|
|
||||||
tmpdir.refresh();
|
tmpdir.refresh();
|
||||||
const tmpDir = tmpdir.path;
|
const tmpDir = tmpdir.path;
|
||||||
|
|
||||||
|
@ -14,7 +21,7 @@ fs.mkdirSync(path.join(tmpDir, 'nested'));
|
||||||
fs.mkdirSync(path.join(tmpDir, 'nested2'));
|
fs.mkdirSync(path.join(tmpDir, 'nested2'));
|
||||||
|
|
||||||
const entry = path.join(tmpDir, 'nested', 'entry.js');
|
const entry = path.join(tmpDir, 'nested', 'entry.js');
|
||||||
const entry_link_absolute_path = path.join(tmpDir, 'link.js');
|
const entry_link_absolute_path = path.join(tmpDir, 'index.js');
|
||||||
const submodule = path.join(tmpDir, 'nested2', 'submodule.js');
|
const submodule = path.join(tmpDir, 'nested2', 'submodule.js');
|
||||||
const submodule_link_absolute_path = path.join(tmpDir, 'submodule_link.js');
|
const submodule_link_absolute_path = path.join(tmpDir, 'submodule_link.js');
|
||||||
|
|
||||||
|
@ -31,27 +38,39 @@ try {
|
||||||
fs.symlinkSync(submodule, submodule_link_absolute_path);
|
fs.symlinkSync(submodule, submodule_link_absolute_path);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code !== 'EPERM') throw err;
|
if (err.code !== 'EPERM') throw err;
|
||||||
common.skip('insufficient privileges for symlinks');
|
skip('insufficient privileges for symlinks');
|
||||||
}
|
}
|
||||||
|
|
||||||
function doTest(flags, done) {
|
describe('Invoke the main file via a symlink.', { concurrency: true }, () => {
|
||||||
// Invoke the main file via a symlink. In this case --preserve-symlinks-main
|
it('should resolve relative imports in the main file', async () => {
|
||||||
// dictates that it'll resolve relative imports in the main file relative to
|
const { code } = await spawnPromisified(execPath, [
|
||||||
// the symlink, and not relative to the symlink target; the file structure set
|
'--preserve-symlinks',
|
||||||
// up above requires this to not crash when loading ./submodule_link.js
|
'--preserve-symlinks-main',
|
||||||
spawn(process.execPath, [
|
entry_link_absolute_path,
|
||||||
'--preserve-symlinks',
|
]);
|
||||||
'--preserve-symlinks-main',
|
|
||||||
entry_link_absolute_path,
|
|
||||||
], { stdio: 'inherit' })
|
|
||||||
.on('exit', (code) => {
|
|
||||||
assert.strictEqual(code, 0);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// First test the commonjs module loader
|
assert.strictEqual(code, 0);
|
||||||
doTest([], () => {
|
});
|
||||||
// Now test the new loader
|
|
||||||
doTest([], () => {});
|
it('should resolve relative imports in the main file when file extension is omitted', async () => {
|
||||||
|
const entry_link_absolute_path_without_ext = path.join(tmpDir, 'index');
|
||||||
|
|
||||||
|
const { code } = await spawnPromisified(execPath, [
|
||||||
|
'--preserve-symlinks',
|
||||||
|
'--preserve-symlinks-main',
|
||||||
|
entry_link_absolute_path_without_ext,
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert.strictEqual(code, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve relative imports in the main file when filename(index.js) is omitted', async () => {
|
||||||
|
const { code } = await spawnPromisified(execPath, [
|
||||||
|
'--preserve-symlinks',
|
||||||
|
'--preserve-symlinks-main',
|
||||||
|
tmpDir,
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert.strictEqual(code, 0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue