auklet 0.1.9 → 0.2.1
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/core/style/entries.js +7 -4
- package/dist/css/core/stylePackageContext.d.ts +5 -0
- package/dist/css/core/stylePackageContext.js +11 -0
- package/dist/css/vite/hmr.d.ts +2 -0
- package/dist/css/vite/hmr.js +37 -17
- package/dist/css/vite/moduleGraph/devDependency.d.ts +2 -0
- package/dist/css/vite/moduleGraph/devDependency.js +51 -0
- package/dist/css/vite/moduleGraph/graph.d.ts +1 -4
- package/dist/css/vite/moduleGraph/graph.js +2 -0
- package/dist/css/vite/moduleGraph/loadResult.d.ts +2 -0
- package/dist/css/vite/moduleGraph/loadResult.js +2 -0
- package/dist/css/vite/moduleGraph/persistentCache.d.ts +15 -0
- package/dist/css/vite/moduleGraph/persistentCache.js +179 -0
- package/dist/css/vite/moduleGraph/requestCache.d.ts +23 -1
- package/dist/css/vite/moduleGraph/requestCache.js +147 -0
- package/dist/css/vite/moduleGraph/styleCodeFactory.d.ts +4 -5
- package/dist/css/vite/moduleGraph/styleCodeFactory.js +34 -10
- package/dist/css/vite/moduleGraph/types.d.ts +2 -0
- package/dist/css/vite/vitePlugin.js +1 -1
- 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,5 +1,4 @@
|
|
|
1
1
|
import { getGlobalStyleDependencies, getThemeNames, getThemeStyleDependencies, } from '#auklet/css/core/style/dependencies';
|
|
2
|
-
import { StyleModuleEntryPlanner } from '#auklet/css/core/styleModuleEntryPlanner';
|
|
3
2
|
const dependenciesPart = (specifiers) => ({ type: 'dependencies', specifiers });
|
|
4
3
|
// 环境无关的 style entry graph。production writer 和 Vite/dev renderer 都从这里取入口语义。
|
|
5
4
|
export function createStyleEntryParts(config) {
|
|
@@ -25,11 +24,15 @@ export function createExternalEntryParts(config) {
|
|
|
25
24
|
];
|
|
26
25
|
}
|
|
27
26
|
export function collectModuleStyleImports(packageContext) {
|
|
28
|
-
return packageContext.
|
|
27
|
+
return packageContext.getModuleStyleImports();
|
|
29
28
|
}
|
|
30
29
|
export function createModuleStyleEntryPlan(packageContext, sourceDir) {
|
|
31
|
-
return
|
|
30
|
+
return packageContext
|
|
31
|
+
.getModuleStyleEntryPlanner()
|
|
32
|
+
.createEntry(sourceDir, collectModuleStyleImports(packageContext));
|
|
32
33
|
}
|
|
33
34
|
export function createModuleStyleEntryPlans(packageContext) {
|
|
34
|
-
return
|
|
35
|
+
return packageContext
|
|
36
|
+
.getModuleStyleEntryPlanner()
|
|
37
|
+
.createEntries(collectModuleStyleImports(packageContext));
|
|
35
38
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ModuleStyleImportCollector } from '#auklet/css/core/styleImports/collector';
|
|
2
|
+
import { StyleModuleEntryPlanner } from '#auklet/css/core/styleModuleEntryPlanner';
|
|
2
3
|
import { StyleProcessor } from '#auklet/css/core/styleProcessor';
|
|
3
4
|
import { WorkspaceStyleResolver } from '#auklet/css/core/workspaceStyleResolver';
|
|
4
5
|
import type { ModuleStyleBuildConfig, NormalizedAukletConfig, ResolvedModuleStyleBuildContext } from '#auklet/types';
|
|
@@ -18,6 +19,10 @@ export declare class StylePackageContext {
|
|
|
18
19
|
readonly themeFiles: Map<string, string>;
|
|
19
20
|
readonly themeNames: Array<string>;
|
|
20
21
|
readonly styleFiles: Array<string>;
|
|
22
|
+
private moduleStyleEntryPlanner?;
|
|
23
|
+
private moduleStyleImports?;
|
|
21
24
|
constructor(options: StylePackageContextOptions);
|
|
22
25
|
getStyleFiles(files: Array<string>): string[];
|
|
26
|
+
getModuleStyleImports(): Map<string, string[]>;
|
|
27
|
+
getModuleStyleEntryPlanner(): StyleModuleEntryPlanner;
|
|
23
28
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { ModuleStyleImportCollector } from '#auklet/css/core/styleImports/collector';
|
|
4
|
+
import { StyleModuleEntryPlanner } from '#auklet/css/core/styleModuleEntryPlanner';
|
|
4
5
|
import { StyleProcessor } from '#auklet/css/core/styleProcessor';
|
|
5
6
|
import { WorkspaceStyleResolver } from '#auklet/css/core/workspaceStyleResolver';
|
|
6
7
|
import { createStyleFileKeySet } from '#auklet/css/core/style/files';
|
|
@@ -17,6 +18,8 @@ export class StylePackageContext {
|
|
|
17
18
|
themeFiles;
|
|
18
19
|
themeNames;
|
|
19
20
|
styleFiles;
|
|
21
|
+
moduleStyleEntryPlanner;
|
|
22
|
+
moduleStyleImports;
|
|
20
23
|
constructor(options) {
|
|
21
24
|
this.options = options;
|
|
22
25
|
const { config, context, normalizedConfig } = this.options;
|
|
@@ -38,4 +41,12 @@ export class StylePackageContext {
|
|
|
38
41
|
.filter((file) => this.options.config.styleExtensions.includes(path.extname(file)))
|
|
39
42
|
.filter((styleFile) => !themeFileKeys.has(normalizeFileKey(styleFile)));
|
|
40
43
|
}
|
|
44
|
+
getModuleStyleImports() {
|
|
45
|
+
this.moduleStyleImports ??= this.importCollector.collect(this.sourceFiles, this.normalizedConfig);
|
|
46
|
+
return this.moduleStyleImports;
|
|
47
|
+
}
|
|
48
|
+
getModuleStyleEntryPlanner() {
|
|
49
|
+
this.moduleStyleEntryPlanner ??= new StyleModuleEntryPlanner(this);
|
|
50
|
+
return this.moduleStyleEntryPlanner;
|
|
51
|
+
}
|
|
41
52
|
}
|
package/dist/css/vite/hmr.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export declare class AukletStyleHmr {
|
|
|
9
9
|
trackVirtualStyleDependency(file: string, virtualId: string): void;
|
|
10
10
|
installFullReloadGuard(server: Pick<ViteDevServer, 'ws'>): void;
|
|
11
11
|
handleStyleHotUpdate(context: HotUpdateOptions): never[] | undefined;
|
|
12
|
+
handleSourceModuleChange(server: Pick<ViteDevServer, 'moduleGraph' | 'ws'>, file: string): boolean;
|
|
13
|
+
private sendVirtualStyleUpdates;
|
|
12
14
|
private suppressFullReload;
|
|
13
15
|
private shouldSuppressFullReload;
|
|
14
16
|
private isDuplicateUpdate;
|
package/dist/css/vite/hmr.js
CHANGED
|
@@ -26,6 +26,19 @@ const getDependencyVirtualModules = (virtualIdsByDependency, server, file) => {
|
|
|
26
26
|
return module ? [module] : [];
|
|
27
27
|
});
|
|
28
28
|
};
|
|
29
|
+
const createJsUpdates = (virtualIds, timestamp) => {
|
|
30
|
+
return virtualIds.map((id) => {
|
|
31
|
+
const browserPath = toBrowserVirtualPath(id);
|
|
32
|
+
return {
|
|
33
|
+
type: 'js-update',
|
|
34
|
+
path: browserPath,
|
|
35
|
+
acceptedPath: browserPath,
|
|
36
|
+
timestamp,
|
|
37
|
+
explicitImportRequired: false,
|
|
38
|
+
isWithinCircularImport: false,
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
};
|
|
29
42
|
export class AukletStyleHmr {
|
|
30
43
|
graph;
|
|
31
44
|
lastUpdateTimes = new Map();
|
|
@@ -64,30 +77,37 @@ export class AukletStyleHmr {
|
|
|
64
77
|
if (this.isDuplicateUpdate(context.file)) {
|
|
65
78
|
return [];
|
|
66
79
|
}
|
|
67
|
-
const
|
|
68
|
-
|
|
80
|
+
const updates = this.sendVirtualStyleUpdates(context.file, context.server, context.timestamp);
|
|
81
|
+
logger.info(`package css hmr ${getRelativeFile(context.file)} tracked=${updates.tracked} updates=${updates.sent}`);
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
handleSourceModuleChange(server, file) {
|
|
85
|
+
const graph = this.graph();
|
|
86
|
+
if (!graph.isSourceGraphFile(file) || !graph.isSourceModuleFile(file)) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
graph.invalidateFile(file);
|
|
90
|
+
const updates = this.sendVirtualStyleUpdates(file, server, Date.now());
|
|
91
|
+
logger.info(`package css source hmr ${getRelativeFile(file)} tracked=${updates.tracked} updates=${updates.sent}`);
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
sendVirtualStyleUpdates(file, server, timestamp) {
|
|
95
|
+
const virtualIds = getDependencyVirtualIds(this.virtualIdsByDependency, file);
|
|
96
|
+
const modules = getDependencyVirtualModules(this.virtualIdsByDependency, server, file);
|
|
69
97
|
for (const module of modules) {
|
|
70
|
-
|
|
98
|
+
server.moduleGraph.invalidateModule(module);
|
|
71
99
|
}
|
|
72
|
-
const updates = virtualIds
|
|
73
|
-
const browserPath = toBrowserVirtualPath(id);
|
|
74
|
-
return {
|
|
75
|
-
type: 'js-update',
|
|
76
|
-
path: browserPath,
|
|
77
|
-
acceptedPath: browserPath,
|
|
78
|
-
timestamp: context.timestamp,
|
|
79
|
-
explicitImportRequired: false,
|
|
80
|
-
isWithinCircularImport: false,
|
|
81
|
-
};
|
|
82
|
-
});
|
|
83
|
-
logger.info(`package css hmr ${getRelativeFile(context.file)} tracked=${virtualIds.length} updates=${updates.length}`);
|
|
100
|
+
const updates = createJsUpdates(virtualIds, timestamp);
|
|
84
101
|
if (updates.length) {
|
|
85
|
-
|
|
102
|
+
server.ws.send({
|
|
86
103
|
type: 'update',
|
|
87
104
|
updates,
|
|
88
105
|
});
|
|
89
106
|
}
|
|
90
|
-
return
|
|
107
|
+
return {
|
|
108
|
+
sent: updates.length,
|
|
109
|
+
tracked: virtualIds.length,
|
|
110
|
+
};
|
|
91
111
|
}
|
|
92
112
|
suppressFullReload() {
|
|
93
113
|
this.suppressFullReloadUntil = Date.now() + FULL_RELOAD_SUPPRESS_MS;
|
|
@@ -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
|
};
|
|
@@ -15,10 +15,7 @@ export declare class ModuleStyleGraph {
|
|
|
15
15
|
isStyleFile(file: string): boolean;
|
|
16
16
|
getPackageNames(): string[];
|
|
17
17
|
getWatchRoots(): Promise<string[]>;
|
|
18
|
-
createPackageStyleCode(parsed: PackageStyleId): Promise<
|
|
19
|
-
code: string;
|
|
20
|
-
watchFiles: string[];
|
|
21
|
-
}>;
|
|
18
|
+
createPackageStyleCode(parsed: PackageStyleId): Promise<import("#auklet/css/vite/moduleGraph/types").PackageStyleLoadResult>;
|
|
22
19
|
invalidatePackage(packageName: string): void;
|
|
23
20
|
invalidateFile(file: string): string | null;
|
|
24
21
|
isSourceModuleFile(file: string): boolean;
|
|
@@ -32,6 +32,8 @@ export class ModuleStyleGraph {
|
|
|
32
32
|
loadAukletConfig: this.loadAukletConfig,
|
|
33
33
|
});
|
|
34
34
|
this.requestCache = new ModuleStyleGraphRequestCache({
|
|
35
|
+
root: normalizeFileKey(options.root),
|
|
36
|
+
mode: options.mode ?? 'package',
|
|
35
37
|
packageSource: this.packageSource,
|
|
36
38
|
config: this.config,
|
|
37
39
|
loadAukletConfig: this.loadAukletConfig,
|
|
@@ -2,4 +2,6 @@ import type { PackageStyleLoadResult } from '#auklet/css/vite/moduleGraph/types'
|
|
|
2
2
|
export declare function mergeLoadResults(...results: Array<PackageStyleLoadResult>): {
|
|
3
3
|
code: string;
|
|
4
4
|
watchFiles: string[];
|
|
5
|
+
cacheInputFiles: string[];
|
|
6
|
+
dependencyPackages: string[];
|
|
5
7
|
};
|
|
@@ -6,5 +6,7 @@ export function mergeLoadResults(...results) {
|
|
|
6
6
|
.filter((code) => code.trim())
|
|
7
7
|
.join('\n'),
|
|
8
8
|
watchFiles: Array.from(new Set(results.flatMap((result) => result.watchFiles))),
|
|
9
|
+
cacheInputFiles: Array.from(new Set(results.flatMap((result) => result.cacheInputFiles ?? []))),
|
|
10
|
+
dependencyPackages: Array.from(new Set(results.flatMap((result) => result.dependencyPackages ?? []))),
|
|
9
11
|
};
|
|
10
12
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PackageStyleLoadResult } from '#auklet/css/vite/moduleGraph/types';
|
|
2
|
+
export type PersistentStyleGraphCacheOptions = {
|
|
3
|
+
root: string;
|
|
4
|
+
};
|
|
5
|
+
export declare class PersistentStyleGraphCache {
|
|
6
|
+
private static readonly cleanedRoots;
|
|
7
|
+
private readonly cacheRoot;
|
|
8
|
+
constructor(options: PersistentStyleGraphCacheOptions);
|
|
9
|
+
createKey(value: unknown): string;
|
|
10
|
+
read(key: string): PackageStyleLoadResult | null;
|
|
11
|
+
write(key: string, result: PackageStyleLoadResult, inputFiles: Array<string>): void;
|
|
12
|
+
private cleanupStaleEntries;
|
|
13
|
+
private getCacheFile;
|
|
14
|
+
private isFresh;
|
|
15
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import crypto from 'node:crypto';
|
|
4
|
+
import { toPosixPath } from '#auklet/utils';
|
|
5
|
+
const cacheVersion = 'v1';
|
|
6
|
+
const maxCacheFiles = 5000;
|
|
7
|
+
const staleCacheAgeMs = 7 * 24 * 60 * 60 * 1000;
|
|
8
|
+
const stableStringify = (value) => {
|
|
9
|
+
if (Array.isArray(value)) {
|
|
10
|
+
return `[${value.map((item) => stableStringify(item)).join(',')}]`;
|
|
11
|
+
}
|
|
12
|
+
if (value && typeof value === 'object') {
|
|
13
|
+
return `{${Object.entries(value)
|
|
14
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
15
|
+
.map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`)
|
|
16
|
+
.join(',')}}`;
|
|
17
|
+
}
|
|
18
|
+
return JSON.stringify(value);
|
|
19
|
+
};
|
|
20
|
+
const hashValue = (value) => {
|
|
21
|
+
return crypto
|
|
22
|
+
.createHash('sha256')
|
|
23
|
+
.update(stableStringify(value))
|
|
24
|
+
.digest('hex');
|
|
25
|
+
};
|
|
26
|
+
const hashFile = (file) => {
|
|
27
|
+
return crypto.createHash('md5').update(fs.readFileSync(file)).digest('hex');
|
|
28
|
+
};
|
|
29
|
+
const normalizeCachePath = (file) => {
|
|
30
|
+
return toPosixPath(path.resolve(file));
|
|
31
|
+
};
|
|
32
|
+
const normalizeRealpath = (file) => {
|
|
33
|
+
return toPosixPath(fs.realpathSync.native(file));
|
|
34
|
+
};
|
|
35
|
+
const statCachedFile = (file) => {
|
|
36
|
+
const resolved = path.resolve(file);
|
|
37
|
+
if (!fs.existsSync(resolved)) {
|
|
38
|
+
return {
|
|
39
|
+
file: normalizeCachePath(file),
|
|
40
|
+
exists: false,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const stat = fs.statSync(resolved);
|
|
44
|
+
if (stat.isDirectory()) {
|
|
45
|
+
return {
|
|
46
|
+
file: normalizeCachePath(file),
|
|
47
|
+
exists: true,
|
|
48
|
+
realpath: normalizeRealpath(resolved),
|
|
49
|
+
type: 'directory',
|
|
50
|
+
mtimeMs: stat.mtimeMs,
|
|
51
|
+
size: stat.size,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (!stat.isFile()) {
|
|
55
|
+
return {
|
|
56
|
+
file: normalizeCachePath(file),
|
|
57
|
+
exists: false,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
hash: hashFile(resolved),
|
|
62
|
+
file: normalizeCachePath(file),
|
|
63
|
+
exists: true,
|
|
64
|
+
realpath: normalizeRealpath(resolved),
|
|
65
|
+
type: 'file',
|
|
66
|
+
mtimeMs: stat.mtimeMs,
|
|
67
|
+
size: stat.size,
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
export class PersistentStyleGraphCache {
|
|
71
|
+
static cleanedRoots = new Set();
|
|
72
|
+
cacheRoot;
|
|
73
|
+
constructor(options) {
|
|
74
|
+
this.cacheRoot = path.join(options.root, 'node_modules', '.auklet', 'cache', 'vite-style', cacheVersion);
|
|
75
|
+
}
|
|
76
|
+
createKey(value) {
|
|
77
|
+
return hashValue({
|
|
78
|
+
cacheVersion,
|
|
79
|
+
value,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
read(key) {
|
|
83
|
+
const cacheFile = this.getCacheFile(key);
|
|
84
|
+
if (!fs.existsSync(cacheFile))
|
|
85
|
+
return null;
|
|
86
|
+
try {
|
|
87
|
+
const cached = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
|
|
88
|
+
if (cached.key !== key)
|
|
89
|
+
return null;
|
|
90
|
+
if (!this.isFresh(cached.files))
|
|
91
|
+
return null;
|
|
92
|
+
return cached.result;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
write(key, result, inputFiles) {
|
|
99
|
+
const files = Array.from(new Map(inputFiles
|
|
100
|
+
.map((file) => statCachedFile(file))
|
|
101
|
+
.map((file) => [file.file, file])).values());
|
|
102
|
+
try {
|
|
103
|
+
fs.mkdirSync(this.cacheRoot, { recursive: true });
|
|
104
|
+
fs.writeFileSync(this.getCacheFile(key), `${JSON.stringify({
|
|
105
|
+
files,
|
|
106
|
+
key,
|
|
107
|
+
result,
|
|
108
|
+
}, null, 2)}\n`);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
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.
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
getCacheFile(key) {
|
|
154
|
+
return path.join(this.cacheRoot, `${key}.json`);
|
|
155
|
+
}
|
|
156
|
+
isFresh(files) {
|
|
157
|
+
for (const file of files) {
|
|
158
|
+
const current = statCachedFile(file.file);
|
|
159
|
+
if (current.exists !== file.exists)
|
|
160
|
+
return false;
|
|
161
|
+
if (!current.exists || !file.exists)
|
|
162
|
+
continue;
|
|
163
|
+
if (current.type !== file.type)
|
|
164
|
+
return false;
|
|
165
|
+
if (current.realpath !== file.realpath ||
|
|
166
|
+
current.size !== file.size ||
|
|
167
|
+
current.mtimeMs !== file.mtimeMs ||
|
|
168
|
+
toPosixPath(current.file) !== toPosixPath(file.file)) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
if (current.type === 'file' &&
|
|
172
|
+
file.type === 'file' &&
|
|
173
|
+
current.hash !== file.hash) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -3,7 +3,7 @@ import type { ModuleStyleBuildConfig, NormalizedAukletConfig, ResolvedModuleStyl
|
|
|
3
3
|
import type { StyleProcessor } from '#auklet/css/core/styleProcessor';
|
|
4
4
|
import type { WorkspaceStyleResolver } from '#auklet/css/core/workspaceStyleResolver';
|
|
5
5
|
import type { StylePackageSource } from '#auklet/css/vite/moduleGraph/packageSource/types';
|
|
6
|
-
import type { LoadAukletConfig, PackageStyleId } from '#auklet/css/vite/moduleGraph/types';
|
|
6
|
+
import type { LoadAukletConfig, PackageStyleId, PackageStyleLoadResult } from '#auklet/css/vite/moduleGraph/types';
|
|
7
7
|
export type PackageStyleContext = {
|
|
8
8
|
normalizedConfig: NormalizedAukletConfig;
|
|
9
9
|
context: ResolvedModuleStyleBuildContext;
|
|
@@ -15,6 +15,8 @@ export type PackageStyleContext = {
|
|
|
15
15
|
styleProcessor: StyleProcessor;
|
|
16
16
|
};
|
|
17
17
|
export type ModuleStyleGraphRequestCacheOptions = {
|
|
18
|
+
root: string;
|
|
19
|
+
mode: 'monorepo' | 'package';
|
|
18
20
|
packageSource: StylePackageSource;
|
|
19
21
|
config: ModuleStyleBuildConfig;
|
|
20
22
|
loadAukletConfig?: LoadAukletConfig;
|
|
@@ -22,7 +24,10 @@ export type ModuleStyleGraphRequestCacheOptions = {
|
|
|
22
24
|
export declare class ModuleStyleGraphRequestCache {
|
|
23
25
|
private readonly options;
|
|
24
26
|
private readonly contexts;
|
|
27
|
+
private readonly loadResults;
|
|
28
|
+
private readonly loadResultDependencies;
|
|
25
29
|
private readonly loadAukletConfig;
|
|
30
|
+
private readonly persistentCache;
|
|
26
31
|
constructor(options: ModuleStyleGraphRequestCacheOptions);
|
|
27
32
|
getPackageNames(): string[];
|
|
28
33
|
isKnownPackageName(packageName: string): boolean;
|
|
@@ -62,6 +67,23 @@ export declare class ModuleStyleGraphRequestCache {
|
|
|
62
67
|
sourceRoot: string;
|
|
63
68
|
styleProcessor: StyleProcessor;
|
|
64
69
|
} | null>;
|
|
70
|
+
getLoadResult(parsed: PackageStyleId, create: () => Promise<PackageStyleLoadResult>): Promise<PackageStyleLoadResult>;
|
|
65
71
|
invalidatePackage(packageName: string): void;
|
|
72
|
+
readPersistentLoadResult(parsed: PackageStyleId, context: PackageStyleContext): PackageStyleLoadResult | null;
|
|
73
|
+
writePersistentLoadResult(parsed: PackageStyleId, context: PackageStyleContext, result: PackageStyleLoadResult): {
|
|
74
|
+
cacheInputFiles: string[];
|
|
75
|
+
code: string;
|
|
76
|
+
watchFiles: Array<string>;
|
|
77
|
+
dependencyPackages?: Array<string>;
|
|
78
|
+
};
|
|
66
79
|
private createContext;
|
|
80
|
+
private createPersistentKey;
|
|
81
|
+
private getPersistentInputFiles;
|
|
82
|
+
private getPackageKeyEntries;
|
|
83
|
+
private getWorkspaceInputFiles;
|
|
84
|
+
private getSourceInputFiles;
|
|
85
|
+
private getResolutionInputFiles;
|
|
86
|
+
private getLoadResultKey;
|
|
87
|
+
private getLoadResultPackageName;
|
|
88
|
+
private invalidateLoadResults;
|
|
67
89
|
}
|
|
@@ -2,13 +2,21 @@ import path from 'node:path';
|
|
|
2
2
|
import { loadAukletConfig, resolveAukletConfigPath, } from '#auklet/configLoader';
|
|
3
3
|
import { aukletConfigFiles, normalizeAukletConfig } from '#auklet/config';
|
|
4
4
|
import { StylePackageContext } from '#auklet/css/core/stylePackageContext';
|
|
5
|
+
import { PersistentStyleGraphCache } from '#auklet/css/vite/moduleGraph/persistentCache';
|
|
6
|
+
import { normalizeFileKey, toPosixPath } from '#auklet/utils';
|
|
5
7
|
export class ModuleStyleGraphRequestCache {
|
|
6
8
|
options;
|
|
7
9
|
contexts = new Map();
|
|
10
|
+
loadResults = new Map();
|
|
11
|
+
loadResultDependencies = new Map();
|
|
8
12
|
loadAukletConfig;
|
|
13
|
+
persistentCache;
|
|
9
14
|
constructor(options) {
|
|
10
15
|
this.options = options;
|
|
11
16
|
this.loadAukletConfig = options.loadAukletConfig ?? loadAukletConfig;
|
|
17
|
+
this.persistentCache = new PersistentStyleGraphCache({
|
|
18
|
+
root: options.root,
|
|
19
|
+
});
|
|
12
20
|
}
|
|
13
21
|
getPackageNames() {
|
|
14
22
|
return this.options.packageSource.getPackageNames();
|
|
@@ -24,8 +32,33 @@ export class ModuleStyleGraphRequestCache {
|
|
|
24
32
|
this.contexts.set(parsed.packageName, context);
|
|
25
33
|
return context;
|
|
26
34
|
}
|
|
35
|
+
getLoadResult(parsed, create) {
|
|
36
|
+
const key = this.getLoadResultKey(parsed);
|
|
37
|
+
const cachedResult = this.loadResults.get(key);
|
|
38
|
+
if (cachedResult)
|
|
39
|
+
return cachedResult;
|
|
40
|
+
const result = create().then((value) => {
|
|
41
|
+
this.loadResultDependencies.set(key, new Set(value.dependencyPackages ?? []));
|
|
42
|
+
return value;
|
|
43
|
+
});
|
|
44
|
+
this.loadResults.set(key, result);
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
27
47
|
invalidatePackage(packageName) {
|
|
28
48
|
this.contexts.delete(packageName);
|
|
49
|
+
this.invalidateLoadResults(packageName);
|
|
50
|
+
}
|
|
51
|
+
readPersistentLoadResult(parsed, context) {
|
|
52
|
+
return this.persistentCache.read(this.createPersistentKey(parsed, context));
|
|
53
|
+
}
|
|
54
|
+
writePersistentLoadResult(parsed, context, result) {
|
|
55
|
+
const cacheInputFiles = this.getPersistentInputFiles(context, result);
|
|
56
|
+
const cacheResult = {
|
|
57
|
+
...result,
|
|
58
|
+
cacheInputFiles,
|
|
59
|
+
};
|
|
60
|
+
this.persistentCache.write(this.createPersistentKey(parsed, context), cacheResult, cacheInputFiles);
|
|
61
|
+
return cacheResult;
|
|
29
62
|
}
|
|
30
63
|
async createContext(parsed) {
|
|
31
64
|
const stylePackage = this.options.packageSource
|
|
@@ -63,4 +96,118 @@ export class ModuleStyleGraphRequestCache {
|
|
|
63
96
|
styleProcessor: packageContext.styleProcessor,
|
|
64
97
|
};
|
|
65
98
|
}
|
|
99
|
+
createPersistentKey(parsed, context) {
|
|
100
|
+
return this.persistentCache.createKey({
|
|
101
|
+
config: this.options.config,
|
|
102
|
+
mode: this.options.mode,
|
|
103
|
+
normalizedConfig: context.normalizedConfig,
|
|
104
|
+
packageName: context.packageName,
|
|
105
|
+
packageNames: this.getPackageNames(),
|
|
106
|
+
packages: this.getPackageKeyEntries(),
|
|
107
|
+
packageRoot: normalizeFileKey(context.context.packageRoot),
|
|
108
|
+
parsed,
|
|
109
|
+
root: normalizeFileKey(this.options.root),
|
|
110
|
+
sourceFiles: context.packageContext.sourceFiles.map((file) => toPosixPath(path.relative(context.sourceRoot, file))),
|
|
111
|
+
sourceRoot: normalizeFileKey(context.sourceRoot),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
getPersistentInputFiles(context, result) {
|
|
115
|
+
return [
|
|
116
|
+
...result.watchFiles,
|
|
117
|
+
...(result.cacheInputFiles ?? []),
|
|
118
|
+
...this.getSourceInputFiles(context.sourceRoot, context.packageContext.sourceFiles),
|
|
119
|
+
...this.getResolutionInputFiles(context.context.packageRoot),
|
|
120
|
+
...this.getWorkspaceInputFiles(),
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
getPackageKeyEntries() {
|
|
124
|
+
return this.options.packageSource
|
|
125
|
+
.getPackages()
|
|
126
|
+
.map((item) => ({
|
|
127
|
+
packageName: item.packageName,
|
|
128
|
+
packageRoot: normalizeFileKey(item.packageRoot),
|
|
129
|
+
}))
|
|
130
|
+
.sort((left, right) => {
|
|
131
|
+
const nameOrder = left.packageName.localeCompare(right.packageName);
|
|
132
|
+
if (nameOrder !== 0)
|
|
133
|
+
return nameOrder;
|
|
134
|
+
return left.packageRoot.localeCompare(right.packageRoot);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
getWorkspaceInputFiles() {
|
|
138
|
+
if (this.options.mode !== 'monorepo')
|
|
139
|
+
return [];
|
|
140
|
+
return [path.join(this.options.root, 'pnpm-workspace.yaml')];
|
|
141
|
+
}
|
|
142
|
+
getSourceInputFiles(sourceRoot, sourceFiles) {
|
|
143
|
+
const sourceInputFiles = new Set([sourceRoot, ...sourceFiles]);
|
|
144
|
+
const normalizedSourceRoot = normalizeFileKey(sourceRoot);
|
|
145
|
+
for (const file of sourceFiles) {
|
|
146
|
+
let current = path.dirname(file);
|
|
147
|
+
let currentKey = normalizeFileKey(current);
|
|
148
|
+
while (currentKey === normalizedSourceRoot ||
|
|
149
|
+
currentKey.startsWith(`${normalizedSourceRoot}/`)) {
|
|
150
|
+
sourceInputFiles.add(current);
|
|
151
|
+
if (currentKey === normalizedSourceRoot)
|
|
152
|
+
break;
|
|
153
|
+
const parent = path.dirname(current);
|
|
154
|
+
current = parent;
|
|
155
|
+
currentKey = normalizeFileKey(current);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return Array.from(sourceInputFiles);
|
|
159
|
+
}
|
|
160
|
+
getResolutionInputFiles(packageRoot) {
|
|
161
|
+
const files = [path.join(packageRoot, 'package.json')];
|
|
162
|
+
let current = packageRoot;
|
|
163
|
+
const graphRoot = normalizeFileKey(this.options.root);
|
|
164
|
+
let reachedGraphRoot = false;
|
|
165
|
+
while (!reachedGraphRoot) {
|
|
166
|
+
const tsconfig = path.join(current, 'tsconfig.json');
|
|
167
|
+
files.push(tsconfig);
|
|
168
|
+
reachedGraphRoot = normalizeFileKey(current) === graphRoot;
|
|
169
|
+
if (reachedGraphRoot)
|
|
170
|
+
break;
|
|
171
|
+
const parent = path.dirname(current);
|
|
172
|
+
if (parent === current)
|
|
173
|
+
break;
|
|
174
|
+
current = parent;
|
|
175
|
+
}
|
|
176
|
+
return Array.from(new Set(files));
|
|
177
|
+
}
|
|
178
|
+
getLoadResultKey(parsed) {
|
|
179
|
+
return `${parsed.packageName}\0${parsed.stylePath}`;
|
|
180
|
+
}
|
|
181
|
+
getLoadResultPackageName(key) {
|
|
182
|
+
return key.split('\0')[0];
|
|
183
|
+
}
|
|
184
|
+
invalidateLoadResults(packageName) {
|
|
185
|
+
const invalidPackageNames = new Set([packageName]);
|
|
186
|
+
let changed = true;
|
|
187
|
+
while (changed) {
|
|
188
|
+
changed = false;
|
|
189
|
+
for (const [key, dependencyPackages] of this.loadResultDependencies) {
|
|
190
|
+
const resultPackageName = this.getLoadResultPackageName(key);
|
|
191
|
+
const shouldInvalidate = invalidPackageNames.has(resultPackageName) ||
|
|
192
|
+
Array.from(dependencyPackages).some((dependencyPackage) => invalidPackageNames.has(dependencyPackage));
|
|
193
|
+
if (!shouldInvalidate)
|
|
194
|
+
continue;
|
|
195
|
+
if (!invalidPackageNames.has(resultPackageName)) {
|
|
196
|
+
invalidPackageNames.add(resultPackageName);
|
|
197
|
+
changed = true;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
for (const key of this.loadResults.keys()) {
|
|
202
|
+
if (!invalidPackageNames.has(this.getLoadResultPackageName(key))) {
|
|
203
|
+
const dependencyPackages = this.loadResultDependencies.get(key);
|
|
204
|
+
if (!dependencyPackages ||
|
|
205
|
+
!Array.from(dependencyPackages).some((dependencyPackage) => invalidPackageNames.has(dependencyPackage))) {
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
this.loadResults.delete(key);
|
|
210
|
+
this.loadResultDependencies.delete(key);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
66
213
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import type { ModuleStyleBuildConfig } from '#auklet/types';
|
|
2
2
|
import type { ModuleStyleGraphRequestCache } from '#auklet/css/vite/moduleGraph/requestCache';
|
|
3
|
-
import type { PackageStyleId } from '#auklet/css/vite/moduleGraph/types';
|
|
3
|
+
import type { PackageStyleId, PackageStyleLoadResult } from '#auklet/css/vite/moduleGraph/types';
|
|
4
4
|
export declare class StyleCodeFactory {
|
|
5
5
|
private readonly config;
|
|
6
6
|
constructor(config: ModuleStyleBuildConfig);
|
|
7
|
-
createPackageStyleCode(parsed: PackageStyleId, cache: ModuleStyleGraphRequestCache): Promise<
|
|
8
|
-
|
|
9
|
-
watchFiles: string[];
|
|
10
|
-
}>;
|
|
7
|
+
createPackageStyleCode(parsed: PackageStyleId, cache: ModuleStyleGraphRequestCache): Promise<PackageStyleLoadResult>;
|
|
8
|
+
private createUncachedPackageStyleCode;
|
|
11
9
|
private createStyleCode;
|
|
12
10
|
private createDependencyStyleCode;
|
|
13
11
|
private createExternalStyleCode;
|
|
@@ -17,4 +15,5 @@ export declare class StyleCodeFactory {
|
|
|
17
15
|
private toDevModuleImportSpecifier;
|
|
18
16
|
private toDevExternalStyleSpecifier;
|
|
19
17
|
private parsePackageStyleIdInRequest;
|
|
18
|
+
private withDependencyPackage;
|
|
20
19
|
}
|
|
@@ -12,6 +12,9 @@ export class StyleCodeFactory {
|
|
|
12
12
|
this.config = config;
|
|
13
13
|
}
|
|
14
14
|
async createPackageStyleCode(parsed, cache) {
|
|
15
|
+
return cache.getLoadResult(parsed, () => this.createUncachedPackageStyleCode(parsed, cache));
|
|
16
|
+
}
|
|
17
|
+
async createUncachedPackageStyleCode(parsed, cache) {
|
|
15
18
|
const context = await cache.getContext(parsed);
|
|
16
19
|
if (!context) {
|
|
17
20
|
return {
|
|
@@ -19,21 +22,28 @@ export class StyleCodeFactory {
|
|
|
19
22
|
watchFiles: [],
|
|
20
23
|
};
|
|
21
24
|
}
|
|
25
|
+
const cachedResult = cache.readPersistentLoadResult(parsed, context);
|
|
26
|
+
if (cachedResult)
|
|
27
|
+
return cachedResult;
|
|
28
|
+
let result;
|
|
22
29
|
if (parsed.stylePath === STYLE_ENTRY) {
|
|
23
|
-
|
|
30
|
+
result = await this.createStyleCode(context, cache);
|
|
24
31
|
}
|
|
25
|
-
if (parsed.stylePath === EXTERNAL_ENTRY) {
|
|
26
|
-
|
|
32
|
+
else if (parsed.stylePath === EXTERNAL_ENTRY) {
|
|
33
|
+
result = await this.createExternalStyleCode(context, cache);
|
|
27
34
|
}
|
|
28
|
-
if (parsed.stylePath === MODULE_ENTRY) {
|
|
29
|
-
|
|
35
|
+
else if (parsed.stylePath === MODULE_ENTRY) {
|
|
36
|
+
result = this.createModuleStyleCode(context);
|
|
30
37
|
}
|
|
31
|
-
if (parsed.stylePath.startsWith(THEMES_ENTRY_PREFIX)) {
|
|
32
|
-
|
|
38
|
+
else if (parsed.stylePath.startsWith(THEMES_ENTRY_PREFIX)) {
|
|
39
|
+
result = await this.createThemeStyleCode(context, cache, [
|
|
33
40
|
removeStyleExtension(parsed.stylePath.slice(THEMES_ENTRY_PREFIX.length)),
|
|
34
41
|
]);
|
|
35
42
|
}
|
|
36
|
-
|
|
43
|
+
else {
|
|
44
|
+
result = await this.createSourceModuleStyleCode(context, cache, parsed.stylePath);
|
|
45
|
+
}
|
|
46
|
+
return cache.writePersistentLoadResult(parsed, context, result);
|
|
37
47
|
}
|
|
38
48
|
async createStyleCode(context, cache) {
|
|
39
49
|
const results = [];
|
|
@@ -52,23 +62,27 @@ export class StyleCodeFactory {
|
|
|
52
62
|
}
|
|
53
63
|
async createDependencyStyleCode(context, cache, specifiers, mapSpecifier = (specifier) => specifier) {
|
|
54
64
|
const results = [];
|
|
65
|
+
const cacheInputFiles = [];
|
|
55
66
|
const imports = [];
|
|
56
67
|
const watchFiles = [...context.configPaths];
|
|
57
68
|
for (const specifier of specifiers) {
|
|
58
69
|
const outputSpecifier = mapSpecifier(specifier);
|
|
59
70
|
const parsed = this.parsePackageStyleIdInRequest(outputSpecifier, cache);
|
|
60
71
|
if (parsed) {
|
|
61
|
-
|
|
72
|
+
const result = await this.createPackageStyleCode(parsed, cache);
|
|
73
|
+
results.push(this.withDependencyPackage(result, parsed.packageName));
|
|
62
74
|
continue;
|
|
63
75
|
}
|
|
64
76
|
const resolvedSpecifier = toDevDependencyImportSpecifier(context, outputSpecifier);
|
|
65
77
|
imports.push(resolvedSpecifier.specifier);
|
|
78
|
+
cacheInputFiles.push(...(resolvedSpecifier.cacheInputFiles ?? []));
|
|
66
79
|
if (resolvedSpecifier.watchFile) {
|
|
67
80
|
watchFiles.push(resolvedSpecifier.watchFile);
|
|
68
81
|
}
|
|
69
82
|
}
|
|
70
83
|
return mergeLoadResults({
|
|
71
84
|
code: createImportCode(imports),
|
|
85
|
+
cacheInputFiles,
|
|
72
86
|
watchFiles,
|
|
73
87
|
}, ...results);
|
|
74
88
|
}
|
|
@@ -133,15 +147,18 @@ export class StyleCodeFactory {
|
|
|
133
147
|
const moduleStyleResults = [];
|
|
134
148
|
const moduleStyleSpecifiers = [];
|
|
135
149
|
const moduleStyleWatchFiles = [];
|
|
150
|
+
const moduleStyleCacheInputFiles = [];
|
|
136
151
|
for (const specifier of entry.moduleStyleImports) {
|
|
137
152
|
const result = this.toDevModuleImportSpecifier(specifier, context, cache, sourceStyleDir);
|
|
138
153
|
const parsed = this.parsePackageStyleIdInRequest(result, cache);
|
|
139
154
|
if (parsed) {
|
|
140
|
-
|
|
155
|
+
const loadResult = await this.createPackageStyleCode(parsed, cache);
|
|
156
|
+
moduleStyleResults.push(this.withDependencyPackage(loadResult, parsed.packageName));
|
|
141
157
|
continue;
|
|
142
158
|
}
|
|
143
159
|
const resolvedSpecifier = toDevDependencyImportSpecifier(context, result);
|
|
144
160
|
moduleStyleSpecifiers.push(resolvedSpecifier.specifier);
|
|
161
|
+
moduleStyleCacheInputFiles.push(...(resolvedSpecifier.cacheInputFiles ?? []));
|
|
145
162
|
if (resolvedSpecifier.watchFile) {
|
|
146
163
|
moduleStyleWatchFiles.push(resolvedSpecifier.watchFile);
|
|
147
164
|
}
|
|
@@ -167,6 +184,7 @@ export class StyleCodeFactory {
|
|
|
167
184
|
...moduleStyleWatchFiles,
|
|
168
185
|
...sourceFiles.filter((file) => /\.(ts|tsx)$/.test(file)),
|
|
169
186
|
],
|
|
187
|
+
cacheInputFiles: moduleStyleCacheInputFiles,
|
|
170
188
|
});
|
|
171
189
|
}
|
|
172
190
|
toDevModuleImportSpecifier(specifier, context, cache, sourceStyleDir) {
|
|
@@ -190,4 +208,10 @@ export class StyleCodeFactory {
|
|
|
190
208
|
parsePackageStyleIdInRequest(id, cache) {
|
|
191
209
|
return parsePackageStyleId(id, cache.getPackageNames());
|
|
192
210
|
}
|
|
211
|
+
withDependencyPackage(result, packageName) {
|
|
212
|
+
return {
|
|
213
|
+
...result,
|
|
214
|
+
dependencyPackages: Array.from(new Set([packageName, ...(result.dependencyPackages ?? [])])),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
193
217
|
}
|
|
@@ -11,7 +11,9 @@ export type PackageStyleId = {
|
|
|
11
11
|
};
|
|
12
12
|
export type PackageStyleLoadResult = {
|
|
13
13
|
code: string;
|
|
14
|
+
cacheInputFiles?: Array<string>;
|
|
14
15
|
watchFiles: Array<string>;
|
|
16
|
+
dependencyPackages?: Array<string>;
|
|
15
17
|
};
|
|
16
18
|
export type LoadAukletConfig = (packageRoot: string, options?: {
|
|
17
19
|
cacheBust?: boolean;
|