Skip to content

Commit b882e1c

Browse files
authored
[fix] Handle windows paths and regexp chars in kit.alias (#6034)
Fixes #5962
1 parent e5f6bf1 commit b882e1c

File tree

3 files changed

+31
-4
lines changed

3 files changed

+31
-4
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
Handle windows paths and regexp chars in kit.alias

packages/kit/src/vite/utils.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import fs from 'fs';
22
import path from 'path';
33
import { loadConfigFromFile, loadEnv, normalizePath } from 'vite';
44
import { runtime_directory } from '../core/utils.js';
5+
import { posixify } from '../utils/filesystem.js';
56

67
/**
78
* @param {import('vite').ResolvedConfig} config
@@ -113,18 +114,22 @@ export function get_aliases(config) {
113114
];
114115

115116
for (let [key, value] of Object.entries(config.alias)) {
117+
value = posixify(value);
116118
if (value.endsWith('/*')) {
117119
value = value.slice(0, -2);
118120
}
119121
if (key.endsWith('/*')) {
120122
// Doing just `{ find: key.slice(0, -2) ,..}` would mean `import .. from "key"` would also be matched, which we don't want
121123
alias.push({
122-
find: new RegExp(`^${key.slice(0, -2)}\\/(.+)$`),
124+
find: new RegExp(`^${escape_for_regexp(key.slice(0, -2))}\\/(.+)$`),
123125
replacement: `${path.resolve(value)}/$1`
124126
});
125127
} else if (key + '/*' in config.alias) {
126128
// key and key/* both exist -> the replacement for key needs to happen _only_ on import .. from "key"
127-
alias.push({ find: new RegExp(`^${key}$`), replacement: path.resolve(value) });
129+
alias.push({
130+
find: new RegExp(`^${escape_for_regexp(key)}$`),
131+
replacement: path.resolve(value)
132+
});
128133
} else {
129134
alias.push({ find: key, replacement: path.resolve(value) });
130135
}
@@ -133,6 +138,13 @@ export function get_aliases(config) {
133138
return alias;
134139
}
135140

141+
/**
142+
* @param {string} str
143+
*/
144+
function escape_for_regexp(str) {
145+
return str.replace(/[.*+?^${}()|[\]\\]/g, (match) => '\\' + match);
146+
}
147+
136148
/**
137149
* Given an entry point like [cwd]/src/hooks, returns a filename like [cwd]/src/hooks.js or [cwd]/src/hooks/index.js
138150
* @param {string} entry

packages/kit/src/vite/utils.spec.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,15 @@ test('merge resolve.alias', () => {
207207

208208
test('transform kit.alias to resolve.alias', () => {
209209
const config = validate_config({
210-
kit: { alias: { simpleKey: 'simple/value', key: 'value', 'key/*': 'value/*' } }
210+
kit: {
211+
alias: {
212+
simpleKey: 'simple/value',
213+
key: 'value',
214+
'key/*': 'value/*',
215+
$regexChar: 'windows\\path',
216+
'$regexChar/*': 'windows\\path\\*'
217+
}
218+
}
211219
});
212220

213221
const transformed = get_aliases(config.kit).map((entry) => {
@@ -227,7 +235,9 @@ test('transform kit.alias to resolve.alias', () => {
227235
{ find: '$lib', replacement: 'src/lib' },
228236
{ find: 'simpleKey', replacement: 'simple/value' },
229237
{ find: /^key$/.toString(), replacement: 'value' },
230-
{ find: /^key\/(.+)$/.toString(), replacement: 'value/$1' }
238+
{ find: /^key\/(.+)$/.toString(), replacement: 'value/$1' },
239+
{ find: /^\$regexChar$/.toString(), replacement: 'windows/path' },
240+
{ find: /^\$regexChar\/(.+)$/.toString(), replacement: 'windows/path/$1' }
231241
]);
232242
});
233243

0 commit comments

Comments
 (0)