vite-plugin-simple-tsconfig-alias 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +78 -43
- package/dist/index.d.mts +19 -0
- package/dist/index.mjs +86 -0
- package/package.json +68 -7
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Ray <https://github.com/so1ve>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,45 +1,80 @@
|
|
|
1
1
|
# vite-plugin-simple-tsconfig-alias
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/vite-plugin-simple-tsconfig-alias)
|
|
4
|
+
|
|
5
|
+
A simple Vite plugin to resolve tsconfig paths as aliases.
|
|
6
|
+
|
|
7
|
+
## 💎 Features
|
|
8
|
+
|
|
9
|
+
- Reads `compilerOptions.paths` from one or more tsconfig files.
|
|
10
|
+
- Supports exact mappings (no `*`), e.g. `"@": ["./src"]`.
|
|
11
|
+
- Supports single-star wildcard mappings, e.g. `"@/*": ["./src/*"]`.
|
|
12
|
+
- The `*` is converted to a RegExp capture group on `find` and `$1` replacements.
|
|
13
|
+
- Merges aliases into `config.resolve.alias` early (`enforce: "pre"`).
|
|
14
|
+
- Aliases from tsconfig are prepended so they take precedence over existing ones.
|
|
15
|
+
- `baseUrl` behavior:
|
|
16
|
+
- If `baseUrl` is set in a tsconfig, targets are resolved relative to it.
|
|
17
|
+
- If not set, targets are resolved relative to that tsconfig's directory.
|
|
18
|
+
|
|
19
|
+
## 📦 Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
$ npm install vite-plugin-simple-tsconfig-alias
|
|
23
|
+
$ yarn add vite-plugin-simple-tsconfig-alias
|
|
24
|
+
$ pnpm add vite-plugin-simple-tsconfig-alias
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 🚀 Usage
|
|
28
|
+
|
|
29
|
+
### Vite Plugin
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
// vite.config.ts
|
|
33
|
+
import { defineConfig } from "vite";
|
|
34
|
+
import TsconfigAlias from "vite-plugin-simple-tsconfig-alias";
|
|
35
|
+
|
|
36
|
+
export default defineConfig({
|
|
37
|
+
plugins: [
|
|
38
|
+
TsconfigAlias({
|
|
39
|
+
// Optional: root directory of the project (default: process.cwd())
|
|
40
|
+
root: process.cwd(),
|
|
41
|
+
// Optional: tsconfig file names to read (default: ["tsconfig.json"])
|
|
42
|
+
configNames: ["tsconfig.json", "tsconfig.paths.json"],
|
|
43
|
+
}),
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Programmatic API
|
|
49
|
+
|
|
50
|
+
You can also use the underlying functions to parse and merge aliases manually. This makes it possible to be used in other contexts beyond Vite plugins, like other bundlers that doesn't have a `config` hook.
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import {
|
|
54
|
+
mergeAliases,
|
|
55
|
+
parseTsconfigAliases,
|
|
56
|
+
} from "vite-plugin-simple-tsconfig-alias";
|
|
57
|
+
|
|
58
|
+
// Parse aliases from tsconfig files
|
|
59
|
+
const aliases = parseTsconfigAliases(process.cwd(), ["tsconfig.json"]);
|
|
60
|
+
|
|
61
|
+
// Merge with existing Vite aliases
|
|
62
|
+
const finalAliases = mergeAliases(
|
|
63
|
+
[{ find: "@custom", replacement: "./src/custom" }],
|
|
64
|
+
aliases,
|
|
65
|
+
);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## ⚠️ Limitations
|
|
69
|
+
|
|
70
|
+
- Only the first target in a `paths` entry is used. If you rely on fallbacks like `"@/*": ["./src/*", "./generated/*"]`, only `./src/*` will be applied.
|
|
71
|
+
- Path mapping transforms are only injected into Vite's resolver.
|
|
72
|
+
- TypeScript / vue-tsc still use tsconfig directly; keep tsconfig correct.
|
|
73
|
+
- Does not support Vite's `\0` virtual module prefix use cases.
|
|
74
|
+
- Wildcard handling is generic regex-based and may be looser than TypeScript's own matching in edge cases (multiple `*` segments, unusual patterns).
|
|
75
|
+
- If the tsconfig file can't be read/parsed, it is silently skipped.
|
|
76
|
+
- Windows paths: Replacements are absolute filesystem paths produced by Node's `path.resolve`.
|
|
77
|
+
|
|
78
|
+
## 📝 License
|
|
79
|
+
|
|
80
|
+
[MIT](./LICENSE). Made with ❤️ by [Ray](https://github.com/so1ve)
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
|
|
3
|
+
//#region src/types.d.ts
|
|
4
|
+
interface Alias {
|
|
5
|
+
find: string | RegExp;
|
|
6
|
+
replacement: string;
|
|
7
|
+
}
|
|
8
|
+
type AliasOptions = readonly Alias[] | Record<string, string>;
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/index.d.ts
|
|
11
|
+
interface TsconfigAliasPluginOptions {
|
|
12
|
+
root?: string;
|
|
13
|
+
configNames?: string[];
|
|
14
|
+
}
|
|
15
|
+
declare function parseTsconfigAliases(projectRoot: string, configNames: string[]): Alias[];
|
|
16
|
+
declare function mergeAliases(existing: AliasOptions | undefined, incoming: Alias[]): Alias[];
|
|
17
|
+
declare function TsconfigAlias(options?: TsconfigAliasPluginOptions): Plugin;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { TsconfigAliasPluginOptions, TsconfigAlias as default, mergeAliases, parseTsconfigAliases };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import ts from "typescript";
|
|
4
|
+
|
|
5
|
+
//#region src/index.ts
|
|
6
|
+
const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7
|
+
function buildStarRegex(pattern) {
|
|
8
|
+
const parts = pattern.split("*");
|
|
9
|
+
const starCount = parts.length - 1;
|
|
10
|
+
const source = `^${parts.map(escapeRegExp).join("(.*)")}$`;
|
|
11
|
+
return {
|
|
12
|
+
find: new RegExp(source),
|
|
13
|
+
starCount
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function buildReplacement(target, starCount) {
|
|
17
|
+
let replacement = target;
|
|
18
|
+
for (let i = 1; i <= starCount; i += 1) replacement = replacement.replace("*", `$${i}`);
|
|
19
|
+
return replacement;
|
|
20
|
+
}
|
|
21
|
+
function readTsconfig(filePath) {
|
|
22
|
+
if (!fs.existsSync(filePath)) return null;
|
|
23
|
+
const read = ts.readConfigFile(filePath, ts.sys.readFile);
|
|
24
|
+
if (read.error) return null;
|
|
25
|
+
return ts.parseJsonConfigFileContent(read.config, ts.sys, path.dirname(filePath), void 0, filePath);
|
|
26
|
+
}
|
|
27
|
+
function toArray(value) {
|
|
28
|
+
if (Array.isArray(value)) return value.filter((v) => typeof v === "string");
|
|
29
|
+
if (typeof value === "string") return [value];
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
function parseTsconfigAliases(projectRoot, configNames) {
|
|
33
|
+
const aliases = [];
|
|
34
|
+
for (const configName of configNames) {
|
|
35
|
+
const configPath = path.resolve(projectRoot, configName);
|
|
36
|
+
const parsed = readTsconfig(configPath);
|
|
37
|
+
if (!parsed) continue;
|
|
38
|
+
const baseUrl = parsed.options.baseUrl ?? path.dirname(configPath);
|
|
39
|
+
const paths = parsed.options.paths ?? {};
|
|
40
|
+
for (const [from, to] of Object.entries(paths)) {
|
|
41
|
+
const firstTarget = toArray(to)[0];
|
|
42
|
+
if (!firstTarget) continue;
|
|
43
|
+
const absoluteTarget = path.resolve(baseUrl, firstTarget);
|
|
44
|
+
if (!from.includes("*")) {
|
|
45
|
+
aliases.push({
|
|
46
|
+
find: from,
|
|
47
|
+
replacement: absoluteTarget
|
|
48
|
+
});
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const { find, starCount } = buildStarRegex(from);
|
|
52
|
+
aliases.push({
|
|
53
|
+
find,
|
|
54
|
+
replacement: buildReplacement(absoluteTarget, starCount)
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
aliases.sort((a, b) => {
|
|
59
|
+
const aLen = typeof a.find === "string" ? a.find.length : a.find.source.length;
|
|
60
|
+
return (typeof b.find === "string" ? b.find.length : b.find.source.length) - aLen;
|
|
61
|
+
});
|
|
62
|
+
return aliases;
|
|
63
|
+
}
|
|
64
|
+
function mergeAliases(existing, incoming) {
|
|
65
|
+
const normalizedExisting = existing ? Array.isArray(existing) ? [...existing] : Object.entries(existing).map(([find, replacement]) => ({
|
|
66
|
+
find,
|
|
67
|
+
replacement
|
|
68
|
+
})) : [];
|
|
69
|
+
return [...incoming, ...normalizedExisting];
|
|
70
|
+
}
|
|
71
|
+
function TsconfigAlias(options = {}) {
|
|
72
|
+
const root = options.root ?? process.cwd();
|
|
73
|
+
const configNames = options.configNames ?? ["tsconfig.json"];
|
|
74
|
+
return {
|
|
75
|
+
name: "vite-plugin-simple-tsconfig-alias",
|
|
76
|
+
enforce: "pre",
|
|
77
|
+
config(config) {
|
|
78
|
+
const aliases = parseTsconfigAliases(root, configNames);
|
|
79
|
+
config.resolve ??= {};
|
|
80
|
+
config.resolve.alias = mergeAliases(config.resolve.alias, aliases);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
//#endregion
|
|
86
|
+
export { TsconfigAlias as default, mergeAliases, parseTsconfigAliases };
|
package/package.json
CHANGED
|
@@ -1,10 +1,71 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-simple-tsconfig-alias",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"author": "Ray <i@mk1.io> (@so1ve)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "A simple Vite plugin to resolve tsconfig paths as aliases.",
|
|
5
7
|
"keywords": [
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
"vite",
|
|
9
|
+
"vite-plugin",
|
|
10
|
+
"tsconfig",
|
|
11
|
+
"alias",
|
|
12
|
+
"path-mapping"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/so1ve/vite-plugin-simple-tsconfig-alias#readme",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/so1ve/vite-plugin-simple-tsconfig-alias.git"
|
|
18
|
+
},
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/so1ve/vite-plugin-simple-tsconfig-alias/issues"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"exports": {
|
|
25
|
+
".": "./dist/index.mjs",
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"main": "./dist/index.mjs",
|
|
29
|
+
"module": "./dist/index.mjs",
|
|
30
|
+
"types": "./dist/index.d.mts",
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@antfu/ni": "^28.0.0",
|
|
39
|
+
"@so1ve/eslint-config": "^4.1.2",
|
|
40
|
+
"@so1ve/prettier-config": "^4.1.2",
|
|
41
|
+
"@types/node": "^25.0.3",
|
|
42
|
+
"@typescript/native-preview": "7.0.0-dev.20251029.1",
|
|
43
|
+
"bumpp": "^10.3.2",
|
|
44
|
+
"eslint": "^9.39.2",
|
|
45
|
+
"prettier": "^3.7.4",
|
|
46
|
+
"tsdown": "^0.18.3",
|
|
47
|
+
"typescript": "^5.9.3",
|
|
48
|
+
"vite": "^7.3.0",
|
|
49
|
+
"vitest": "^4.0.16"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"typescript": "^5",
|
|
53
|
+
"vite": "^4 || ^5 || ^6 || ^7"
|
|
54
|
+
},
|
|
55
|
+
"peerDependenciesMeta": {
|
|
56
|
+
"vite": {
|
|
57
|
+
"optional": true
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "tsdown",
|
|
62
|
+
"lint": "eslint . && prettier . --check",
|
|
63
|
+
"lint:fix": "eslint . --fix && prettier . --write",
|
|
64
|
+
"release": "bumpp --commit --push --tag",
|
|
65
|
+
"test": "vitest",
|
|
66
|
+
"typecheck": "nr typecheck:isolated && nr typecheck:non-isolated",
|
|
67
|
+
"typecheck:isolated": "tsc --noEmit --project tsconfig.isolated.json",
|
|
68
|
+
"typecheck:non-isolated": "tsgo --noEmit --project tsconfig.non-isolated.json",
|
|
69
|
+
"watch": "tsdown --watch"
|
|
70
|
+
}
|
|
71
|
+
}
|