auklet 0.0.3 → 0.0.5
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/README.md +99 -42
- package/bin/entry.cjs +33 -11
- package/dist/build/runTsdown.js +2 -3
- package/dist/build/tsdownConfig.d.ts +138 -2
- package/dist/build/tsdownConfig.js +108 -63
- package/dist/config.d.ts +38 -6
- package/dist/config.js +43 -7
- package/dist/configLoader.js +1 -2
- package/dist/css/config.d.ts +2 -0
- package/dist/css/config.js +10 -0
- package/dist/css/constants.d.ts +7 -0
- package/dist/css/constants.js +7 -0
- package/dist/css/core/moduleGraph.d.ts +55 -0
- package/dist/css/core/moduleGraph.js +363 -0
- package/dist/css/core/moduleGraphRequestCache.d.ts +80 -0
- package/dist/css/core/moduleGraphRequestCache.js +92 -0
- package/dist/css/core/style/dependencies.d.ts +20 -0
- package/dist/css/core/style/dependencies.js +55 -0
- package/dist/css/core/style/files.d.ts +8 -0
- package/dist/css/core/style/files.js +19 -0
- package/dist/css/core/style/plan.d.ts +59 -0
- package/dist/css/core/style/plan.js +27 -0
- package/dist/css/core/style/specifier.d.ts +14 -0
- package/dist/css/core/style/specifier.js +27 -0
- package/dist/css/core/{moduleStyleImportCollector.d.ts → styleImports/collector.d.ts} +5 -5
- package/dist/css/core/{moduleStyleImportCollector.js → styleImports/collector.js} +36 -99
- package/dist/css/core/styleImports/sourceReference.d.ts +19 -0
- package/dist/css/core/styleImports/sourceReference.js +193 -0
- package/dist/css/core/styleModuleEntryPlanner.d.ts +29 -0
- package/dist/css/core/styleModuleEntryPlanner.js +67 -0
- package/dist/css/core/stylePackageContext.d.ts +27 -0
- package/dist/css/core/stylePackageContext.js +57 -0
- package/dist/css/core/styleProcessor.d.ts +3 -3
- package/dist/css/core/styleProcessor.js +18 -35
- package/dist/css/core/workspaceStyleResolver.d.ts +4 -5
- package/dist/css/core/workspaceStyleResolver.js +12 -28
- package/dist/css/production/builder.d.ts +18 -0
- package/dist/css/production/builder.js +68 -0
- package/dist/css/production/format/componentWriter.d.ts +12 -0
- package/dist/css/production/format/componentWriter.js +67 -0
- package/dist/css/production/format/entryWriter.d.ts +12 -0
- package/dist/css/production/format/entryWriter.js +54 -0
- package/dist/css/production/format/externalWriter.d.ts +9 -0
- package/dist/css/production/format/externalWriter.js +39 -0
- package/dist/css/production/format/moduleWriter.d.ts +8 -0
- package/dist/css/production/format/moduleWriter.js +31 -0
- package/dist/css/production/format/shared.d.ts +20 -0
- package/dist/css/production/format/shared.js +8 -0
- package/dist/css/production/format/sourceWriter.d.ts +6 -0
- package/dist/css/production/format/sourceWriter.js +16 -0
- package/dist/css/production/format/themeWriter.d.ts +16 -0
- package/dist/css/production/format/themeWriter.js +80 -0
- package/dist/css/production/moduleOutputWriter.d.ts +26 -0
- package/dist/css/production/moduleOutputWriter.js +83 -0
- package/dist/css/production/packageEntryWriter.d.ts +20 -0
- package/dist/css/production/packageEntryWriter.js +55 -0
- package/dist/css/vite/hmr.d.ts +4 -4
- package/dist/css/vite/hmr.js +14 -27
- package/dist/css/vite/vitePlugin.d.ts +5 -5
- package/dist/css/vite/vitePlugin.js +21 -30
- package/dist/css/watch/{moduleCssWatcher.d.ts → watcher.d.ts} +8 -4
- package/dist/css/watch/watcher.js +91 -0
- package/dist/index.d.ts +15 -12
- package/dist/index.js +6 -5
- package/dist/types.d.ts +40 -20
- package/dist/utils.d.ts +5 -1
- package/dist/utils.js +37 -12
- package/package.json +19 -14
- package/dist/css/core/config.d.ts +0 -2
- package/dist/css/core/config.js +0 -11
- package/dist/css/core/constants.d.ts +0 -3
- package/dist/css/core/constants.js +0 -3
- package/dist/css/core/moduleCssGraph.d.ts +0 -51
- package/dist/css/core/moduleCssGraph.js +0 -416
- package/dist/css/core/path.d.ts +0 -4
- package/dist/css/core/path.js +0 -26
- package/dist/css/core/styleEntry.d.ts +0 -45
- package/dist/css/core/styleEntry.js +0 -108
- package/dist/css/production/moduleCssBuilder.d.ts +0 -33
- package/dist/css/production/moduleCssBuilder.js +0 -445
- package/dist/css/watch/moduleCssWatcher.js +0 -106
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export class SourceStyleFileWriter {
|
|
4
|
+
sourceRoot;
|
|
5
|
+
constructor(options) {
|
|
6
|
+
this.sourceRoot = options.packageContext.sourceRoot;
|
|
7
|
+
}
|
|
8
|
+
copy(files, outRoot) {
|
|
9
|
+
for (const sourceFile of files) {
|
|
10
|
+
const relative = path.relative(this.sourceRoot, sourceFile);
|
|
11
|
+
const target = path.join(outRoot, relative);
|
|
12
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
13
|
+
fs.copyFileSync(sourceFile, target);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type FormatWriterOptions,
|
|
3
|
+
type ThemeStyleOutput,
|
|
4
|
+
} from '#auklet/css/production/format/shared';
|
|
5
|
+
export declare class ThemeStyleWriter {
|
|
6
|
+
private readonly config;
|
|
7
|
+
private readonly packageContext;
|
|
8
|
+
private readonly styleProcessor;
|
|
9
|
+
constructor(options: FormatWriterOptions);
|
|
10
|
+
clean(outRoot: string): void;
|
|
11
|
+
writeThemeStyles(outRoot: string): ThemeStyleOutput[];
|
|
12
|
+
writeThemeEntries(
|
|
13
|
+
themeStyles: Map<string, string>,
|
|
14
|
+
outRoot: string,
|
|
15
|
+
): string[];
|
|
16
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { THEMES_DIR } from '#auklet/css/constants';
|
|
4
|
+
import { createThemeEntryParts } from '#auklet/css/core/style/plan';
|
|
5
|
+
import { toRelativeImportSpecifier } from '#auklet/css/production/format/shared';
|
|
6
|
+
export class ThemeStyleWriter {
|
|
7
|
+
config;
|
|
8
|
+
packageContext;
|
|
9
|
+
styleProcessor;
|
|
10
|
+
constructor(options) {
|
|
11
|
+
this.config = options.config;
|
|
12
|
+
this.packageContext = options.packageContext;
|
|
13
|
+
this.styleProcessor = options.packageContext.styleProcessor;
|
|
14
|
+
}
|
|
15
|
+
clean(outRoot) {
|
|
16
|
+
fs.rmSync(path.join(outRoot, THEMES_DIR), {
|
|
17
|
+
recursive: true,
|
|
18
|
+
force: true,
|
|
19
|
+
});
|
|
20
|
+
fs.rmSync(path.join(outRoot, this.config.output.styleDir, THEMES_DIR), {
|
|
21
|
+
recursive: true,
|
|
22
|
+
force: true,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
writeThemeStyles(outRoot) {
|
|
26
|
+
const outputs = [];
|
|
27
|
+
const themesDir = path.join(
|
|
28
|
+
outRoot,
|
|
29
|
+
this.config.output.styleDir,
|
|
30
|
+
THEMES_DIR,
|
|
31
|
+
);
|
|
32
|
+
for (const [themeName, stylePath] of this.packageContext.themeFiles) {
|
|
33
|
+
const root = this.styleProcessor.createRoot();
|
|
34
|
+
const content = this.styleProcessor.readStyleFile(stylePath);
|
|
35
|
+
if (content.trim()) {
|
|
36
|
+
this.styleProcessor.appendStyleContent(root, content, stylePath);
|
|
37
|
+
}
|
|
38
|
+
const target = path.join(themesDir, `${themeName}.css`);
|
|
39
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
40
|
+
fs.writeFileSync(
|
|
41
|
+
target,
|
|
42
|
+
root.nodes?.length ? this.styleProcessor.stringify(root) : '',
|
|
43
|
+
);
|
|
44
|
+
outputs.push({ themeName, file: target });
|
|
45
|
+
}
|
|
46
|
+
return outputs;
|
|
47
|
+
}
|
|
48
|
+
writeThemeEntries(themeStyles, outRoot) {
|
|
49
|
+
const outputs = [];
|
|
50
|
+
const themesDir = path.join(outRoot, THEMES_DIR);
|
|
51
|
+
for (const themeName of this.packageContext.themeNames) {
|
|
52
|
+
const target = path.join(themesDir, `${themeName}.css`);
|
|
53
|
+
const root = this.styleProcessor.createRoot();
|
|
54
|
+
const targetDir = path.dirname(target);
|
|
55
|
+
const themeStyle = themeStyles.get(themeName);
|
|
56
|
+
for (const part of createThemeEntryParts(
|
|
57
|
+
this.packageContext.normalizedConfig,
|
|
58
|
+
themeName,
|
|
59
|
+
)) {
|
|
60
|
+
if (part.type === 'dependencies') {
|
|
61
|
+
for (const specifier of part.specifiers) {
|
|
62
|
+
this.styleProcessor.appendImportRule(root, specifier);
|
|
63
|
+
}
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (themeStyle) {
|
|
67
|
+
this.styleProcessor.appendImportRule(
|
|
68
|
+
root,
|
|
69
|
+
toRelativeImportSpecifier(targetDir, themeStyle),
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (!root.nodes?.length) continue;
|
|
74
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
75
|
+
fs.writeFileSync(target, this.styleProcessor.stringify(root));
|
|
76
|
+
outputs.push(target);
|
|
77
|
+
}
|
|
78
|
+
return outputs;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { StylePackageContext } from '#auklet/css/core/stylePackageContext';
|
|
2
|
+
import type {
|
|
3
|
+
ModuleStyleBuildConfig,
|
|
4
|
+
ResolvedModuleStyleBuildContext,
|
|
5
|
+
} from '#auklet/types';
|
|
6
|
+
export type ModuleStyleOutputWriterOptions = {
|
|
7
|
+
config: ModuleStyleBuildConfig;
|
|
8
|
+
context: ResolvedModuleStyleBuildContext;
|
|
9
|
+
packageContext: StylePackageContext;
|
|
10
|
+
};
|
|
11
|
+
export declare class ModuleStyleOutputWriter {
|
|
12
|
+
private readonly config;
|
|
13
|
+
private readonly context;
|
|
14
|
+
private readonly packageContext;
|
|
15
|
+
private readonly sourceWriter;
|
|
16
|
+
private readonly themeWriter;
|
|
17
|
+
private readonly externalWriter;
|
|
18
|
+
private readonly moduleWriter;
|
|
19
|
+
private readonly entryWriter;
|
|
20
|
+
private readonly componentWriter;
|
|
21
|
+
constructor(options: ModuleStyleOutputWriterOptions);
|
|
22
|
+
write(): string[];
|
|
23
|
+
private get outputRoot();
|
|
24
|
+
private createComponentEntries;
|
|
25
|
+
private writeFormat;
|
|
26
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { StyleModuleEntryPlanner } from '#auklet/css/core/styleModuleEntryPlanner';
|
|
3
|
+
import { ComponentStyleEntryWriter } from '#auklet/css/production/format/componentWriter';
|
|
4
|
+
import { StyleEntryWriter } from '#auklet/css/production/format/entryWriter';
|
|
5
|
+
import { ExternalStyleWriter } from '#auklet/css/production/format/externalWriter';
|
|
6
|
+
import { ModuleStyleWriter } from '#auklet/css/production/format/moduleWriter';
|
|
7
|
+
import { SourceStyleFileWriter } from '#auklet/css/production/format/sourceWriter';
|
|
8
|
+
import { ThemeStyleWriter } from '#auklet/css/production/format/themeWriter';
|
|
9
|
+
// Coordinates all module-mode style output under format directories such as `dist/es` and `dist/lib`.
|
|
10
|
+
export class ModuleStyleOutputWriter {
|
|
11
|
+
config;
|
|
12
|
+
context;
|
|
13
|
+
packageContext;
|
|
14
|
+
sourceWriter;
|
|
15
|
+
themeWriter;
|
|
16
|
+
externalWriter;
|
|
17
|
+
moduleWriter;
|
|
18
|
+
entryWriter;
|
|
19
|
+
componentWriter;
|
|
20
|
+
constructor(options) {
|
|
21
|
+
this.config = options.config;
|
|
22
|
+
this.context = options.context;
|
|
23
|
+
this.packageContext = options.packageContext;
|
|
24
|
+
this.sourceWriter = new SourceStyleFileWriter(options);
|
|
25
|
+
this.themeWriter = new ThemeStyleWriter(options);
|
|
26
|
+
this.externalWriter = new ExternalStyleWriter(options);
|
|
27
|
+
this.moduleWriter = new ModuleStyleWriter(options);
|
|
28
|
+
this.entryWriter = new StyleEntryWriter(options);
|
|
29
|
+
this.componentWriter = new ComponentStyleEntryWriter(options);
|
|
30
|
+
}
|
|
31
|
+
write() {
|
|
32
|
+
const componentEntries = this.createComponentEntries();
|
|
33
|
+
const outputs = [];
|
|
34
|
+
for (const format of this.config.output.outputFormats) {
|
|
35
|
+
outputs.push(...this.writeFormat(format, componentEntries));
|
|
36
|
+
}
|
|
37
|
+
return outputs;
|
|
38
|
+
}
|
|
39
|
+
get outputRoot() {
|
|
40
|
+
return path.join(this.context.packageRoot, this.context.outputDir);
|
|
41
|
+
}
|
|
42
|
+
createComponentEntries() {
|
|
43
|
+
const moduleStyleImports = this.packageContext.importCollector.collect(
|
|
44
|
+
this.packageContext.sourceFiles,
|
|
45
|
+
this.packageContext.normalizedConfig,
|
|
46
|
+
);
|
|
47
|
+
return new StyleModuleEntryPlanner(this.packageContext).createEntries(
|
|
48
|
+
moduleStyleImports,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
writeFormat(format, componentEntries) {
|
|
52
|
+
const outRoot = path.join(this.outputRoot, format);
|
|
53
|
+
const outputs = [];
|
|
54
|
+
this.themeWriter.clean(outRoot);
|
|
55
|
+
this.sourceWriter.copy(this.packageContext.styleFiles, outRoot);
|
|
56
|
+
const themeStyles = this.themeWriter.writeThemeStyles(outRoot);
|
|
57
|
+
const themeStyleMap = new Map(
|
|
58
|
+
themeStyles.map((themeStyle) => [themeStyle.themeName, themeStyle.file]),
|
|
59
|
+
);
|
|
60
|
+
const themeEntries = this.themeWriter.writeThemeEntries(
|
|
61
|
+
themeStyleMap,
|
|
62
|
+
outRoot,
|
|
63
|
+
);
|
|
64
|
+
const externalStyle = this.externalWriter.write(outRoot);
|
|
65
|
+
const moduleStyle = this.moduleWriter.write(outRoot);
|
|
66
|
+
const entryStyle = this.entryWriter.write(
|
|
67
|
+
outRoot,
|
|
68
|
+
themeStyleMap,
|
|
69
|
+
moduleStyle,
|
|
70
|
+
);
|
|
71
|
+
const componentStyles = this.componentWriter.write(
|
|
72
|
+
outRoot,
|
|
73
|
+
componentEntries,
|
|
74
|
+
);
|
|
75
|
+
outputs.push(...themeStyles.map((themeStyle) => themeStyle.file));
|
|
76
|
+
outputs.push(...themeEntries);
|
|
77
|
+
if (externalStyle) outputs.push(externalStyle);
|
|
78
|
+
if (moduleStyle) outputs.push(moduleStyle);
|
|
79
|
+
if (entryStyle) outputs.push(entryStyle);
|
|
80
|
+
outputs.push(...componentStyles);
|
|
81
|
+
return outputs;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { StylePackageContext } from '#auklet/css/core/stylePackageContext';
|
|
2
|
+
import type {
|
|
3
|
+
ModuleStyleBuildConfig,
|
|
4
|
+
ResolvedModuleStyleBuildContext,
|
|
5
|
+
} from '#auklet/types';
|
|
6
|
+
export type PackageStyleEntryWriterOptions = {
|
|
7
|
+
config: ModuleStyleBuildConfig;
|
|
8
|
+
context: ResolvedModuleStyleBuildContext;
|
|
9
|
+
packageContext: StylePackageContext;
|
|
10
|
+
};
|
|
11
|
+
export declare class PackageStyleEntryWriter {
|
|
12
|
+
private readonly config;
|
|
13
|
+
private readonly context;
|
|
14
|
+
private readonly packageContext;
|
|
15
|
+
private readonly resolver;
|
|
16
|
+
private readonly styleProcessor;
|
|
17
|
+
constructor(options: PackageStyleEntryWriterOptions);
|
|
18
|
+
write(): string | null;
|
|
19
|
+
private get outputRoot();
|
|
20
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { getGlobalStyleDependencies } from '#auklet/css/core/style/dependencies';
|
|
4
|
+
// Builds the package-level style entry at `dist/index.css` by aggregating local themes, dependencies, and source styles.
|
|
5
|
+
export class PackageStyleEntryWriter {
|
|
6
|
+
config;
|
|
7
|
+
context;
|
|
8
|
+
packageContext;
|
|
9
|
+
resolver;
|
|
10
|
+
styleProcessor;
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this.config = options.config;
|
|
13
|
+
this.context = options.context;
|
|
14
|
+
this.packageContext = options.packageContext;
|
|
15
|
+
this.resolver = options.packageContext.resolver;
|
|
16
|
+
this.styleProcessor = options.packageContext.styleProcessor;
|
|
17
|
+
}
|
|
18
|
+
write() {
|
|
19
|
+
const seen = new Set();
|
|
20
|
+
const root = this.styleProcessor.createRoot();
|
|
21
|
+
for (const stylePath of this.packageContext.themeFiles.values()) {
|
|
22
|
+
const content = this.styleProcessor.readStyleFile(stylePath, seen);
|
|
23
|
+
if (content.trim()) {
|
|
24
|
+
this.styleProcessor.appendStyleContent(root, content, stylePath);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
for (const specifier of getGlobalStyleDependencies(
|
|
28
|
+
this.packageContext.normalizedConfig,
|
|
29
|
+
)) {
|
|
30
|
+
const stylePath = this.resolver.resolveStyleDependency(specifier);
|
|
31
|
+
if (!stylePath) continue;
|
|
32
|
+
const content = this.styleProcessor.readStyleFile(stylePath, seen);
|
|
33
|
+
if (content.trim()) {
|
|
34
|
+
this.styleProcessor.appendStyleContent(root, content, stylePath);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
for (const styleFile of this.packageContext.styleFiles) {
|
|
38
|
+
const content = this.styleProcessor.readStyleFile(styleFile, seen);
|
|
39
|
+
if (content.trim()) {
|
|
40
|
+
this.styleProcessor.appendStyleContent(root, content, styleFile);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (!root.nodes?.length) return null;
|
|
44
|
+
fs.mkdirSync(this.outputRoot, { recursive: true });
|
|
45
|
+
const target = path.join(
|
|
46
|
+
this.outputRoot,
|
|
47
|
+
this.config.output.indexStyleFile,
|
|
48
|
+
);
|
|
49
|
+
fs.writeFileSync(target, this.styleProcessor.stringify(root));
|
|
50
|
+
return target;
|
|
51
|
+
}
|
|
52
|
+
get outputRoot() {
|
|
53
|
+
return path.join(this.context.packageRoot, this.context.outputDir);
|
|
54
|
+
}
|
|
55
|
+
}
|
package/dist/css/vite/hmr.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { HotUpdateOptions, ViteDevServer } from 'vite';
|
|
2
|
-
import type {
|
|
3
|
-
export declare class
|
|
2
|
+
import type { ModuleStyleGraph } from '#auklet/css/core/moduleGraph';
|
|
3
|
+
export declare class AukletStyleHmr {
|
|
4
4
|
private readonly graph;
|
|
5
5
|
private readonly lastUpdateTimes;
|
|
6
6
|
private suppressFullReloadUntil;
|
|
7
7
|
private readonly virtualIdsByDependency;
|
|
8
|
-
constructor(graph: () =>
|
|
9
|
-
|
|
8
|
+
constructor(graph: () => ModuleStyleGraph);
|
|
9
|
+
trackVirtualStyleDependency(file: string, virtualId: string): void;
|
|
10
10
|
installFullReloadGuard(server: Pick<ViteDevServer, 'ws'>): void;
|
|
11
11
|
handleStyleHotUpdate(context: HotUpdateOptions): never[] | undefined;
|
|
12
12
|
private suppressFullReload;
|
package/dist/css/vite/hmr.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import {
|
|
2
|
+
import { normalizeFileKey } from '#auklet/utils';
|
|
3
3
|
// package CSS 的 HMR 不能直接走 Vite 原生 CSS 文件链路:
|
|
4
4
|
// - 浏览器 import 的是 auklet-css:* 虚拟 CSS 模块,不是真实的
|
|
5
5
|
// packages/*/src/**/*.css 文件,所以真实 CSS 变化时 Vite 的 modules 可能为空。
|
|
@@ -30,24 +30,14 @@ const invalidateVirtualModules = (server, graph) => {
|
|
|
30
30
|
}
|
|
31
31
|
return modules;
|
|
32
32
|
};
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
const values =
|
|
37
|
-
(_a = virtualIdsByDependency.get(normalizedFile)) !== null && _a !== void 0
|
|
38
|
-
? _a
|
|
39
|
-
: new Set();
|
|
33
|
+
const addVirtualStyleDependency = (virtualIdsByDependency, file, virtualId) => {
|
|
34
|
+
const normalizedFile = normalizeFileKey(file);
|
|
35
|
+
const values = virtualIdsByDependency.get(normalizedFile) ?? new Set();
|
|
40
36
|
values.add(virtualId);
|
|
41
37
|
virtualIdsByDependency.set(normalizedFile, values);
|
|
42
38
|
};
|
|
43
39
|
const getDependencyVirtualIds = (virtualIdsByDependency, file) => {
|
|
44
|
-
|
|
45
|
-
return Array.from(
|
|
46
|
-
(_a = virtualIdsByDependency.get(normalizeCssFileKey(file))) !== null &&
|
|
47
|
-
_a !== void 0
|
|
48
|
-
? _a
|
|
49
|
-
: [],
|
|
50
|
-
);
|
|
40
|
+
return Array.from(virtualIdsByDependency.get(normalizeFileKey(file)) ?? []);
|
|
51
41
|
};
|
|
52
42
|
const getDependencyVirtualModules = (virtualIdsByDependency, server, file) => {
|
|
53
43
|
return getDependencyVirtualIds(virtualIdsByDependency, file).flatMap((id) => {
|
|
@@ -55,15 +45,16 @@ const getDependencyVirtualModules = (virtualIdsByDependency, server, file) => {
|
|
|
55
45
|
return module ? [module] : [];
|
|
56
46
|
});
|
|
57
47
|
};
|
|
58
|
-
export class
|
|
48
|
+
export class AukletStyleHmr {
|
|
49
|
+
graph;
|
|
50
|
+
lastUpdateTimes = new Map();
|
|
51
|
+
suppressFullReloadUntil = 0;
|
|
52
|
+
virtualIdsByDependency = new Map();
|
|
59
53
|
constructor(graph) {
|
|
60
54
|
this.graph = graph;
|
|
61
|
-
this.lastUpdateTimes = new Map();
|
|
62
|
-
this.suppressFullReloadUntil = 0;
|
|
63
|
-
this.virtualIdsByDependency = new Map();
|
|
64
55
|
}
|
|
65
|
-
|
|
66
|
-
|
|
56
|
+
trackVirtualStyleDependency(file, virtualId) {
|
|
57
|
+
addVirtualStyleDependency(this.virtualIdsByDependency, file, virtualId);
|
|
67
58
|
}
|
|
68
59
|
installFullReloadGuard(server) {
|
|
69
60
|
const send = server.ws.send.bind(server.ws);
|
|
@@ -139,13 +130,9 @@ export class AukletCssHmr {
|
|
|
139
130
|
return Date.now() <= this.suppressFullReloadUntil;
|
|
140
131
|
}
|
|
141
132
|
isDuplicateUpdate(file) {
|
|
142
|
-
var _a;
|
|
143
133
|
const now = Date.now();
|
|
144
|
-
const normalizedFile =
|
|
145
|
-
const lastUpdateTime =
|
|
146
|
-
(_a = this.lastUpdateTimes.get(normalizedFile)) !== null && _a !== void 0
|
|
147
|
-
? _a
|
|
148
|
-
: 0;
|
|
134
|
+
const normalizedFile = normalizeFileKey(file);
|
|
135
|
+
const lastUpdateTime = this.lastUpdateTimes.get(normalizedFile) ?? 0;
|
|
149
136
|
const isDuplicate = now - lastUpdateTime < DUPLICATE_UPDATE_IGNORE_MS;
|
|
150
137
|
this.lastUpdateTimes.set(normalizedFile, now);
|
|
151
138
|
return isDuplicate;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { HotUpdateOptions, ViteDevServer } from 'vite';
|
|
2
|
-
import { type
|
|
3
|
-
export type
|
|
4
|
-
Pick<
|
|
2
|
+
import { type ModuleStyleGraphOptions } from '#auklet/css/core/moduleGraph';
|
|
3
|
+
export type AukletStylePluginOptions = Partial<
|
|
4
|
+
Pick<ModuleStyleGraphOptions, 'workspaceRoot'>
|
|
5
5
|
> &
|
|
6
|
-
Omit<
|
|
7
|
-
export declare function
|
|
6
|
+
Omit<ModuleStyleGraphOptions, 'workspaceRoot'>;
|
|
7
|
+
export declare function aukletStylePlugin(options?: AukletStylePluginOptions): {
|
|
8
8
|
name: string;
|
|
9
9
|
apply: 'serve';
|
|
10
10
|
enforce: 'pre';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { ModuleStyleGraph } from '#auklet/css/core/moduleGraph';
|
|
4
|
+
import { AukletStyleHmr } from '#auklet/css/vite/hmr';
|
|
5
5
|
const WORKSPACE_FILE = 'pnpm-workspace.yaml';
|
|
6
6
|
const VIRTUAL_ID_PREFIX = 'virtual:auklet-css:';
|
|
7
7
|
const RESOLVED_VIRTUAL_ID_PREFIX = '\0auklet-css:';
|
|
@@ -29,16 +29,10 @@ const findWorkspaceRoot = (startDir) => {
|
|
|
29
29
|
current = parent;
|
|
30
30
|
}
|
|
31
31
|
};
|
|
32
|
-
const
|
|
33
|
-
var _a, _b;
|
|
32
|
+
const createModuleStyleGraph = (options, viteRoot) => {
|
|
34
33
|
const workspaceRoot =
|
|
35
|
-
(
|
|
36
|
-
|
|
37
|
-
? _a
|
|
38
|
-
: findWorkspaceRoot(viteRoot)) !== null && _b !== void 0
|
|
39
|
-
? _b
|
|
40
|
-
: process.cwd();
|
|
41
|
-
return new ModuleCssGraph({
|
|
34
|
+
options.workspaceRoot ?? findWorkspaceRoot(viteRoot) ?? process.cwd();
|
|
35
|
+
return new ModuleStyleGraph({
|
|
42
36
|
...options,
|
|
43
37
|
workspaceRoot,
|
|
44
38
|
});
|
|
@@ -57,21 +51,21 @@ const invalidateVirtualModules = (server, graph) => {
|
|
|
57
51
|
}
|
|
58
52
|
return modules;
|
|
59
53
|
};
|
|
60
|
-
export function
|
|
54
|
+
export function aukletStylePlugin(options = {}) {
|
|
61
55
|
let graph = null;
|
|
62
56
|
const getGraph = () => {
|
|
63
57
|
if (!graph) {
|
|
64
|
-
graph =
|
|
58
|
+
graph = createModuleStyleGraph(options, process.cwd());
|
|
65
59
|
}
|
|
66
60
|
return graph;
|
|
67
61
|
};
|
|
68
|
-
const hmr = new
|
|
62
|
+
const hmr = new AukletStyleHmr(getGraph);
|
|
69
63
|
return {
|
|
70
64
|
name: 'auklet-css',
|
|
71
65
|
apply: 'serve',
|
|
72
66
|
enforce: 'pre',
|
|
73
67
|
configResolved(config) {
|
|
74
|
-
graph =
|
|
68
|
+
graph = createModuleStyleGraph(options, config.root);
|
|
75
69
|
},
|
|
76
70
|
resolveId(id) {
|
|
77
71
|
const graph = getGraph();
|
|
@@ -83,22 +77,19 @@ export function aukletCssPlugin(options = {}) {
|
|
|
83
77
|
VIRTUAL_ID_PREFIX.length,
|
|
84
78
|
)}`;
|
|
85
79
|
}
|
|
86
|
-
if (!graph.
|
|
80
|
+
if (!graph.parsePackageStyleId(cleanId)) return null;
|
|
87
81
|
return `${RESOLVED_VIRTUAL_ID_PREFIX}${cleanId}`;
|
|
88
82
|
},
|
|
89
83
|
async load(id) {
|
|
90
|
-
var _a;
|
|
91
84
|
if (!id.startsWith(RESOLVED_VIRTUAL_ID_PREFIX)) return null;
|
|
92
85
|
const originalId = id.slice(RESOLVED_VIRTUAL_ID_PREFIX.length);
|
|
93
86
|
const graph = getGraph();
|
|
94
|
-
const parsed = graph.
|
|
87
|
+
const parsed = graph.parsePackageStyleId(originalId);
|
|
95
88
|
if (!parsed) return null;
|
|
96
|
-
const result = await graph.
|
|
89
|
+
const result = await graph.createPackageStyleCode(parsed);
|
|
97
90
|
for (const file of result.watchFiles) {
|
|
98
|
-
hmr.
|
|
99
|
-
|
|
100
|
-
? void 0
|
|
101
|
-
: _a.call(this, file);
|
|
91
|
+
hmr.trackVirtualStyleDependency(file, id);
|
|
92
|
+
this.addWatchFile?.(file);
|
|
102
93
|
}
|
|
103
94
|
return result.code;
|
|
104
95
|
},
|
|
@@ -106,27 +97,27 @@ export function aukletCssPlugin(options = {}) {
|
|
|
106
97
|
const graph = getGraph();
|
|
107
98
|
hmr.installFullReloadGuard(server);
|
|
108
99
|
server.watcher.add(graph.getWatchRoots());
|
|
109
|
-
const
|
|
100
|
+
const invalidateStyleGraph = (file) => {
|
|
110
101
|
if (!graph.isWorkspaceSourceGraphFile(file)) return false;
|
|
111
102
|
invalidateVirtualModules(server, graph);
|
|
112
103
|
return true;
|
|
113
104
|
};
|
|
114
|
-
const
|
|
115
|
-
if (!
|
|
105
|
+
const reloadStyleGraph = (file) => {
|
|
106
|
+
if (!invalidateStyleGraph(file)) return;
|
|
116
107
|
server.ws.send({ type: 'full-reload' });
|
|
117
108
|
};
|
|
118
109
|
const handleSourceAddOrUnlink = (file) => {
|
|
119
110
|
if (graph.isStyleFile(file)) {
|
|
120
|
-
|
|
111
|
+
invalidateStyleGraph(file);
|
|
121
112
|
return;
|
|
122
113
|
}
|
|
123
|
-
|
|
114
|
+
reloadStyleGraph(file);
|
|
124
115
|
};
|
|
125
116
|
server.watcher.on('add', handleSourceAddOrUnlink);
|
|
126
117
|
server.watcher.on('unlink', handleSourceAddOrUnlink);
|
|
127
118
|
server.watcher.on('change', (file) => {
|
|
128
|
-
if (graph.
|
|
129
|
-
|
|
119
|
+
if (graph.isStyleConfigFile(file)) {
|
|
120
|
+
reloadStyleGraph(file);
|
|
130
121
|
}
|
|
131
122
|
});
|
|
132
123
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
ModuleStyleBuildConfig,
|
|
3
|
+
ModuleStyleBuildContext,
|
|
4
4
|
} from '#auklet/types';
|
|
5
|
-
export declare class
|
|
5
|
+
export declare class ModuleStyleWatcher {
|
|
6
6
|
private readonly config;
|
|
7
7
|
private readonly context;
|
|
8
8
|
private readonly logger?;
|
|
@@ -10,10 +10,14 @@ export declare class ModuleCssWatcher {
|
|
|
10
10
|
private isBuilding;
|
|
11
11
|
private shouldRebuild;
|
|
12
12
|
private watcher;
|
|
13
|
-
constructor(
|
|
13
|
+
constructor(
|
|
14
|
+
context?: ModuleStyleBuildContext,
|
|
15
|
+
config?: ModuleStyleBuildConfig,
|
|
16
|
+
);
|
|
14
17
|
watch(): Promise<void>;
|
|
15
18
|
private rebuild;
|
|
16
19
|
private refreshWatcher;
|
|
17
20
|
private scheduleBuild;
|
|
21
|
+
private shouldRebuildForFile;
|
|
18
22
|
close(): Promise<void>;
|
|
19
23
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import chokidar from 'chokidar';
|
|
4
|
+
import { aukletConfigFile, aukletDefaultOptions } from '#auklet/config';
|
|
5
|
+
import { moduleStyleBuildConfig } from '#auklet/css/config';
|
|
6
|
+
import { SOURCE_COMPONENT_MODULE_RE } from '#auklet/css/constants';
|
|
7
|
+
import { ModuleStyleBuilder } from '#auklet/css/production/builder';
|
|
8
|
+
export class ModuleStyleWatcher {
|
|
9
|
+
config;
|
|
10
|
+
context;
|
|
11
|
+
logger;
|
|
12
|
+
timer = null;
|
|
13
|
+
isBuilding = false;
|
|
14
|
+
shouldRebuild = false;
|
|
15
|
+
watcher = null;
|
|
16
|
+
constructor(context = {}, config = moduleStyleBuildConfig) {
|
|
17
|
+
this.config = config;
|
|
18
|
+
this.context = {
|
|
19
|
+
packageRoot: process.cwd(),
|
|
20
|
+
...context,
|
|
21
|
+
};
|
|
22
|
+
this.logger = context.logger;
|
|
23
|
+
}
|
|
24
|
+
async watch() {
|
|
25
|
+
await this.rebuild();
|
|
26
|
+
this.logger?.log?.('[auklet:css] watch mode ready');
|
|
27
|
+
}
|
|
28
|
+
async rebuild() {
|
|
29
|
+
if (this.isBuilding) {
|
|
30
|
+
this.shouldRebuild = true;
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
this.isBuilding = true;
|
|
34
|
+
try {
|
|
35
|
+
const builder = new ModuleStyleBuilder(this.context, this.config);
|
|
36
|
+
await builder.build();
|
|
37
|
+
await this.refreshWatcher();
|
|
38
|
+
} catch (error) {
|
|
39
|
+
this.logger?.error?.(error);
|
|
40
|
+
} finally {
|
|
41
|
+
this.isBuilding = false;
|
|
42
|
+
if (this.shouldRebuild) {
|
|
43
|
+
this.shouldRebuild = false;
|
|
44
|
+
this.scheduleBuild();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async refreshWatcher() {
|
|
49
|
+
const aukletConfig = this.context.aukletConfig ?? {};
|
|
50
|
+
const sourceDir =
|
|
51
|
+
this.context.source ?? aukletConfig.source ?? aukletDefaultOptions.source;
|
|
52
|
+
const sourceRoot = path.join(this.context.packageRoot, sourceDir);
|
|
53
|
+
const configPath = path.join(this.context.packageRoot, aukletConfigFile);
|
|
54
|
+
const watchPaths = [sourceRoot, configPath].filter((file) =>
|
|
55
|
+
fs.existsSync(file),
|
|
56
|
+
);
|
|
57
|
+
await this.watcher?.close();
|
|
58
|
+
this.watcher = chokidar.watch(watchPaths, {
|
|
59
|
+
ignoreInitial: true,
|
|
60
|
+
interval: 300,
|
|
61
|
+
usePolling: true,
|
|
62
|
+
});
|
|
63
|
+
this.watcher.on('all', (_event, file) => {
|
|
64
|
+
if (typeof file === 'string' && !this.shouldRebuildForFile(file)) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
this.scheduleBuild();
|
|
68
|
+
});
|
|
69
|
+
this.watcher.on('error', (error) => {
|
|
70
|
+
this.logger?.error?.(error);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
scheduleBuild() {
|
|
74
|
+
if (this.timer) clearTimeout(this.timer);
|
|
75
|
+
this.timer = setTimeout(() => {
|
|
76
|
+
this.timer = null;
|
|
77
|
+
this.rebuild().catch((error) => {
|
|
78
|
+
this.logger?.error?.(error);
|
|
79
|
+
});
|
|
80
|
+
}, 80);
|
|
81
|
+
}
|
|
82
|
+
shouldRebuildForFile(file) {
|
|
83
|
+
if (path.basename(file) === aukletConfigFile) return true;
|
|
84
|
+
if (SOURCE_COMPONENT_MODULE_RE.test(file)) return true;
|
|
85
|
+
return this.config.styleExtensions.includes(path.extname(file));
|
|
86
|
+
}
|
|
87
|
+
async close() {
|
|
88
|
+
if (this.timer) clearTimeout(this.timer);
|
|
89
|
+
await this.watcher?.close();
|
|
90
|
+
}
|
|
91
|
+
}
|