auklet 0.2.0 → 0.2.2
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/dist/configLoader.js +3 -1
- package/dist/css/vite/moduleGraph/devDependency.d.ts +2 -0
- package/dist/css/vite/moduleGraph/devDependency.js +51 -0
- package/dist/css/vite/moduleGraph/persistentCache.d.ts +2 -0
- package/dist/css/vite/moduleGraph/persistentCache.js +42 -0
- package/dist/css/vite/moduleGraph/requestCache.d.ts +2 -0
- package/dist/css/vite/moduleGraph/requestCache.js +35 -8
- package/dist/css/vite/moduleGraph/styleCodeFactory.js +6 -0
- package/package.json +1 -1
package/dist/configLoader.js
CHANGED
|
@@ -6,6 +6,7 @@ import { aukletConfigFiles, isAukletConfigFile } from '#auklet/config';
|
|
|
6
6
|
const asRecord = (value) => {
|
|
7
7
|
return isPlainObject(value) ? value : null;
|
|
8
8
|
};
|
|
9
|
+
let configImportVersion = 0;
|
|
9
10
|
const assertSupportedConfigFile = (configFile) => {
|
|
10
11
|
const basename = path.basename(configFile);
|
|
11
12
|
if (isAukletConfigFile(basename))
|
|
@@ -53,7 +54,8 @@ export async function loadAukletConfig(packageRoot, options = {}) {
|
|
|
53
54
|
}
|
|
54
55
|
const url = pathToFileURL(configPath);
|
|
55
56
|
if (options.cacheBust) {
|
|
56
|
-
|
|
57
|
+
configImportVersion += 1;
|
|
58
|
+
url.searchParams.set('t', configImportVersion.toString());
|
|
57
59
|
}
|
|
58
60
|
const module = (await import(url.href));
|
|
59
61
|
return resolveAukletConfigModule(module);
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { PackageStyleContext } from '#auklet/css/vite/moduleGraph/requestCache';
|
|
2
2
|
export declare function toDevDependencyImportSpecifier(context: PackageStyleContext, specifier: string): {
|
|
3
3
|
specifier: string;
|
|
4
|
+
cacheInputFiles?: undefined;
|
|
4
5
|
watchFile?: undefined;
|
|
5
6
|
} | {
|
|
7
|
+
cacheInputFiles: string[];
|
|
6
8
|
specifier: string;
|
|
7
9
|
watchFile: string;
|
|
8
10
|
};
|
|
@@ -1,11 +1,62 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
1
3
|
import { toFsSpecifier } from '#auklet/utils';
|
|
4
|
+
const getPackageName = (specifier) => {
|
|
5
|
+
if (!specifier.startsWith('@'))
|
|
6
|
+
return specifier.split('/')[0] ?? specifier;
|
|
7
|
+
const [scope, name] = specifier.split('/');
|
|
8
|
+
if (!scope || !name)
|
|
9
|
+
return null;
|
|
10
|
+
return `${scope}/${name}`;
|
|
11
|
+
};
|
|
12
|
+
const findNodeModulesPackageRoot = (file, packageName) => {
|
|
13
|
+
const resolved = path.resolve(file);
|
|
14
|
+
const root = path.parse(resolved).root;
|
|
15
|
+
const parts = path.relative(root, resolved).split(path.sep);
|
|
16
|
+
const packageParts = packageName.split('/');
|
|
17
|
+
const packageLength = packageParts.length;
|
|
18
|
+
for (let index = parts.length - packageLength - 1; index >= 0; index -= 1) {
|
|
19
|
+
if (parts[index] !== 'node_modules')
|
|
20
|
+
continue;
|
|
21
|
+
const candidateParts = parts.slice(index + 1, index + 1 + packageLength);
|
|
22
|
+
if (candidateParts.join('/') !== packageName)
|
|
23
|
+
continue;
|
|
24
|
+
return path.join(root, ...parts.slice(0, index + 1 + packageLength));
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
};
|
|
28
|
+
const findPackageJson = (file, context, specifier) => {
|
|
29
|
+
const packageName = getPackageName(specifier);
|
|
30
|
+
if (!packageName)
|
|
31
|
+
return null;
|
|
32
|
+
const packageRoot = findNodeModulesPackageRoot(file, packageName);
|
|
33
|
+
if (!packageRoot) {
|
|
34
|
+
return path.join(context.context.packageRoot, 'node_modules', packageName, 'package.json');
|
|
35
|
+
}
|
|
36
|
+
let current = path.dirname(file);
|
|
37
|
+
let next = current;
|
|
38
|
+
const packageRootKey = path.resolve(packageRoot);
|
|
39
|
+
do {
|
|
40
|
+
const packageJson = path.join(current, 'package.json');
|
|
41
|
+
if (fs.existsSync(packageJson))
|
|
42
|
+
return packageJson;
|
|
43
|
+
if (path.resolve(current) === packageRootKey)
|
|
44
|
+
break;
|
|
45
|
+
next = path.dirname(current);
|
|
46
|
+
if (next !== current)
|
|
47
|
+
current = next;
|
|
48
|
+
} while (next !== current);
|
|
49
|
+
return path.join(context.context.packageRoot, 'node_modules', packageName, 'package.json');
|
|
50
|
+
};
|
|
2
51
|
// 在 Vite 虚拟 CSS 中,第三方 CSS 依赖要用声明它的包作为解析根。
|
|
3
52
|
export function toDevDependencyImportSpecifier(context, specifier) {
|
|
4
53
|
if (specifier.startsWith('.') || specifier.startsWith('/')) {
|
|
5
54
|
return { specifier };
|
|
6
55
|
}
|
|
7
56
|
const resolved = context.resolver.resolveStyleDependency(specifier);
|
|
57
|
+
const packageJson = findPackageJson(resolved, context, specifier);
|
|
8
58
|
return {
|
|
59
|
+
cacheInputFiles: packageJson ? [packageJson] : [],
|
|
9
60
|
specifier: toFsSpecifier(resolved),
|
|
10
61
|
watchFile: resolved,
|
|
11
62
|
};
|
|
@@ -3,11 +3,13 @@ export type PersistentStyleGraphCacheOptions = {
|
|
|
3
3
|
root: string;
|
|
4
4
|
};
|
|
5
5
|
export declare class PersistentStyleGraphCache {
|
|
6
|
+
private static readonly cleanedRoots;
|
|
6
7
|
private readonly cacheRoot;
|
|
7
8
|
constructor(options: PersistentStyleGraphCacheOptions);
|
|
8
9
|
createKey(value: unknown): string;
|
|
9
10
|
read(key: string): PackageStyleLoadResult | null;
|
|
10
11
|
write(key: string, result: PackageStyleLoadResult, inputFiles: Array<string>): void;
|
|
12
|
+
private cleanupStaleEntries;
|
|
11
13
|
private getCacheFile;
|
|
12
14
|
private isFresh;
|
|
13
15
|
}
|
|
@@ -3,6 +3,8 @@ import path from 'node:path';
|
|
|
3
3
|
import crypto from 'node:crypto';
|
|
4
4
|
import { toPosixPath } from '#auklet/utils';
|
|
5
5
|
const cacheVersion = 'v1';
|
|
6
|
+
const maxCacheFiles = 5000;
|
|
7
|
+
const staleCacheAgeMs = 7 * 24 * 60 * 60 * 1000;
|
|
6
8
|
const stableStringify = (value) => {
|
|
7
9
|
if (Array.isArray(value)) {
|
|
8
10
|
return `[${value.map((item) => stableStringify(item)).join(',')}]`;
|
|
@@ -66,6 +68,7 @@ const statCachedFile = (file) => {
|
|
|
66
68
|
};
|
|
67
69
|
};
|
|
68
70
|
export class PersistentStyleGraphCache {
|
|
71
|
+
static cleanedRoots = new Set();
|
|
69
72
|
cacheRoot;
|
|
70
73
|
constructor(options) {
|
|
71
74
|
this.cacheRoot = path.join(options.root, 'node_modules', '.auklet', 'cache', 'vite-style', cacheVersion);
|
|
@@ -106,6 +109,45 @@ export class PersistentStyleGraphCache {
|
|
|
106
109
|
}
|
|
107
110
|
catch {
|
|
108
111
|
// Cache writes are an optimization; dev CSS generation must keep working.
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
this.cleanupStaleEntries();
|
|
115
|
+
}
|
|
116
|
+
cleanupStaleEntries() {
|
|
117
|
+
if (PersistentStyleGraphCache.cleanedRoots.has(this.cacheRoot))
|
|
118
|
+
return;
|
|
119
|
+
PersistentStyleGraphCache.cleanedRoots.add(this.cacheRoot);
|
|
120
|
+
try {
|
|
121
|
+
const now = Date.now();
|
|
122
|
+
const entries = fs
|
|
123
|
+
.readdirSync(this.cacheRoot, { withFileTypes: true })
|
|
124
|
+
.filter((entry) => entry.isFile() && entry.name.endsWith('.json'))
|
|
125
|
+
.map((entry) => {
|
|
126
|
+
const file = path.join(this.cacheRoot, entry.name);
|
|
127
|
+
return {
|
|
128
|
+
file,
|
|
129
|
+
mtimeMs: fs.statSync(file).mtimeMs,
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
const freshEntries = [];
|
|
133
|
+
for (const entry of entries) {
|
|
134
|
+
if (now - entry.mtimeMs > staleCacheAgeMs) {
|
|
135
|
+
fs.unlinkSync(entry.file);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
freshEntries.push(entry);
|
|
139
|
+
}
|
|
140
|
+
const overflowCount = freshEntries.length - maxCacheFiles;
|
|
141
|
+
if (overflowCount <= 0)
|
|
142
|
+
return;
|
|
143
|
+
for (const entry of freshEntries
|
|
144
|
+
.sort((left, right) => left.mtimeMs - right.mtimeMs)
|
|
145
|
+
.slice(0, overflowCount)) {
|
|
146
|
+
fs.unlinkSync(entry.file);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
// Cache cleanup is best-effort and must not affect dev CSS generation.
|
|
109
151
|
}
|
|
110
152
|
}
|
|
111
153
|
getCacheFile(key) {
|
|
@@ -79,6 +79,8 @@ export declare class ModuleStyleGraphRequestCache {
|
|
|
79
79
|
private createContext;
|
|
80
80
|
private createPersistentKey;
|
|
81
81
|
private getPersistentInputFiles;
|
|
82
|
+
private getPackageKeyEntries;
|
|
83
|
+
private getWorkspaceInputFiles;
|
|
82
84
|
private getSourceInputFiles;
|
|
83
85
|
private getResolutionInputFiles;
|
|
84
86
|
private getLoadResultKey;
|
|
@@ -57,6 +57,8 @@ export class ModuleStyleGraphRequestCache {
|
|
|
57
57
|
...result,
|
|
58
58
|
cacheInputFiles,
|
|
59
59
|
};
|
|
60
|
+
if (!result.code.trim())
|
|
61
|
+
return cacheResult;
|
|
60
62
|
this.persistentCache.write(this.createPersistentKey(parsed, context), cacheResult, cacheInputFiles);
|
|
61
63
|
return cacheResult;
|
|
62
64
|
}
|
|
@@ -103,6 +105,7 @@ export class ModuleStyleGraphRequestCache {
|
|
|
103
105
|
normalizedConfig: context.normalizedConfig,
|
|
104
106
|
packageName: context.packageName,
|
|
105
107
|
packageNames: this.getPackageNames(),
|
|
108
|
+
packages: this.getPackageKeyEntries(),
|
|
106
109
|
packageRoot: normalizeFileKey(context.context.packageRoot),
|
|
107
110
|
parsed,
|
|
108
111
|
root: normalizeFileKey(this.options.root),
|
|
@@ -116,21 +119,42 @@ export class ModuleStyleGraphRequestCache {
|
|
|
116
119
|
...(result.cacheInputFiles ?? []),
|
|
117
120
|
...this.getSourceInputFiles(context.sourceRoot, context.packageContext.sourceFiles),
|
|
118
121
|
...this.getResolutionInputFiles(context.context.packageRoot),
|
|
122
|
+
...this.getWorkspaceInputFiles(),
|
|
119
123
|
];
|
|
120
124
|
}
|
|
125
|
+
getPackageKeyEntries() {
|
|
126
|
+
return this.options.packageSource
|
|
127
|
+
.getPackages()
|
|
128
|
+
.map((item) => ({
|
|
129
|
+
packageName: item.packageName,
|
|
130
|
+
packageRoot: normalizeFileKey(item.packageRoot),
|
|
131
|
+
}))
|
|
132
|
+
.sort((left, right) => {
|
|
133
|
+
const nameOrder = left.packageName.localeCompare(right.packageName);
|
|
134
|
+
if (nameOrder !== 0)
|
|
135
|
+
return nameOrder;
|
|
136
|
+
return left.packageRoot.localeCompare(right.packageRoot);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
getWorkspaceInputFiles() {
|
|
140
|
+
if (this.options.mode !== 'monorepo')
|
|
141
|
+
return [];
|
|
142
|
+
return [path.join(this.options.root, 'pnpm-workspace.yaml')];
|
|
143
|
+
}
|
|
121
144
|
getSourceInputFiles(sourceRoot, sourceFiles) {
|
|
122
145
|
const sourceInputFiles = new Set([sourceRoot, ...sourceFiles]);
|
|
123
146
|
const normalizedSourceRoot = normalizeFileKey(sourceRoot);
|
|
124
147
|
for (const file of sourceFiles) {
|
|
125
148
|
let current = path.dirname(file);
|
|
126
|
-
|
|
149
|
+
let currentKey = normalizeFileKey(current);
|
|
150
|
+
while (currentKey === normalizedSourceRoot ||
|
|
151
|
+
currentKey.startsWith(`${normalizedSourceRoot}/`)) {
|
|
127
152
|
sourceInputFiles.add(current);
|
|
128
|
-
if (
|
|
153
|
+
if (currentKey === normalizedSourceRoot)
|
|
129
154
|
break;
|
|
130
155
|
const parent = path.dirname(current);
|
|
131
|
-
if (parent === current)
|
|
132
|
-
break;
|
|
133
156
|
current = parent;
|
|
157
|
+
currentKey = normalizeFileKey(current);
|
|
134
158
|
}
|
|
135
159
|
}
|
|
136
160
|
return Array.from(sourceInputFiles);
|
|
@@ -139,16 +163,19 @@ export class ModuleStyleGraphRequestCache {
|
|
|
139
163
|
const files = [path.join(packageRoot, 'package.json')];
|
|
140
164
|
let current = packageRoot;
|
|
141
165
|
const graphRoot = normalizeFileKey(this.options.root);
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
166
|
+
let reachedGraphRoot = false;
|
|
167
|
+
while (!reachedGraphRoot) {
|
|
168
|
+
const tsconfig = path.join(current, 'tsconfig.json');
|
|
169
|
+
files.push(tsconfig);
|
|
170
|
+
reachedGraphRoot = normalizeFileKey(current) === graphRoot;
|
|
171
|
+
if (reachedGraphRoot)
|
|
145
172
|
break;
|
|
146
173
|
const parent = path.dirname(current);
|
|
147
174
|
if (parent === current)
|
|
148
175
|
break;
|
|
149
176
|
current = parent;
|
|
150
177
|
}
|
|
151
|
-
return files;
|
|
178
|
+
return Array.from(new Set(files));
|
|
152
179
|
}
|
|
153
180
|
getLoadResultKey(parsed) {
|
|
154
181
|
return `${parsed.packageName}\0${parsed.stylePath}`;
|
|
@@ -62,6 +62,7 @@ export class StyleCodeFactory {
|
|
|
62
62
|
}
|
|
63
63
|
async createDependencyStyleCode(context, cache, specifiers, mapSpecifier = (specifier) => specifier) {
|
|
64
64
|
const results = [];
|
|
65
|
+
const cacheInputFiles = [];
|
|
65
66
|
const imports = [];
|
|
66
67
|
const watchFiles = [...context.configPaths];
|
|
67
68
|
for (const specifier of specifiers) {
|
|
@@ -74,12 +75,14 @@ export class StyleCodeFactory {
|
|
|
74
75
|
}
|
|
75
76
|
const resolvedSpecifier = toDevDependencyImportSpecifier(context, outputSpecifier);
|
|
76
77
|
imports.push(resolvedSpecifier.specifier);
|
|
78
|
+
cacheInputFiles.push(...(resolvedSpecifier.cacheInputFiles ?? []));
|
|
77
79
|
if (resolvedSpecifier.watchFile) {
|
|
78
80
|
watchFiles.push(resolvedSpecifier.watchFile);
|
|
79
81
|
}
|
|
80
82
|
}
|
|
81
83
|
return mergeLoadResults({
|
|
82
84
|
code: createImportCode(imports),
|
|
85
|
+
cacheInputFiles,
|
|
83
86
|
watchFiles,
|
|
84
87
|
}, ...results);
|
|
85
88
|
}
|
|
@@ -144,6 +147,7 @@ export class StyleCodeFactory {
|
|
|
144
147
|
const moduleStyleResults = [];
|
|
145
148
|
const moduleStyleSpecifiers = [];
|
|
146
149
|
const moduleStyleWatchFiles = [];
|
|
150
|
+
const moduleStyleCacheInputFiles = [];
|
|
147
151
|
for (const specifier of entry.moduleStyleImports) {
|
|
148
152
|
const result = this.toDevModuleImportSpecifier(specifier, context, cache, sourceStyleDir);
|
|
149
153
|
const parsed = this.parsePackageStyleIdInRequest(result, cache);
|
|
@@ -154,6 +158,7 @@ export class StyleCodeFactory {
|
|
|
154
158
|
}
|
|
155
159
|
const resolvedSpecifier = toDevDependencyImportSpecifier(context, result);
|
|
156
160
|
moduleStyleSpecifiers.push(resolvedSpecifier.specifier);
|
|
161
|
+
moduleStyleCacheInputFiles.push(...(resolvedSpecifier.cacheInputFiles ?? []));
|
|
157
162
|
if (resolvedSpecifier.watchFile) {
|
|
158
163
|
moduleStyleWatchFiles.push(resolvedSpecifier.watchFile);
|
|
159
164
|
}
|
|
@@ -179,6 +184,7 @@ export class StyleCodeFactory {
|
|
|
179
184
|
...moduleStyleWatchFiles,
|
|
180
185
|
...sourceFiles.filter((file) => /\.(ts|tsx)$/.test(file)),
|
|
181
186
|
],
|
|
187
|
+
cacheInputFiles: moduleStyleCacheInputFiles,
|
|
182
188
|
});
|
|
183
189
|
}
|
|
184
190
|
toDevModuleImportSpecifier(specifier, context, cache, sourceStyleDir) {
|