diff --git a/.changeset/mighty-students-develop.md b/.changeset/mighty-students-develop.md new file mode 100644 index 000000000000..cbffb0dea70d --- /dev/null +++ b/.changeset/mighty-students-develop.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +Handle windows paths and regexp chars in kit.alias diff --git a/packages/kit/src/vite/utils.js b/packages/kit/src/vite/utils.js index 6c62d2636d60..4e9ae7543878 100644 --- a/packages/kit/src/vite/utils.js +++ b/packages/kit/src/vite/utils.js @@ -2,6 +2,7 @@ import fs from 'fs'; import path from 'path'; import { loadConfigFromFile, loadEnv, normalizePath } from 'vite'; import { runtime_directory } from '../core/utils.js'; +import { posixify } from '../utils/filesystem.js'; /** * @param {import('vite').ResolvedConfig} config @@ -113,18 +114,22 @@ export function get_aliases(config) { ]; for (let [key, value] of Object.entries(config.alias)) { + value = posixify(value); if (value.endsWith('/*')) { value = value.slice(0, -2); } if (key.endsWith('/*')) { // Doing just `{ find: key.slice(0, -2) ,..}` would mean `import .. from "key"` would also be matched, which we don't want alias.push({ - find: new RegExp(`^${key.slice(0, -2)}\\/(.+)$`), + find: new RegExp(`^${escape_for_regexp(key.slice(0, -2))}\\/(.+)$`), replacement: `${path.resolve(value)}/$1` }); } else if (key + '/*' in config.alias) { // key and key/* both exist -> the replacement for key needs to happen _only_ on import .. from "key" - alias.push({ find: new RegExp(`^${key}$`), replacement: path.resolve(value) }); + alias.push({ + find: new RegExp(`^${escape_for_regexp(key)}$`), + replacement: path.resolve(value) + }); } else { alias.push({ find: key, replacement: path.resolve(value) }); } @@ -133,6 +138,13 @@ export function get_aliases(config) { return alias; } +/** + * @param {string} str + */ +function escape_for_regexp(str) { + return str.replace(/[.*+?^${}()|[\]\\]/g, (match) => '\\' + match); +} + /** * Given an entry point like [cwd]/src/hooks, returns a filename like [cwd]/src/hooks.js or [cwd]/src/hooks/index.js * @param {string} entry diff --git a/packages/kit/src/vite/utils.spec.js b/packages/kit/src/vite/utils.spec.js index a566434f53a4..6fa338f648f9 100644 --- a/packages/kit/src/vite/utils.spec.js +++ b/packages/kit/src/vite/utils.spec.js @@ -207,7 +207,15 @@ test('merge resolve.alias', () => { test('transform kit.alias to resolve.alias', () => { const config = validate_config({ - kit: { alias: { simpleKey: 'simple/value', key: 'value', 'key/*': 'value/*' } } + kit: { + alias: { + simpleKey: 'simple/value', + key: 'value', + 'key/*': 'value/*', + $regexChar: 'windows\\path', + '$regexChar/*': 'windows\\path\\*' + } + } }); const transformed = get_aliases(config.kit).map((entry) => { @@ -227,7 +235,9 @@ test('transform kit.alias to resolve.alias', () => { { find: '$lib', replacement: 'src/lib' }, { find: 'simpleKey', replacement: 'simple/value' }, { find: /^key$/.toString(), replacement: 'value' }, - { find: /^key\/(.+)$/.toString(), replacement: 'value/$1' } + { find: /^key\/(.+)$/.toString(), replacement: 'value/$1' }, + { find: /^\$regexChar$/.toString(), replacement: 'windows/path' }, + { find: /^\$regexChar\/(.+)$/.toString(), replacement: 'windows/path/$1' } ]); });