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

feat: preserveSymlinks: 'auto' #5428

Closed
wants to merge 1 commit into from
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/rollup/types.d.ts
Expand Up @@ -590,7 +590,7 @@ export interface InputOptions {
perf?: boolean;
plugins?: InputPluginOption;
preserveEntrySignatures?: PreserveEntrySignaturesOption;
preserveSymlinks?: boolean;
preserveSymlinks?: boolean | 'auto';
shimMissingExports?: boolean;
strictDeprecations?: boolean;
treeshake?: boolean | TreeshakingPreset | TreeshakingOptions;
Expand All @@ -616,7 +616,7 @@ export interface NormalizedInputOptions {
perf: boolean;
plugins: Plugin[];
preserveEntrySignatures: PreserveEntrySignaturesOption;
preserveSymlinks: boolean;
preserveSymlinks: boolean | 'auto';
shimMissingExports: boolean;
strictDeprecations: boolean;
treeshake: false | NormalizedTreeshakingOptions;
Expand Down
35 changes: 26 additions & 9 deletions src/utils/resolveId.ts
Expand Up @@ -8,7 +8,7 @@ import { resolveIdViaPlugins } from './resolveIdViaPlugins';
export async function resolveId(
source: string,
importer: string | undefined,
preserveSymlinks: boolean,
preserveSymlinks: boolean | 'auto',
pluginDriver: PluginDriver,
moduleLoaderResolveId: ModuleLoaderResolveId,
skip: readonly { importer: string | undefined; plugin: Plugin; source: string }[] | null,
Expand Down Expand Up @@ -48,14 +48,31 @@ export async function resolveId(
// are skipped at this stage.
if (importer !== undefined && !isAbsolute(source) && source[0] !== '.') return null;

// `resolve` processes paths from right to left, prepending them until an
// absolute path is created. Absolute importees therefore shortcircuit the
// resolve call and require no special handing on our part.
// See https://nodejs.org/api/path.html#path_path_resolve_paths
return addJsExtensionIfNecessary(
importer ? resolve(dirname(importer), source) : resolve(source),
preserveSymlinks
);
switch (preserveSymlinks) {
case 'auto': {
// Try to resolve the importee.
if (!importer) return addJsExtensionIfNecessary(resolve(source), true);
const resolved = await addJsExtensionIfNecessary(resolve(dirname(importer), source), true);
if (resolved) return resolved;

// Since resolving the importee failed, see if the importer is a symlink and can be resolved.
importer = await addJsExtensionIfNecessary(resolve(importer), false);
if (!importer) return;

// Try again
return addJsExtensionIfNecessary(resolve(dirname(importer), source), true);
}
default: {
// `resolve` processes paths from right to left, prepending them until an
// absolute path is created. Absolute importees therefore shortcircuit the
// resolve call and require no special handing on our part.
// See https://nodejs.org/api/path.html#path_path_resolve_paths
return addJsExtensionIfNecessary(
importer ? resolve(dirname(importer), source) : resolve(source),
preserveSymlinks
);
}
}
}

async function addJsExtensionIfNecessary(
Expand Down
7 changes: 7 additions & 0 deletions test/function/samples/preserve-symlink-auto-follow/_config.js
@@ -0,0 +1,7 @@
module.exports = defineTest({
skipIfWindows: true,
description: 'auto symlinks',
options: {
preserveSymlinks: 'auto'
}
});
1 change: 1 addition & 0 deletions test/function/samples/preserve-symlink-auto-follow/foo.js
2 changes: 2 additions & 0 deletions test/function/samples/preserve-symlink-auto-follow/main.js
@@ -0,0 +1,2 @@
import foo from './foo.js';
assert.equal(foo, 'BAZ');
@@ -0,0 +1,3 @@
export default function () {
return 'BAZ';
}
@@ -0,0 +1,2 @@
import bar from './bar.js';
export default bar();
@@ -0,0 +1,7 @@
module.exports = defineTest({
skipIfWindows: true,
description: 'auto symlinks',
options: {
preserveSymlinks: 'auto'
}
});
3 changes: 3 additions & 0 deletions test/function/samples/preserve-symlink-auto-no-follow/bar.js
@@ -0,0 +1,3 @@
export default function () {
return 'BAR';
}
2 changes: 2 additions & 0 deletions test/function/samples/preserve-symlink-auto-no-follow/main.js
@@ -0,0 +1,2 @@
import foo from './foo.js';
assert.equal(foo, 'BAR');
@@ -0,0 +1,3 @@
export default function () {
return 'BAZ';
}
@@ -0,0 +1,2 @@
import bar from './bar.js';
export default bar();