Skip to content

Commit ee5f940

Browse files
authored
(fix) check path aliases (#471)
If a path alias starts with "/", it is recognized as an absolute path by the paths library. Therefore virtual svelte files with such paths were resolved with the normal tsSys. This fix adds an additional check for the path aliases. #468
1 parent cc6205d commit ee5f940

File tree

2 files changed

+68
-2
lines changed

2 files changed

+68
-2
lines changed

packages/language-server/src/plugins/typescript/module-loader.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export function createSvelteModuleLoader(
6767
) {
6868
const svelteSys = createSvelteSys(getSnapshot);
6969
const moduleCache = new ModuleResolutionCache();
70+
const pathAliases = getPathAliases(compilerOptions.paths);
7071

7172
return {
7273
fileExists: svelteSys.fileExists,
@@ -98,7 +99,7 @@ export function createSvelteModuleLoader(
9899
): ts.ResolvedModule | undefined {
99100
// In the normal case, delegate to ts.resolveModuleName.
100101
// In the relative-imported.svelte case, delegate to our own svelte module loader.
101-
if (isAbsolute(name) || !isSvelteFilePath(name)) {
102+
if (isAbsolutePath(name) || !isSvelteFilePath(name)) {
102103
return ts.resolveModuleName(name, containingFile, compilerOptions, ts.sys)
103104
.resolvedModule;
104105
}
@@ -122,4 +123,17 @@ export function createSvelteModuleLoader(
122123
};
123124
return resolvedSvelteModule;
124125
}
126+
127+
function isAbsolutePath(path: string) {
128+
return isAbsolute(path) && !pathAliases.some((p) => path.startsWith(p));
129+
}
130+
131+
function getPathAliases(paths: ts.MapLike<string[]> | undefined) {
132+
return Object.keys(paths || {}).map((key) => {
133+
if (key.endsWith('*')) {
134+
key = key.substr(0, key.length - 1);
135+
}
136+
return key;
137+
});
138+
}
125139
}

packages/language-server/test/plugins/typescript/module-loader.test.ts

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe('createSvelteModuleLoader', () => {
2323
const svelteSys = <any>'svelteSys';
2424
sinon.stub(svS, 'createSvelteSys').returns(svelteSys);
2525

26-
const compilerOptions: ts.CompilerOptions = { strict: true };
26+
const compilerOptions: ts.CompilerOptions = { strict: true, paths: { '/@/*': [] } };
2727
const moduleResolver = createSvelteModuleLoader(getSvelteSnapshotStub, compilerOptions);
2828

2929
return {
@@ -55,6 +55,26 @@ describe('createSvelteModuleLoader', () => {
5555
]);
5656
});
5757

58+
it('uses tsSys for normal files part of TS aliases', async () => {
59+
const resolvedModule: ts.ResolvedModuleFull = {
60+
extension: ts.Extension.Ts,
61+
resolvedFileName: 'filename.ts',
62+
};
63+
const { resolveStub, moduleResolver, compilerOptions } = setup(resolvedModule);
64+
const result = moduleResolver.resolveModuleNames(
65+
['/@/normal'],
66+
'C:/somerepo/somefile.svelte',
67+
);
68+
69+
assert.deepStrictEqual(result, [resolvedModule]);
70+
assert.deepStrictEqual(resolveStub.getCall(0).args, [
71+
'/@/normal',
72+
'C:/somerepo/somefile.svelte',
73+
compilerOptions,
74+
ts.sys,
75+
]);
76+
});
77+
5878
it('uses svelte module loader for virtual svelte files', async () => {
5979
const resolvedModule: ts.ResolvedModuleFull = {
6080
extension: ts.Extension.Ts,
@@ -87,6 +107,38 @@ describe('createSvelteModuleLoader', () => {
87107
assert.deepStrictEqual(getSvelteSnapshotStub.getCall(0).args, ['filename.svelte']);
88108
});
89109

110+
it('uses svelte module loader for virtual svelte files with TS path aliases', async () => {
111+
const resolvedModule: ts.ResolvedModuleFull = {
112+
extension: ts.Extension.Ts,
113+
resolvedFileName: 'filename.svelte.ts',
114+
};
115+
const {
116+
resolveStub,
117+
svelteSys,
118+
moduleResolver,
119+
compilerOptions,
120+
getSvelteSnapshotStub,
121+
} = setup(resolvedModule);
122+
const result = moduleResolver.resolveModuleNames(
123+
['/@/svelte.svelte'],
124+
'C:/somerepo/somefile.svelte',
125+
);
126+
127+
assert.deepStrictEqual(result, [
128+
<ts.ResolvedModuleFull>{
129+
extension: ts.Extension.Jsx,
130+
resolvedFileName: 'filename.svelte',
131+
},
132+
]);
133+
assert.deepStrictEqual(resolveStub.getCall(0).args, [
134+
'/@/svelte.svelte',
135+
'C:/somerepo/somefile.svelte',
136+
compilerOptions,
137+
svelteSys,
138+
]);
139+
assert.deepStrictEqual(getSvelteSnapshotStub.getCall(0).args, ['filename.svelte']);
140+
});
141+
90142
it('uses cache if module was already resolved before', async () => {
91143
const resolvedModule: ts.ResolvedModuleFull = {
92144
extension: ts.Extension.Ts,

0 commit comments

Comments
 (0)