auklet 0.0.6 → 0.0.8

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.
Files changed (29) hide show
  1. package/README.md +8 -3
  2. package/bin/entry.cjs +17 -10
  3. package/dist/build/cleanOutput.d.ts +9 -0
  4. package/dist/build/cleanOutput.js +15 -0
  5. package/dist/css/core/style/{plan.d.ts → entries.d.ts} +20 -4
  6. package/dist/css/core/style/{plan.js → entries.js} +19 -0
  7. package/dist/css/production/format/entryWriter.js +1 -1
  8. package/dist/css/production/format/externalWriter.js +1 -1
  9. package/dist/css/production/format/themeWriter.js +1 -1
  10. package/dist/css/production/moduleOutputWriter.js +2 -8
  11. package/dist/css/vite/hmr.d.ts +1 -1
  12. package/dist/css/vite/moduleGraph/devDependency.d.ts +13 -0
  13. package/dist/css/vite/moduleGraph/devDependency.js +12 -0
  14. package/dist/css/vite/moduleGraph/graph.d.ts +26 -0
  15. package/dist/css/vite/moduleGraph/graph.js +73 -0
  16. package/dist/css/vite/moduleGraph/loadResult.d.ts +7 -0
  17. package/dist/css/vite/moduleGraph/loadResult.js +12 -0
  18. package/dist/css/{core/moduleGraphRequestCache.d.ts → vite/moduleGraph/requestCache.d.ts} +4 -8
  19. package/dist/css/vite/moduleGraph/styleCodeFactory.d.ts +23 -0
  20. package/dist/css/{core/moduleGraph.js → vite/moduleGraph/styleCodeFactory.js} +42 -121
  21. package/dist/css/vite/moduleGraph/styleId.d.ts +7 -0
  22. package/dist/css/vite/moduleGraph/styleId.js +14 -0
  23. package/dist/css/vite/moduleGraph/types.d.ts +21 -0
  24. package/dist/css/vite/moduleGraph/types.js +0 -0
  25. package/dist/css/vite/vitePlugin.d.ts +1 -1
  26. package/dist/css/vite/vitePlugin.js +1 -1
  27. package/package.json +10 -1
  28. package/dist/css/core/moduleGraph.d.ts +0 -55
  29. /package/dist/css/{core/moduleGraphRequestCache.js → vite/moduleGraph/requestCache.js} +0 -0
package/README.md CHANGED
@@ -21,7 +21,6 @@ Build utilities for TypeScript packages and module CSS output.
21
21
  ## Requirements
22
22
 
23
23
  - Node.js `>=22`
24
- - pnpm `10.27.0`
25
24
 
26
25
  ## CLI
27
26
 
@@ -38,7 +37,7 @@ pnpm auk dev
38
37
 
39
38
  Commands:
40
39
 
41
- - `build` removes `dist`, builds JavaScript output, then builds CSS output.
40
+ - `build` removes the configured `output` directory, builds JavaScript output, then builds CSS output.
42
41
  - `build-js` runs tsdown with the default auklet tsdown config unless a config flag is passed.
43
42
  - `build-css` generates module CSS output.
44
43
  - `build-css --watch` watches source/config files and rebuilds CSS.
@@ -85,7 +84,7 @@ export const config: AukletConfig = {
85
84
  ### Style Options
86
85
 
87
86
  - `source`: source directory relative to the package root. Defaults to `src`.
88
- - `output`: build output directory relative to the package root. Defaults to `dist`.
87
+ - `output`: build output directory relative to the package root. Defaults to `dist`. `auk build` removes this directory before writing JavaScript and CSS output.
89
88
  - `styles.themes`: package theme style entries. Defaults to `{}`.
90
89
  - `styles.dependencies`: external package style dependencies. Defaults to `{}`.
91
90
 
@@ -204,6 +203,12 @@ import '@scope/app/components/Button.css';
204
203
  import '@scope/app/themes/light.css';
205
204
  ```
206
205
 
206
+ In dev mode, workspace package style dependencies keep using auklet virtual CSS
207
+ entries so changes can be tracked recursively. Third-party CSS dependencies are
208
+ resolved from the package that declares the dependency and emitted as Vite
209
+ `/@fs/...` imports, so packages such as `katex/dist/katex.min.css` do not need
210
+ to be installed by the consuming app.
211
+
207
212
  ## Programmatic API
208
213
 
209
214
  ```ts
package/bin/entry.cjs CHANGED
@@ -16,12 +16,18 @@ const runVersion = async () => {
16
16
  return 0;
17
17
  };
18
18
 
19
- const runBuildStyle = async (args) => {
20
- const shouldWatch = args.includes('--watch') || args.includes('-w');
19
+ const loadCurrentAukletConfig = async (options) => {
21
20
  const { loadAukletConfig } = await import('../dist/configLoader.js');
22
- const aukletConfig = await loadAukletConfig(process.cwd(), {
23
- cacheBust: shouldWatch,
24
- });
21
+ return loadAukletConfig(process.cwd(), options);
22
+ };
23
+
24
+ const runBuildStyle = async (args, options = {}) => {
25
+ const shouldWatch = args.includes('--watch') || args.includes('-w');
26
+ const aukletConfig =
27
+ options.aukletConfig ??
28
+ (await loadCurrentAukletConfig({
29
+ cacheBust: shouldWatch,
30
+ }));
25
31
 
26
32
  if (shouldWatch) {
27
33
  const { ModuleStyleWatcher } = await import('../dist/css/watch/watcher.js');
@@ -53,15 +59,16 @@ const runBuildJs = async (args) => {
53
59
  };
54
60
 
55
61
  const runBuild = async (args) => {
56
- fs.rmSync(path.join(process.cwd(), 'dist'), {
57
- recursive: true,
58
- force: true,
59
- });
62
+ const aukletConfig = await loadCurrentAukletConfig();
63
+ const { cleanAukletOutputByConfig } = await import(
64
+ '../dist/build/cleanOutput.js'
65
+ );
66
+ cleanAukletOutputByConfig(process.cwd(), aukletConfig);
60
67
 
61
68
  const jsExitCode = await runBuildJs(args);
62
69
  if (jsExitCode) return jsExitCode;
63
70
 
64
- return runBuildStyle([]);
71
+ return runBuildStyle([], { aukletConfig });
65
72
  };
66
73
 
67
74
  const runDev = async () => {
@@ -0,0 +1,9 @@
1
+ import type { AukletConfig, LoadAukletConfigOptions } from '#auklet/types';
2
+ export declare function cleanAukletOutputByConfig(
3
+ packageRoot: string,
4
+ config?: AukletConfig,
5
+ ): void;
6
+ export declare function cleanAukletOutput(
7
+ packageRoot: string,
8
+ options?: LoadAukletConfigOptions,
9
+ ): Promise<void>;
@@ -0,0 +1,15 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { normalizeAukletConfig } from '#auklet/config';
4
+ import { loadAukletConfig } from '#auklet/configLoader';
5
+ export function cleanAukletOutputByConfig(packageRoot, config = {}) {
6
+ const normalizedConfig = normalizeAukletConfig(config);
7
+ fs.rmSync(path.join(packageRoot, normalizedConfig.output), {
8
+ recursive: true,
9
+ force: true,
10
+ });
11
+ }
12
+ export async function cleanAukletOutput(packageRoot, options = {}) {
13
+ const rawConfig = await loadAukletConfig(packageRoot, options);
14
+ cleanAukletOutputByConfig(packageRoot, rawConfig);
15
+ }
@@ -1,3 +1,4 @@
1
+ import type { StylePackageContext } from '#auklet/css/core/stylePackageContext';
1
2
  import type { NormalizedAukletConfig } from '#auklet/types';
2
3
  type StyleModulePart = {
3
4
  type: 'module';
@@ -41,14 +42,11 @@ export declare function createThemeEntryParts(
41
42
  includeDependencies?: boolean;
42
43
  },
43
44
  ): (
45
+ | ThemePart
44
46
  | {
45
47
  type: 'dependencies';
46
48
  specifiers: string[];
47
49
  }
48
- | {
49
- type: 'theme';
50
- themeName: string;
51
- }
52
50
  )[];
53
51
  export declare function createExternalEntryParts(
54
52
  config: NormalizedAukletConfig,
@@ -56,4 +54,22 @@ export declare function createExternalEntryParts(
56
54
  type: 'dependencies';
57
55
  specifiers: string[];
58
56
  }[];
57
+ export declare function collectModuleStyleImports(
58
+ packageContext: StylePackageContext,
59
+ ): Map<string, string[]>;
60
+ export declare function createComponentStyleEntryPlan(
61
+ packageContext: StylePackageContext,
62
+ sourceDir: string,
63
+ ): {
64
+ sourceDir: string;
65
+ moduleStyleImports: string[];
66
+ ownStyleFiles: string[];
67
+ };
68
+ export declare function createComponentStyleEntryPlans(
69
+ packageContext: StylePackageContext,
70
+ ): {
71
+ sourceDir: string;
72
+ moduleStyleImports: string[];
73
+ ownStyleFiles: string[];
74
+ }[];
59
75
  export {};
@@ -4,7 +4,9 @@ import {
4
4
  getThemeNames,
5
5
  getThemeStyleDependencies,
6
6
  } from '#auklet/css/core/style/dependencies';
7
+ import { StyleModuleEntryPlanner } from '#auklet/css/core/styleModuleEntryPlanner';
7
8
  const dependenciesPart = (specifiers) => ({ type: 'dependencies', specifiers });
9
+ // 环境无关的 style entry graph。production writer 和 Vite/dev renderer 都从这里取入口语义。
8
10
  export function createStyleEntryParts(config) {
9
11
  return [
10
12
  dependenciesPart(getGlobalStyleDependencies(config)),
@@ -25,3 +27,20 @@ export function createThemeEntryParts(config, themeName, options = {}) {
25
27
  export function createExternalEntryParts(config) {
26
28
  return [dependenciesPart(getExternalStyleDependencies(config))];
27
29
  }
30
+ export function collectModuleStyleImports(packageContext) {
31
+ return packageContext.importCollector.collect(
32
+ packageContext.sourceFiles,
33
+ packageContext.normalizedConfig,
34
+ );
35
+ }
36
+ export function createComponentStyleEntryPlan(packageContext, sourceDir) {
37
+ return new StyleModuleEntryPlanner(packageContext).createEntry(
38
+ sourceDir,
39
+ collectModuleStyleImports(packageContext),
40
+ );
41
+ }
42
+ export function createComponentStyleEntryPlans(packageContext) {
43
+ return new StyleModuleEntryPlanner(packageContext).createEntries(
44
+ collectModuleStyleImports(packageContext),
45
+ );
46
+ }
@@ -1,6 +1,6 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { createStyleEntryParts } from '#auklet/css/core/style/plan';
3
+ import { createStyleEntryParts } from '#auklet/css/core/style/entries';
4
4
  import { toRelativeImportSpecifier } from '#auklet/css/production/format/shared';
5
5
  export class StyleEntryWriter {
6
6
  config;
@@ -1,6 +1,6 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { createExternalEntryParts } from '#auklet/css/core/style/plan';
3
+ import { createExternalEntryParts } from '#auklet/css/core/style/entries';
4
4
  export class ExternalStyleWriter {
5
5
  config;
6
6
  packageContext;
@@ -1,7 +1,7 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { THEMES_DIR } from '#auklet/css/constants';
4
- import { createThemeEntryParts } from '#auklet/css/core/style/plan';
4
+ import { createThemeEntryParts } from '#auklet/css/core/style/entries';
5
5
  import { toRelativeImportSpecifier } from '#auklet/css/production/format/shared';
6
6
  export class ThemeStyleWriter {
7
7
  config;
@@ -1,5 +1,5 @@
1
1
  import path from 'node:path';
2
- import { StyleModuleEntryPlanner } from '#auklet/css/core/styleModuleEntryPlanner';
2
+ import { createComponentStyleEntryPlans } from '#auklet/css/core/style/entries';
3
3
  import { ComponentStyleEntryWriter } from '#auklet/css/production/format/componentWriter';
4
4
  import { StyleEntryWriter } from '#auklet/css/production/format/entryWriter';
5
5
  import { ExternalStyleWriter } from '#auklet/css/production/format/externalWriter';
@@ -40,13 +40,7 @@ export class ModuleStyleOutputWriter {
40
40
  return path.join(this.context.packageRoot, this.context.outputDir);
41
41
  }
42
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
- );
43
+ return createComponentStyleEntryPlans(this.packageContext);
50
44
  }
51
45
  writeFormat(format, componentEntries) {
52
46
  const outRoot = path.join(this.outputRoot, format);
@@ -1,5 +1,5 @@
1
1
  import type { HotUpdateOptions, ViteDevServer } from 'vite';
2
- import type { ModuleStyleGraph } from '#auklet/css/core/moduleGraph';
2
+ import type { ModuleStyleGraph } from '#auklet/css/vite/moduleGraph/graph';
3
3
  export declare class AukletStyleHmr {
4
4
  private readonly graph;
5
5
  private readonly lastUpdateTimes;
@@ -0,0 +1,13 @@
1
+ import type { PackageStyleContext } from '#auklet/css/vite/moduleGraph/requestCache';
2
+ export declare function toDevDependencyImportSpecifier(
3
+ context: PackageStyleContext,
4
+ specifier: string,
5
+ ):
6
+ | {
7
+ specifier: string;
8
+ watchFile?: undefined;
9
+ }
10
+ | {
11
+ specifier: string;
12
+ watchFile: string;
13
+ };
@@ -0,0 +1,12 @@
1
+ import { toFsSpecifier } from '#auklet/utils';
2
+ // 在 Vite 虚拟 CSS 中,第三方 CSS 依赖要用声明它的包作为解析根。
3
+ export function toDevDependencyImportSpecifier(context, specifier) {
4
+ if (specifier.startsWith('.') || specifier.startsWith('/')) {
5
+ return { specifier };
6
+ }
7
+ const resolved = context.resolver.resolveStyleDependency(specifier);
8
+ return {
9
+ specifier: toFsSpecifier(resolved),
10
+ watchFile: resolved,
11
+ };
12
+ }
@@ -0,0 +1,26 @@
1
+ import type {
2
+ ModuleStyleGraphOptions,
3
+ PackageStyleId,
4
+ } from '#auklet/css/vite/moduleGraph/types';
5
+ export declare class ModuleStyleGraph {
6
+ private readonly config;
7
+ private readonly workspaceRoot;
8
+ private readonly packagesDir;
9
+ private readonly styleCodeFactory;
10
+ private readonly loadAukletConfig;
11
+ constructor(options: ModuleStyleGraphOptions);
12
+ parsePackageStyleId(id: string): {
13
+ packageName: string;
14
+ stylePath: string;
15
+ } | null;
16
+ isWorkspaceSourceGraphFile(file: string): boolean;
17
+ isStyleConfigFile(file: string): boolean;
18
+ isStyleFile(file: string): boolean;
19
+ getWorkspacePackageNames(): string[];
20
+ getWatchRoots(): string[];
21
+ createPackageStyleCode(parsed: PackageStyleId): Promise<{
22
+ code: string;
23
+ watchFiles: string[];
24
+ }>;
25
+ private createRequestCache;
26
+ }
@@ -0,0 +1,73 @@
1
+ import path from 'node:path';
2
+ import { aukletConfigFile } from '#auklet/config';
3
+ import { loadAukletConfig } from '#auklet/configLoader';
4
+ import { moduleStyleBuildConfig } from '#auklet/css/config';
5
+ import { ModuleStyleGraphRequestCache } from '#auklet/css/vite/moduleGraph/requestCache';
6
+ import { StyleCodeFactory } from '#auklet/css/vite/moduleGraph/styleCodeFactory';
7
+ import { parsePackageStyleId } from '#auklet/css/vite/moduleGraph/styleId';
8
+ import { SOURCE_COMPONENT_MODULE_RE } from '#auklet/css/constants';
9
+ import { normalizeFileKey, toWatchPath } from '#auklet/utils';
10
+ // package style graph 的对外门面,负责 workspace 发现、watch 边界和请求分发。
11
+ export class ModuleStyleGraph {
12
+ config;
13
+ workspaceRoot;
14
+ packagesDir;
15
+ styleCodeFactory;
16
+ loadAukletConfig;
17
+ constructor(options) {
18
+ this.config = options.config ?? moduleStyleBuildConfig;
19
+ this.workspaceRoot = normalizeFileKey(options.workspaceRoot);
20
+ this.packagesDir = options.packagesDir ?? 'packages';
21
+ this.loadAukletConfig = options.loadAukletConfig ?? loadAukletConfig;
22
+ this.styleCodeFactory = new StyleCodeFactory(this.config);
23
+ }
24
+ parsePackageStyleId(id) {
25
+ return parsePackageStyleId(id, this.getWorkspacePackageNames());
26
+ }
27
+ isWorkspaceSourceGraphFile(file) {
28
+ const normalizedFile = normalizeFileKey(file);
29
+ const packagesRoot = normalizeFileKey(
30
+ path.join(this.workspaceRoot, this.packagesDir),
31
+ );
32
+ if (!normalizedFile.startsWith(`${packagesRoot}/`)) {
33
+ return false;
34
+ }
35
+ if (normalizedFile.endsWith(aukletConfigFile)) return true;
36
+ if (SOURCE_COMPONENT_MODULE_RE.test(normalizedFile)) {
37
+ return true;
38
+ }
39
+ return this.config.styleExtensions.some((extension) =>
40
+ normalizedFile.endsWith(extension),
41
+ );
42
+ }
43
+ isStyleConfigFile(file) {
44
+ return normalizeFileKey(file).endsWith(aukletConfigFile);
45
+ }
46
+ isStyleFile(file) {
47
+ return this.config.styleExtensions.includes(path.extname(file));
48
+ }
49
+ getWorkspacePackageNames() {
50
+ return this.createRequestCache().getWorkspacePackageNames();
51
+ }
52
+ getWatchRoots() {
53
+ const packagesRoot = path.join(this.workspaceRoot, this.packagesDir);
54
+ return [
55
+ toWatchPath(packagesRoot, '*', 'src'),
56
+ toWatchPath(packagesRoot, '*', aukletConfigFile),
57
+ ];
58
+ }
59
+ createPackageStyleCode(parsed) {
60
+ return this.styleCodeFactory.createPackageStyleCode(
61
+ parsed,
62
+ this.createRequestCache(),
63
+ );
64
+ }
65
+ createRequestCache() {
66
+ return new ModuleStyleGraphRequestCache({
67
+ workspaceRoot: this.workspaceRoot,
68
+ packagesDir: this.packagesDir,
69
+ config: this.config,
70
+ loadAukletConfig: this.loadAukletConfig,
71
+ });
72
+ }
73
+ }
@@ -0,0 +1,7 @@
1
+ import type { PackageStyleLoadResult } from '#auklet/css/vite/moduleGraph/types';
2
+ export declare function mergeLoadResults(
3
+ ...results: Array<PackageStyleLoadResult>
4
+ ): {
5
+ code: string;
6
+ watchFiles: string[];
7
+ };
@@ -0,0 +1,12 @@
1
+ // 合并递归 style graph 加载结果,同时保留 CSS 顺序并去重 watch files。
2
+ export function mergeLoadResults(...results) {
3
+ return {
4
+ code: results
5
+ .map((result) => result.code)
6
+ .filter((code) => code.trim())
7
+ .join('\n'),
8
+ watchFiles: Array.from(
9
+ new Set(results.flatMap((result) => result.watchFiles)),
10
+ ),
11
+ };
12
+ }
@@ -1,13 +1,15 @@
1
1
  import { StylePackageContext } from '#auklet/css/core/stylePackageContext';
2
2
  import type {
3
- AukletConfig,
4
3
  ModuleStyleBuildConfig,
5
4
  NormalizedAukletConfig,
6
5
  ResolvedModuleStyleBuildContext,
7
6
  } from '#auklet/types';
8
7
  import type { StyleProcessor } from '#auklet/css/core/styleProcessor';
9
8
  import type { WorkspaceStyleResolver } from '#auklet/css/core/workspaceStyleResolver';
10
- import type { PackageStyleId } from '#auklet/css/core/moduleGraph';
9
+ import type {
10
+ LoadAukletConfig,
11
+ PackageStyleId,
12
+ } from '#auklet/css/vite/moduleGraph/types';
11
13
  export type PackageStyleContext = {
12
14
  normalizedConfig: NormalizedAukletConfig;
13
15
  context: ResolvedModuleStyleBuildContext;
@@ -18,12 +20,6 @@ export type PackageStyleContext = {
18
20
  sourceRoot: string;
19
21
  styleProcessor: StyleProcessor;
20
22
  };
21
- export type LoadAukletConfig = (
22
- packageRoot: string,
23
- options?: {
24
- cacheBust?: boolean;
25
- },
26
- ) => Promise<AukletConfig>;
27
23
  export type ModuleStyleGraphRequestCacheOptions = {
28
24
  workspaceRoot: string;
29
25
  packagesDir: string;
@@ -0,0 +1,23 @@
1
+ import type { ModuleStyleBuildConfig } from '#auklet/types';
2
+ import type { ModuleStyleGraphRequestCache } from '#auklet/css/vite/moduleGraph/requestCache';
3
+ import type { PackageStyleId } from '#auklet/css/vite/moduleGraph/types';
4
+ export declare class StyleCodeFactory {
5
+ private readonly config;
6
+ constructor(config: ModuleStyleBuildConfig);
7
+ createPackageStyleCode(
8
+ parsed: PackageStyleId,
9
+ cache: ModuleStyleGraphRequestCache,
10
+ ): Promise<{
11
+ code: string;
12
+ watchFiles: string[];
13
+ }>;
14
+ private createStyleCode;
15
+ private createDependencyStyleCode;
16
+ private createExternalStyleCode;
17
+ private createThemeStyleCode;
18
+ private createModuleStyleCode;
19
+ private createSourceModuleStyleCode;
20
+ private toDevModuleImportSpecifier;
21
+ private toDevExternalStyleSpecifier;
22
+ private parsePackageStyleIdInRequest;
23
+ }
@@ -1,96 +1,32 @@
1
1
  import path from 'node:path';
2
- import { aukletConfigFile } from '#auklet/config';
3
- import { loadAukletConfig } from '#auklet/configLoader';
4
- import { moduleStyleBuildConfig } from '#auklet/css/config';
5
- import { ModuleStyleGraphRequestCache } from '#auklet/css/core/moduleGraphRequestCache';
6
- import { StyleModuleEntryPlanner } from '#auklet/css/core/styleModuleEntryPlanner';
2
+ import { mergeLoadResults } from '#auklet/css/vite/moduleGraph/loadResult';
3
+ import { parsePackageStyleId } from '#auklet/css/vite/moduleGraph/styleId';
4
+ import { toDevDependencyImportSpecifier } from '#auklet/css/vite/moduleGraph/devDependency';
7
5
  import {
8
6
  EXTERNAL_ENTRY,
9
7
  MODULE_ENTRY,
10
- SOURCE_COMPONENT_MODULE_RE,
11
8
  STYLE_ENTRY,
12
9
  THEMES_ENTRY_PREFIX,
13
10
  } from '#auklet/css/constants';
14
11
  import {
12
+ createComponentStyleEntryPlan,
15
13
  createExternalEntryParts,
16
14
  createStyleEntryParts,
17
15
  createThemeEntryParts,
18
- } from '#auklet/css/core/style/plan';
16
+ } from '#auklet/css/core/style/entries';
19
17
  import {
20
18
  createImportCode,
21
19
  parsePackageStyleSpecifier,
22
20
  removeStyleExtension,
23
21
  } from '#auklet/css/core/style/specifier';
24
- import {
25
- normalizeFileKey,
26
- toFsSpecifier,
27
- toPosixPath,
28
- toWatchPath,
29
- } from '#auklet/utils';
30
- const mergeLoadResults = (...results) => {
31
- return {
32
- code: results
33
- .map((result) => result.code)
34
- .filter((code) => code.trim())
35
- .join('\n'),
36
- watchFiles: Array.from(
37
- new Set(results.flatMap((result) => result.watchFiles)),
38
- ),
39
- };
40
- };
41
- export class ModuleStyleGraph {
22
+ import { toFsSpecifier, toPosixPath } from '#auklet/utils';
23
+ // 生成 Vite/dev 虚拟 CSS;production writer 共享入口语义,但写入真实文件。
24
+ export class StyleCodeFactory {
42
25
  config;
43
- workspaceRoot;
44
- packagesDir;
45
- loadAukletConfig;
46
- constructor(options) {
47
- this.config = options.config ?? moduleStyleBuildConfig;
48
- this.workspaceRoot = normalizeFileKey(options.workspaceRoot);
49
- this.packagesDir = options.packagesDir ?? 'packages';
50
- this.loadAukletConfig = options.loadAukletConfig ?? loadAukletConfig;
51
- }
52
- parsePackageStyleId(id) {
53
- return parsePackageStyleId(id, this.getWorkspacePackageNames());
54
- }
55
- isWorkspaceSourceGraphFile(file) {
56
- const normalizedFile = normalizeFileKey(file);
57
- const packagesRoot = normalizeFileKey(
58
- path.join(this.workspaceRoot, this.packagesDir),
59
- );
60
- if (!normalizedFile.startsWith(`${packagesRoot}/`)) {
61
- return false;
62
- }
63
- if (normalizedFile.endsWith(aukletConfigFile)) return true;
64
- if (SOURCE_COMPONENT_MODULE_RE.test(normalizedFile)) {
65
- return true;
66
- }
67
- return this.config.styleExtensions.some((extension) =>
68
- normalizedFile.endsWith(extension),
69
- );
70
- }
71
- isStyleConfigFile(file) {
72
- return normalizeFileKey(file).endsWith(aukletConfigFile);
73
- }
74
- isStyleFile(file) {
75
- return this.config.styleExtensions.includes(path.extname(file));
26
+ constructor(config) {
27
+ this.config = config;
76
28
  }
77
- getWorkspacePackageNames() {
78
- return this.createRequestCache().getWorkspacePackageNames();
79
- }
80
- getWatchRoots() {
81
- const packagesRoot = path.join(this.workspaceRoot, this.packagesDir);
82
- return [
83
- toWatchPath(packagesRoot, '*', 'src'),
84
- toWatchPath(packagesRoot, '*', aukletConfigFile),
85
- ];
86
- }
87
- async createPackageStyleCode(parsed) {
88
- return this.createPackageStyleCodeWithCache(
89
- parsed,
90
- this.createRequestCache(),
91
- );
92
- }
93
- async createPackageStyleCodeWithCache(parsed, cache) {
29
+ async createPackageStyleCode(parsed, cache) {
94
30
  const context = await cache.getContext(parsed);
95
31
  if (!context) {
96
32
  return {
@@ -148,19 +84,27 @@ export class ModuleStyleGraph {
148
84
  ) {
149
85
  const results = [];
150
86
  const imports = [];
87
+ const watchFiles = [context.configPath];
151
88
  for (const specifier of specifiers) {
152
89
  const outputSpecifier = mapSpecifier(specifier);
153
90
  const parsed = this.parsePackageStyleIdInRequest(outputSpecifier, cache);
154
91
  if (parsed) {
155
- results.push(await this.createPackageStyleCodeWithCache(parsed, cache));
92
+ results.push(await this.createPackageStyleCode(parsed, cache));
156
93
  continue;
157
94
  }
158
- imports.push(outputSpecifier);
95
+ const resolvedSpecifier = toDevDependencyImportSpecifier(
96
+ context,
97
+ outputSpecifier,
98
+ );
99
+ imports.push(resolvedSpecifier.specifier);
100
+ if (resolvedSpecifier.watchFile) {
101
+ watchFiles.push(resolvedSpecifier.watchFile);
102
+ }
159
103
  }
160
104
  return mergeLoadResults(
161
105
  {
162
106
  code: createImportCode(imports),
163
- watchFiles: [context.configPath],
107
+ watchFiles,
164
108
  },
165
109
  ...results,
166
110
  );
@@ -168,16 +112,14 @@ export class ModuleStyleGraph {
168
112
  async createExternalStyleCode(context, cache) {
169
113
  const results = [];
170
114
  for (const part of createExternalEntryParts(context.normalizedConfig)) {
171
- if (part.type === 'dependencies') {
172
- results.push(
173
- await this.createDependencyStyleCode(
174
- context,
175
- cache,
176
- part.specifiers,
177
- (specifier) => this.toDevExternalStyleSpecifier(specifier, cache),
178
- ),
179
- );
180
- }
115
+ results.push(
116
+ await this.createDependencyStyleCode(
117
+ context,
118
+ cache,
119
+ part.specifiers,
120
+ (specifier) => this.toDevExternalStyleSpecifier(specifier, cache),
121
+ ),
122
+ );
181
123
  }
182
124
  return mergeLoadResults(...results);
183
125
  }
@@ -248,13 +190,10 @@ export class ModuleStyleGraph {
248
190
  async createSourceModuleStyleCode(context, cache, stylePath) {
249
191
  const sourceModuleDir = removeStyleExtension(stylePath);
250
192
  const { styleFiles, sourceFiles } = context.packageContext;
251
- const moduleStyleImports = context.packageContext.importCollector.collect(
252
- sourceFiles,
253
- context.normalizedConfig,
254
- );
255
- const entry = new StyleModuleEntryPlanner(
193
+ const entry = createComponentStyleEntryPlan(
256
194
  context.packageContext,
257
- ).createEntry(sourceModuleDir, moduleStyleImports);
195
+ sourceModuleDir,
196
+ );
258
197
  const sourceStyleDir = path.join(
259
198
  context.sourceRoot,
260
199
  sourceModuleDir,
@@ -262,6 +201,7 @@ export class ModuleStyleGraph {
262
201
  );
263
202
  const moduleStyleResults = [];
264
203
  const moduleStyleSpecifiers = [];
204
+ const moduleStyleWatchFiles = [];
265
205
  for (const specifier of entry.moduleStyleImports) {
266
206
  const result = this.toDevModuleImportSpecifier(
267
207
  context,
@@ -272,11 +212,15 @@ export class ModuleStyleGraph {
272
212
  const parsed = this.parsePackageStyleIdInRequest(result, cache);
273
213
  if (parsed) {
274
214
  moduleStyleResults.push(
275
- await this.createPackageStyleCodeWithCache(parsed, cache),
215
+ await this.createPackageStyleCode(parsed, cache),
276
216
  );
277
217
  continue;
278
218
  }
279
- moduleStyleSpecifiers.push(result);
219
+ const resolvedSpecifier = toDevDependencyImportSpecifier(context, result);
220
+ moduleStyleSpecifiers.push(resolvedSpecifier.specifier);
221
+ if (resolvedSpecifier.watchFile) {
222
+ moduleStyleWatchFiles.push(resolvedSpecifier.watchFile);
223
+ }
280
224
  }
281
225
  const root = context.styleProcessor.createRoot();
282
226
  const seen = new Set();
@@ -296,6 +240,7 @@ export class ModuleStyleGraph {
296
240
  watchFiles: [
297
241
  context.configPath,
298
242
  ...styleFiles,
243
+ ...moduleStyleWatchFiles,
299
244
  ...sourceFiles.filter((file) => /\.(ts|tsx)$/.test(file)),
300
245
  ],
301
246
  });
@@ -318,7 +263,7 @@ export class ModuleStyleGraph {
318
263
  toDevExternalStyleSpecifier(specifier, cache) {
319
264
  const parsed = parsePackageStyleSpecifier(specifier);
320
265
  if (!parsed) return specifier;
321
- if (this.isWorkspacePackageName(parsed.packageName, cache)) {
266
+ if (cache.isWorkspacePackageName(parsed.packageName)) {
322
267
  if (parsed.stylePath === STYLE_ENTRY) {
323
268
  return `${parsed.packageName}/${EXTERNAL_ENTRY}`;
324
269
  }
@@ -336,28 +281,4 @@ export class ModuleStyleGraph {
336
281
  parsePackageStyleIdInRequest(id, cache) {
337
282
  return parsePackageStyleId(id, cache.getWorkspacePackageNames());
338
283
  }
339
- isWorkspacePackageName(packageName, cache) {
340
- return cache.isWorkspacePackageName(packageName);
341
- }
342
- createRequestCache() {
343
- return new ModuleStyleGraphRequestCache({
344
- workspaceRoot: this.workspaceRoot,
345
- packagesDir: this.packagesDir,
346
- config: this.config,
347
- loadAukletConfig: this.loadAukletConfig,
348
- });
349
- }
350
- }
351
- export function parsePackageStyleId(id, packageNames) {
352
- if (!id.endsWith('.css')) {
353
- return null;
354
- }
355
- const packageName = [...packageNames]
356
- .sort((left, right) => right.length - left.length)
357
- .find((name) => id.startsWith(`${name}/`));
358
- if (!packageName) return null;
359
- return {
360
- packageName,
361
- stylePath: id.slice(packageName.length + 1),
362
- };
363
284
  }
@@ -0,0 +1,7 @@
1
+ export declare function parsePackageStyleId(
2
+ id: string,
3
+ packageNames: Array<string>,
4
+ ): {
5
+ packageName: string;
6
+ stylePath: string;
7
+ } | null;
@@ -0,0 +1,14 @@
1
+ // 根据已知 workspace 包名解析 package CSS id,并优先匹配最长包名。
2
+ export function parsePackageStyleId(id, packageNames) {
3
+ if (!id.endsWith('.css')) {
4
+ return null;
5
+ }
6
+ const packageName = [...packageNames]
7
+ .sort((left, right) => right.length - left.length)
8
+ .find((name) => id.startsWith(`${name}/`));
9
+ if (!packageName) return null;
10
+ return {
11
+ packageName,
12
+ stylePath: id.slice(packageName.length + 1),
13
+ };
14
+ }
@@ -0,0 +1,21 @@
1
+ import type { AukletConfig, ModuleStyleBuildConfig } from '#auklet/types';
2
+ export interface ModuleStyleGraphOptions {
3
+ workspaceRoot: string;
4
+ packagesDir?: string;
5
+ config?: ModuleStyleBuildConfig;
6
+ loadAukletConfig?: LoadAukletConfig;
7
+ }
8
+ export type PackageStyleId = {
9
+ packageName: string;
10
+ stylePath: string;
11
+ };
12
+ export type PackageStyleLoadResult = {
13
+ code: string;
14
+ watchFiles: Array<string>;
15
+ };
16
+ export type LoadAukletConfig = (
17
+ packageRoot: string,
18
+ options?: {
19
+ cacheBust?: boolean;
20
+ },
21
+ ) => Promise<AukletConfig>;
File without changes
@@ -1,5 +1,5 @@
1
1
  import type { HotUpdateOptions, ViteDevServer } from 'vite';
2
- import { type ModuleStyleGraphOptions } from '#auklet/css/core/moduleGraph';
2
+ import type { ModuleStyleGraphOptions } from '#auklet/css/vite/moduleGraph/types';
3
3
  export type AukletStylePluginOptions = Partial<
4
4
  Pick<ModuleStyleGraphOptions, 'workspaceRoot'>
5
5
  > &
@@ -1,6 +1,6 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { ModuleStyleGraph } from '#auklet/css/core/moduleGraph';
3
+ import { ModuleStyleGraph } from '#auklet/css/vite/moduleGraph/graph';
4
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:';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auklet",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "type": "module",
5
5
  "author": "chentao.arthur",
6
6
  "packageManager": "pnpm@10.27.0",
@@ -53,6 +53,15 @@
53
53
  "dist",
54
54
  "!dist/__tests__"
55
55
  ],
56
+ "keywords": [
57
+ "build",
58
+ "typescript",
59
+ "css",
60
+ "vite",
61
+ "components",
62
+ "monorepo",
63
+ "tsdown"
64
+ ],
56
65
  "dependencies": {
57
66
  "unrun": "^0.3.0",
58
67
  "execa": "^9.1.0",
@@ -1,55 +0,0 @@
1
- import { type LoadAukletConfig } from '#auklet/css/core/moduleGraphRequestCache';
2
- import type { ModuleStyleBuildConfig } from '#auklet/types';
3
- export interface ModuleStyleGraphOptions {
4
- workspaceRoot: string;
5
- packagesDir?: string;
6
- config?: ModuleStyleBuildConfig;
7
- loadAukletConfig?: LoadAukletConfig;
8
- }
9
- export type PackageStyleId = {
10
- packageName: string;
11
- stylePath: string;
12
- };
13
- export type PackageStyleLoadResult = {
14
- code: string;
15
- watchFiles: Array<string>;
16
- };
17
- export declare class ModuleStyleGraph {
18
- private readonly config;
19
- private readonly workspaceRoot;
20
- private readonly packagesDir;
21
- private readonly loadAukletConfig;
22
- constructor(options: ModuleStyleGraphOptions);
23
- parsePackageStyleId(id: string): {
24
- packageName: string;
25
- stylePath: string;
26
- } | null;
27
- isWorkspaceSourceGraphFile(file: string): boolean;
28
- isStyleConfigFile(file: string): boolean;
29
- isStyleFile(file: string): boolean;
30
- getWorkspacePackageNames(): string[];
31
- getWatchRoots(): string[];
32
- createPackageStyleCode(parsed: PackageStyleId): Promise<{
33
- code: string;
34
- watchFiles: string[];
35
- }>;
36
- private createPackageStyleCodeWithCache;
37
- private createStyleCode;
38
- private createDependencyStyleCode;
39
- private createExternalStyleCode;
40
- private createThemeStyleCode;
41
- private createModuleStyleCode;
42
- private createSourceModuleStyleCode;
43
- private toDevModuleImportSpecifier;
44
- private toDevExternalStyleSpecifier;
45
- private parsePackageStyleIdInRequest;
46
- private isWorkspacePackageName;
47
- private createRequestCache;
48
- }
49
- export declare function parsePackageStyleId(
50
- id: string,
51
- packageNames: Array<string>,
52
- ): {
53
- packageName: string;
54
- stylePath: string;
55
- } | null;