diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index eb247a2248955b..8a8346fcbeb1eb 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -681,6 +681,7 @@ export const configDefaults = Object.freeze({ noExternal: [], external: [], preserveSymlinks: false, + tsconfigPaths: false, alias: [], }, @@ -1934,6 +1935,17 @@ assetFileNames isn't equal for every build.rollupOptions.output. A single patter ) } + if ( + resolved.resolve.tsconfigPaths && + resolved.experimental.enableNativePlugin === false + ) { + resolved.logger.warn( + colors.yellow(` +(!) resolve.tsconfigPaths is set to true, but native plugins are disabled. To use resolve.tsconfigPaths, please enable native plugins via experimental.enableNativePlugin. +`), + ) + } + return resolved } @@ -2177,6 +2189,7 @@ async function bundleConfigFile( dedupe: [], extensions: configDefaults.resolve.extensions, preserveSymlinks: false, + tsconfigPaths: false, packageCache, isRequire, builtins: nodeLikeBuiltins, diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index 6780894acaa24a..21de6da3556bef 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -114,6 +114,15 @@ export interface ResolveOptions extends EnvironmentResolveOptions { * @default false */ preserveSymlinks?: boolean + /** + * Enable tsconfig paths resolution + * + * This option does not have any effect if `experimental.enableNativePlugin` is set to `false`. + * + * @default false + * @experimental + */ + tsconfigPaths?: boolean } interface ResolvePluginOptions { @@ -266,7 +275,7 @@ export function oxcResolvePlugin( tryIndex: options.tryIndex ?? true, tryPrefix: options.tryPrefix, preserveSymlinks: options.preserveSymlinks, - tsconfigPaths: false, + tsconfigPaths: options.tsconfigPaths, }, environmentConsumer: partialEnv.config.consumer, environmentName: partialEnv.name, diff --git a/packages/vite/src/node/ssr/fetchModule.ts b/packages/vite/src/node/ssr/fetchModule.ts index fabeaaa1e716d8..5c9aac410eddfe 100644 --- a/packages/vite/src/node/ssr/fetchModule.ts +++ b/packages/vite/src/node/ssr/fetchModule.ts @@ -57,6 +57,7 @@ export async function fetchModule( extensions: ['.js', '.cjs', '.json'], dedupe, preserveSymlinks, + tsconfigPaths: false, isBuild: false, isProduction, root, diff --git a/playground/resolve-tsconfig-paths/__tests__/resolve.spec.ts b/playground/resolve-tsconfig-paths/__tests__/resolve.spec.ts new file mode 100644 index 00000000000000..6e4f81d4473d40 --- /dev/null +++ b/playground/resolve-tsconfig-paths/__tests__/resolve.spec.ts @@ -0,0 +1,14 @@ +import { expect, test } from 'vitest' +import { page } from '~utils' + +test('import from .ts', async () => { + await expect.poll(() => page.textContent('.ts')).toMatch('[success]') +}) + +test('import from .js', async () => { + await expect.poll(() => page.textContent('.js')).toMatch('[success]') +}) + +test('fallback works', async () => { + await expect.poll(() => page.textContent('.fallback')).toMatch('[success]') +}) diff --git a/playground/resolve-tsconfig-paths/fallback/fallback.js b/playground/resolve-tsconfig-paths/fallback/fallback.js new file mode 100644 index 00000000000000..3407a59f7c86ac --- /dev/null +++ b/playground/resolve-tsconfig-paths/fallback/fallback.js @@ -0,0 +1 @@ +export default '[success] imported from fallback' diff --git a/playground/resolve-tsconfig-paths/index.html b/playground/resolve-tsconfig-paths/index.html new file mode 100644 index 00000000000000..7dd53fe111dc27 --- /dev/null +++ b/playground/resolve-tsconfig-paths/index.html @@ -0,0 +1,25 @@ +