Skip to content

Commit 917427a

Browse files
authored
Merge pull request #342 from tkskto/feat/tsconfig-support
Feat/tsconfig support
2 parents 3168e92 + 54b86b1 commit 917427a

File tree

11 files changed

+120
-5
lines changed

11 files changed

+120
-5
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"commander": "10.0.1",
5454
"ejs": "3.1.9",
5555
"express": "4.19.2",
56+
"get-tsconfig": "4.7.3",
5657
"globby": "13.2.2",
5758
"mkdirp": "3.0.1",
5859
"opener": "1.5.2",

rollup.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export default [
4949
'ws',
5050
'express',
5151
'ejs',
52+
'get-tsconfig',
5253
],
5354
plugins: [
5455
json(),

src/server/Model.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ class Model {
1111

1212
private _isSilentMode = false;
1313

14+
private _tsconfigPathMapping = new Map<string, string>();
15+
1416
get resourceRoot(): string {
1517
return this._resourceRoot;
1618
}
@@ -50,6 +52,14 @@ class Model {
5052
set isSilentMode(value: boolean) {
5153
this._isSilentMode = value;
5254
}
55+
56+
get tsconfigPathMapping(): Map<string, string> {
57+
return this._tsconfigPathMapping;
58+
}
59+
60+
set tsconfigPathMapping(paths: Map<string, string>) {
61+
this._tsconfigPathMapping = paths;
62+
}
5363
}
5464

5565
export const model = new Model();

src/server/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import {fileCounter} from './FileCounter';
99
import {writeFileExtra, writeHTML} from './Output';
1010
import {globby} from 'globby';
1111
import path from 'path';
12+
import {getTsconfig} from 'get-tsconfig';
13+
import {getTsConfigPathMapping} from './utils';
1214

1315
// TODO: add log system
1416
// TODO: add error system
@@ -53,6 +55,14 @@ export const analyzeFromCLI = async (): Promise<void> => {
5355
model.port = argv.port;
5456
model.isSilentMode = argv.silent || false;
5557

58+
const tsconfig = getTsconfig(argv.dir);
59+
60+
if (tsconfig !== null && tsconfig.config.compilerOptions) {
61+
const pathMaps = getTsConfigPathMapping(tsconfig.config.compilerOptions);
62+
63+
model.tsconfigPathMapping = pathMaps;
64+
}
65+
5666
if (argv.format !== FORMAT.BROWSER && argv.format !== FORMAT.JSON && argv.format !== FORMAT.BOTH) {
5767
console.error(`not support ${argv.format} format.`);
5868
}

src/server/utils.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import {
66
import {Token} from 'vue-eslint-parser/ast/tokens';
77
import {model} from './Model';
88
import {existsSync} from 'fs';
9-
import {resolve, extname, dirname} from 'path';
9+
import {resolve, extname, dirname, normalize} from 'path';
10+
import {type TsConfigJson} from 'get-tsconfig';
1011

1112
/**
1213
* get only Import Declaration syntax.
@@ -94,11 +95,28 @@ export const resolveFile = (_filename: string, _currentFileName: string): string
9495
filename = resolve(dirnameOfCurrentFile, _filename);
9596
} else if (_filename.startsWith('./')) {
9697
filename = `${dirnameOfCurrentFile}/${_filename.replace(/\.\/|/ug, '')}`;
98+
} else if (model.tsconfigPathMapping.size > 0) {
99+
// `@@` should be processed before `@`
100+
const keys = Array.from(model.tsconfigPathMapping.keys()).sort().reverse();
101+
102+
for (let index = 0; index < keys.length; index++) {
103+
const key = keys[index];
104+
const replaceTo = model.tsconfigPathMapping.get(key);
105+
106+
if (_filename.startsWith(key) && replaceTo) {
107+
filename = _filename.replace(key, replaceTo);
108+
109+
break;
110+
}
111+
}
97112
} else if (_filename.startsWith('~') || _filename.startsWith('@')) {
98113
filename = _filename.replace('~', model.resourceRoot).replace('@', model.resourceRoot);
99114
}
100115

116+
// filename is empty when import third-party script
101117
if (filename) {
118+
filename = normalize(filename);
119+
102120
if (extname(filename) === '') {
103121
if (existsSync(`${filename}.vue`)) {
104122
return `${filename}.vue`;
@@ -112,3 +130,21 @@ export const resolveFile = (_filename: string, _currentFileName: string): string
112130

113131
return filename;
114132
};
133+
134+
export const getTsConfigPathMapping = (compilerOptions: TsConfigJson.CompilerOptions): Map<string, string> => {
135+
const {paths, baseUrl} = compilerOptions;
136+
const pathMaps = new Map<string, string>();
137+
138+
if (!baseUrl || !paths) {
139+
return pathMaps;
140+
}
141+
142+
for (const key in paths) {
143+
if (Object.hasOwn(paths, key)) {
144+
// only use the first path for now.
145+
pathMaps.set(key.replace('/*', ''), resolve(model.resourceRoot, baseUrl, paths[key][0].replace('/*', '')));
146+
}
147+
}
148+
149+
return pathMaps;
150+
};
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<template>
2+
<div></div>
3+
</template>
4+
<script setup>
5+
import child from '@@/test/components/child.vue';
6+
</script>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<template>
2+
<div></div>
3+
</template>
4+
<script setup>
5+
import child from '~~/test/components/child.vue';
6+
</script>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<template>
2+
<div></div>
3+
</template>
4+
<script setup>
5+
import child from '~/test/components/child.vue';
6+
</script>

test/specs/resolveFile.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {resolveFile} from '../../src/server/utils';
2+
import {model} from '../../src/server/Model';
3+
4+
describe('resolveFile', () => {
5+
beforeAll(() => {
6+
const pathMaps = new Map<string, string>();
7+
8+
pathMaps.set('@', process.cwd());
9+
pathMaps.set('@@', process.cwd());
10+
pathMaps.set('~', `${process.cwd()}/`);
11+
12+
model.tsconfigPathMapping = pathMaps;
13+
});
14+
15+
it('start with @', () => {
16+
const result = resolveFile('@/test/components/child.vue', '/test/fixture/declarationTest/importOneWithTypeScript.vue');
17+
18+
expect(result).toBe(`${process.cwd()}/test/components/child.vue`);
19+
});
20+
21+
it('start with @@', () => {
22+
const result = resolveFile('@@/test/components/child.vue', '/test/fixture/declarationTest/importOneWithTypeScript.vue');
23+
24+
expect(result).toBe(`${process.cwd()}/test/components/child.vue`);
25+
});
26+
27+
it('start with ~', () => {
28+
const result = resolveFile('~/test/components/child.vue', '/test/fixture/declarationTest/importOneWithTypeScript.vue');
29+
30+
expect(result).toBe(`${process.cwd()}/test/components/child.vue`);
31+
});
32+
});

test/tsconfig.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"compilerOptions": {
3+
"baseUrl": "..",
4+
"paths": {
5+
"@@/*": ["./*"],
6+
"@/*": ["./*"],
7+
"~/*": ["./*"],
8+
"~~/*": ["./*"],
9+
}
10+
}
11+
}

0 commit comments

Comments
 (0)