auklet 0.0.9 → 0.0.11

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 CHANGED
@@ -53,6 +53,8 @@ import type { AukletConfig } from 'auklet';
53
53
  export const config: AukletConfig = {
54
54
  source: 'src',
55
55
  output: 'dist',
56
+ modules: true,
57
+ tsconfig: 'tsconfig.json',
56
58
  styles: {
57
59
  themes: {
58
60
  light: './src/themes/light.css',
@@ -72,13 +74,12 @@ export const config: AukletConfig = {
72
74
  },
73
75
  },
74
76
  },
75
- modules: true,
76
77
  build: {
77
- formats: ['esm', 'cjs'],
78
+ alias: { ... },
79
+ globals: { ... },
78
80
  target: 'es2020',
79
- globals: {
80
- react: 'React',
81
- },
81
+ formats: ['esm', 'cjs'],
82
+ mainFields: ['browser', 'module', 'main'],
82
83
  configureTsdown(config, context) {
83
84
  if (context.kind !== 'bundle') return config;
84
85
  return {
@@ -86,7 +87,6 @@ export const config: AukletConfig = {
86
87
  sourcemap: true,
87
88
  };
88
89
  },
89
- tsconfig: 'tsconfig.json',
90
90
  },
91
91
  };
92
92
  ```
@@ -108,6 +108,12 @@ Component style inference only scans source `.tsx` files. Component imports or
108
108
  re-exports in `.ts` files are ignored for CSS auto import, so component barrel
109
109
  files that should drive component CSS must be `.tsx`.
110
110
 
111
+ Same-package component style inference resolves relative imports,
112
+ `package.json#imports` mappings, and `tsconfig.json` `compilerOptions.paths`.
113
+ For `package.json#imports`, the `source` condition is preferred when present.
114
+ Only aliases that resolve into the current package source directory are treated
115
+ as same-package CSS dependencies.
116
+
111
117
  Supported value forms include named imports, named re-exports, and local
112
118
  re-exports that can be traced back to an import binding:
113
119
 
@@ -145,6 +151,8 @@ export const config: AukletConfig = {
145
151
  - `build.platform`: build target runtime platform: `neutral`, `node`, or `browser`. Defaults to `neutral`.
146
152
  - `build.banner`: custom bundle banner. Defaults to a package name/version banner.
147
153
  - `build.externals`: additional external packages. Defaults to `[]`.
154
+ - `build.alias`: path aliases passed to tsdown `alias`. Defaults to `{}`.
155
+ - `build.mainFields`: bundle package entry resolution order passed to rolldown `resolve.mainFields`. When omitted, auklet only sets `['browser', 'module', 'main']` for IIFE bundles.
148
156
  - `build.globals`: IIFE external global names passed to tsdown `output.globals`. Values override auklet's generated global names.
149
157
  - `build.configureTsdown`: final customization hook for each generated tsdown config. It receives `(config, context)` and should return a tsdown config.
150
158
  - `build.tsconfig`: TypeScript config path relative to the package root. Defaults to the nearest `tsconfig.json` found from the package root upward.
@@ -139,6 +139,8 @@ const createBuildContext = (packageRoot, options, output) => {
139
139
  runtimeDependencyNames: Object.keys(pkg.dependencies ?? {}),
140
140
  packageExternal: getPackageExternal(pkg, options),
141
141
  peerExternal: getPeerExternal(pkg, options),
142
+ alias: options.alias ?? {},
143
+ mainFields: options.mainFields,
142
144
  globals: options.globals ?? {},
143
145
  globalName: getGlobalName(pkg),
144
146
  platform: options.platform,
@@ -158,6 +160,7 @@ const createCommonConfig = (context, deps) => {
158
160
  tsconfig: context.tsconfig,
159
161
  target: context.target,
160
162
  platform: context.platform,
163
+ alias: context.alias,
161
164
  deps,
162
165
  define: {
163
166
  __TEST__: 'false',
@@ -167,6 +170,21 @@ const createCommonConfig = (context, deps) => {
167
170
  },
168
171
  };
169
172
  };
173
+ const createBundleInputOptions = (context, format) => {
174
+ const mainFields =
175
+ context.mainFields ??
176
+ (format === 'iife' ? ['browser', 'module', 'main'] : undefined);
177
+ return (options) => {
178
+ if (!mainFields) return options;
179
+ return {
180
+ ...options,
181
+ resolve: {
182
+ ...options.resolve,
183
+ mainFields,
184
+ },
185
+ };
186
+ };
187
+ };
170
188
  const configureTsdown = (context, config, options) => {
171
189
  return (
172
190
  context.configureTsdown?.(config, {
@@ -199,6 +217,10 @@ const createBundleConfigs = (context, formats) => {
199
217
  : {
200
218
  neverBundle: context.packageExternal,
201
219
  };
220
+ const inputOptions =
221
+ context.mainFields || format === 'iife'
222
+ ? createBundleInputOptions(context, format)
223
+ : undefined;
202
224
  return configureTsdown(
203
225
  context,
204
226
  {
@@ -218,6 +240,7 @@ const createBundleConfigs = (context, formats) => {
218
240
  chunkFileNames: `[name]-[hash]${extname}`,
219
241
  globals: format === 'iife' ? getIifeGlobals(context) : {},
220
242
  },
243
+ inputOptions,
221
244
  },
222
245
  { kind: 'bundle', format },
223
246
  );
package/dist/config.d.ts CHANGED
@@ -25,6 +25,8 @@ export declare function normalizeAukletConfig(config?: AukletConfig): {
25
25
  platform: import('#auklet/types').PackageBuildPlatform;
26
26
  banner?: string;
27
27
  externals?: Array<string>;
28
+ alias?: Record<string, string>;
29
+ mainFields?: Array<string>;
28
30
  globals?: Record<string, string>;
29
31
  configureTsdown?: import('#auklet/types').ConfigureTsdown;
30
32
  tsconfig?: string;
@@ -0,0 +1,5 @@
1
+ export declare function resolvePackageImportsSourceImport(
2
+ packageRoot: string,
3
+ sourceRoot: string,
4
+ importPath: string,
5
+ ): string[];
@@ -0,0 +1,53 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { findPathInImports } from 'conditional-export';
4
+ import { POSIX_SEPARATOR, toPosixPath } from '#auklet/utils';
5
+ const conditions = ['source', 'import', 'default'];
6
+ const sourceExtensions = /\.(?:[cm]?[jt]s|[jt]sx)$/;
7
+ const readPackageImports = (packageRoot) => {
8
+ const packageJsonPath = path.join(packageRoot, 'package.json');
9
+ if (!fs.existsSync(packageJsonPath)) return {};
10
+ try {
11
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
12
+ return packageJson.imports ?? {};
13
+ } catch {
14
+ return {};
15
+ }
16
+ };
17
+ const trimSourceExtension = (value) => {
18
+ return value.replace(sourceExtensions, '');
19
+ };
20
+ const toSourceRelativePath = (packageRoot, sourceRoot, target) => {
21
+ if (!target.startsWith('.')) return null;
22
+ const file = path.resolve(packageRoot, target);
23
+ const relative = path.relative(sourceRoot, file);
24
+ if (relative.startsWith('..') || path.isAbsolute(relative)) return null;
25
+ return trimSourceExtension(toPosixPath(relative));
26
+ };
27
+ export function resolvePackageImportsSourceImport(
28
+ packageRoot,
29
+ sourceRoot,
30
+ importPath,
31
+ ) {
32
+ if (!importPath.startsWith('#')) return [];
33
+ const resolved = (() => {
34
+ try {
35
+ return findPathInImports(
36
+ importPath,
37
+ readPackageImports(packageRoot),
38
+ conditions,
39
+ );
40
+ } catch {
41
+ return null;
42
+ }
43
+ })();
44
+ if (!resolved) return [];
45
+ const sourceRelativePath = toSourceRelativePath(
46
+ packageRoot,
47
+ sourceRoot,
48
+ resolved,
49
+ );
50
+ return sourceRelativePath
51
+ ? [sourceRelativePath.split(POSIX_SEPARATOR).join(path.sep)]
52
+ : [];
53
+ }
@@ -0,0 +1,4 @@
1
+ export declare function resolveRelativeSourceImport(
2
+ sourceDir: string,
3
+ importPath: string,
4
+ ): string[];
@@ -0,0 +1,5 @@
1
+ import path from 'node:path';
2
+ export function resolveRelativeSourceImport(sourceDir, importPath) {
3
+ if (!importPath.startsWith('.')) return [];
4
+ return [path.normalize(path.join(sourceDir, importPath))];
5
+ }
@@ -0,0 +1,5 @@
1
+ export declare function resolveTsconfigPathsSourceImport(
2
+ packageRoot: string,
3
+ sourceRoot: string,
4
+ importPath: string,
5
+ ): string[];
@@ -0,0 +1,85 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import ts from 'typescript';
4
+ import { POSIX_SEPARATOR, toPosixPath } from '#auklet/utils';
5
+ const sourceExtensions = /\.(?:[cm]?[jt]s|[jt]sx)$/;
6
+ const findTsconfig = (packageRoot) => {
7
+ let current = packageRoot;
8
+ while (true) {
9
+ const tsconfig = path.join(current, 'tsconfig.json');
10
+ if (fs.existsSync(tsconfig)) return tsconfig;
11
+ const parent = path.dirname(current);
12
+ if (parent === current) return null;
13
+ current = parent;
14
+ }
15
+ };
16
+ const readTsconfigPaths = (packageRoot) => {
17
+ const tsconfig = findTsconfig(packageRoot);
18
+ if (!tsconfig) return null;
19
+ const loaded = ts.readConfigFile(tsconfig, ts.sys.readFile);
20
+ if (loaded.error) return null;
21
+ const parsed = ts.parseJsonConfigFileContent(
22
+ loaded.config,
23
+ ts.sys,
24
+ path.dirname(tsconfig),
25
+ {},
26
+ tsconfig,
27
+ );
28
+ return {
29
+ baseUrl: parsed.options.baseUrl ?? path.dirname(tsconfig),
30
+ paths: parsed.options.paths ?? {},
31
+ };
32
+ };
33
+ const resolvePattern = (pattern, target, importPath) => {
34
+ const wildcardIndex = pattern.indexOf('*');
35
+ if (wildcardIndex < 0) return pattern === importPath ? target : null;
36
+ const prefix = pattern.slice(0, wildcardIndex);
37
+ const suffix = pattern.slice(wildcardIndex + 1);
38
+ if (!importPath.startsWith(prefix) || !importPath.endsWith(suffix)) {
39
+ return null;
40
+ }
41
+ const value = importPath.slice(
42
+ prefix.length,
43
+ importPath.length - suffix.length,
44
+ );
45
+ return target.replace(/\*/g, value);
46
+ };
47
+ const getPatternScore = (pattern) => {
48
+ const wildcardIndex = pattern.indexOf('*');
49
+ if (wildcardIndex < 0) return Number.MAX_SAFE_INTEGER;
50
+ return pattern.slice(0, wildcardIndex).length;
51
+ };
52
+ const trimSourceExtension = (value) => {
53
+ return value.replace(sourceExtensions, '');
54
+ };
55
+ const toSourceRelativePath = (sourceRoot, file) => {
56
+ const relative = path.relative(sourceRoot, file);
57
+ if (relative.startsWith('..') || path.isAbsolute(relative)) return null;
58
+ return trimSourceExtension(toPosixPath(relative));
59
+ };
60
+ export function resolveTsconfigPathsSourceImport(
61
+ packageRoot,
62
+ sourceRoot,
63
+ importPath,
64
+ ) {
65
+ const config = readTsconfigPaths(packageRoot);
66
+ if (!config) return [];
67
+ const matches = [];
68
+ for (const [pattern, targets] of Object.entries(config.paths)) {
69
+ for (const target of targets) {
70
+ const resolved = resolvePattern(pattern, target, importPath);
71
+ if (!resolved) continue;
72
+ const sourceRelativePath = toSourceRelativePath(
73
+ sourceRoot,
74
+ path.resolve(config.baseUrl, resolved),
75
+ );
76
+ if (sourceRelativePath) {
77
+ matches.push({
78
+ path: sourceRelativePath.split(POSIX_SEPARATOR).join(path.sep),
79
+ score: getPatternScore(pattern),
80
+ });
81
+ }
82
+ }
83
+ }
84
+ return matches.sort((a, b) => b.score - a.score).map((match) => match.path);
85
+ }
@@ -5,7 +5,6 @@ export declare class ModuleStyleImportCollector {
5
5
  private readonly packageRoot;
6
6
  private readonly resolver;
7
7
  private readonly styleExtensions;
8
- private readonly sourceImportAliasRules;
9
8
  constructor(
10
9
  srcRoot: string,
11
10
  packageRoot: string,
@@ -18,8 +17,9 @@ export declare class ModuleStyleImportCollector {
18
17
  ): Map<string, string[]>;
19
18
  private collectSourceImportStyle;
20
19
  private resolveSourceImportStyleEntry;
21
- private resolveSourceImportPath;
22
- private createSourceImportAliasRules;
20
+ private isInsideSourceRoot;
21
+ private resolveSourceImportPaths;
22
+ private toSourceBase;
23
23
  private toRelativeSpecifier;
24
24
  private createAutoImportRules;
25
25
  private matchAutoImportRules;
@@ -13,19 +13,22 @@ import {
13
13
  getSourceReferenceImportedNames,
14
14
  isTypeOnlySourceReference,
15
15
  } from '#auklet/css/core/styleImports/sourceReference';
16
+ import { resolveRelativeSourceImport } from '#auklet/css/core/resolvers/relative';
17
+ import { resolvePackageImportsSourceImport } from '#auklet/css/core/resolvers/packageImports';
18
+ import { resolveTsconfigPathsSourceImport } from '#auklet/css/core/resolvers/tsconfigPaths';
16
19
  const GLOBSTAR_TOKEN = '**';
20
+ const SOURCE_EXTENSION_RE = /\.(?:[cm]?[jt]s|[jt]sx)$/;
21
+ const SOURCE_INDEX_RE = new RegExp(`[/\\\\]index${SOURCE_EXTENSION_RE.source}`);
17
22
  export class ModuleStyleImportCollector {
18
23
  srcRoot;
19
24
  packageRoot;
20
25
  resolver;
21
26
  styleExtensions;
22
- sourceImportAliasRules;
23
27
  constructor(srcRoot, packageRoot, resolver, styleExtensions = ['.css']) {
24
28
  this.srcRoot = srcRoot;
25
29
  this.packageRoot = packageRoot;
26
30
  this.resolver = resolver;
27
31
  this.styleExtensions = styleExtensions;
28
- this.sourceImportAliasRules = this.createSourceImportAliasRules();
29
32
  }
30
33
  collect(files, config) {
31
34
  const entries = new Map();
@@ -100,51 +103,51 @@ export class ModuleStyleImportCollector {
100
103
  );
101
104
  }
102
105
  resolveSourceImportStyleEntry(sourceDir, importPath) {
103
- const sourceRelativePath = this.resolveSourceImportPath(
106
+ const sourceRelativePaths = this.resolveSourceImportPaths(
104
107
  sourceDir,
105
108
  importPath,
106
109
  );
107
- if (!sourceRelativePath) return null;
108
- const sourceBase = path.join(this.srcRoot, sourceRelativePath);
109
- const directoryStyleEntry = path.join(sourceBase, 'style', 'index.css');
110
- for (const extension of this.styleExtensions) {
111
- const directorySourceStyle = path.join(sourceBase, `index${extension}`);
112
- if (fs.existsSync(directorySourceStyle)) return directoryStyleEntry;
113
- }
114
- const hasFileSourceStyle = this.styleExtensions.some((extension) =>
115
- fs.existsSync(`${sourceBase}${extension}`),
116
- );
117
- if (!hasFileSourceStyle) return null;
118
- return path.join(sourceBase, 'style', 'index.css');
119
- }
120
- resolveSourceImportPath(sourceDir, importPath) {
121
- if (importPath.startsWith('.')) {
122
- return path.normalize(path.join(sourceDir, importPath));
123
- }
124
- for (const rule of this.sourceImportAliasRules) {
125
- if (!importPath.startsWith(rule.prefix)) continue;
126
- return importPath.slice(rule.prefix.length);
110
+ for (const sourceRelativePath of sourceRelativePaths) {
111
+ const sourceBase = this.toSourceBase(sourceRelativePath);
112
+ if (!this.isInsideSourceRoot(sourceBase)) continue;
113
+ const directoryStyleEntry = path.join(sourceBase, 'style', 'index.css');
114
+ for (const extension of this.styleExtensions) {
115
+ const directorySourceStyle = path.join(sourceBase, `index${extension}`);
116
+ if (fs.existsSync(directorySourceStyle)) return directoryStyleEntry;
117
+ }
118
+ const hasFileSourceStyle = this.styleExtensions.some((extension) =>
119
+ fs.existsSync(`${sourceBase}${extension}`),
120
+ );
121
+ if (hasFileSourceStyle)
122
+ return path.join(sourceBase, 'style', 'index.css');
127
123
  }
128
124
  return null;
129
125
  }
130
- createSourceImportAliasRules() {
131
- const packageJsonPath = path.join(this.packageRoot, 'package.json');
132
- if (!fs.existsSync(packageJsonPath)) return [];
133
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
134
- const rules = [];
135
- for (const [name, target] of Object.entries(packageJson.imports ?? {})) {
136
- if (
137
- !name.endsWith(`${POSIX_SEPARATOR}*`) ||
138
- typeof target !== 'string' ||
139
- !target.includes('*')
140
- ) {
141
- continue;
142
- }
143
- rules.push({
144
- prefix: name.slice(0, -1),
145
- });
126
+ isInsideSourceRoot(file) {
127
+ const relative = path.relative(this.srcRoot, file);
128
+ return !relative.startsWith('..') && !path.isAbsolute(relative);
129
+ }
130
+ resolveSourceImportPaths(sourceDir, importPath) {
131
+ return [
132
+ ...resolveRelativeSourceImport(sourceDir, importPath),
133
+ ...resolvePackageImportsSourceImport(
134
+ this.packageRoot,
135
+ this.srcRoot,
136
+ importPath,
137
+ ),
138
+ ...resolveTsconfigPathsSourceImport(
139
+ this.packageRoot,
140
+ this.srcRoot,
141
+ importPath,
142
+ ),
143
+ ];
144
+ }
145
+ toSourceBase(sourceRelativePath) {
146
+ const sourceBase = path.join(this.srcRoot, sourceRelativePath);
147
+ if (SOURCE_INDEX_RE.test(sourceBase)) {
148
+ return path.dirname(sourceBase);
146
149
  }
147
- return rules;
150
+ return sourceBase.replace(SOURCE_EXTENSION_RE, '');
148
151
  }
149
152
  toRelativeSpecifier(fromDir, file) {
150
153
  const relative = path.relative(fromDir, file).split(path.sep).join('/');
@@ -48,6 +48,8 @@ export declare class ModuleStyleGraphRequestCache {
48
48
  platform: import('#auklet/types').PackageBuildPlatform;
49
49
  banner?: string;
50
50
  externals?: Array<string>;
51
+ alias?: Record<string, string>;
52
+ mainFields?: Array<string>;
51
53
  globals?: Record<string, string>;
52
54
  configureTsdown?: import('#auklet/types').ConfigureTsdown;
53
55
  tsconfig?: string;
package/dist/types.d.ts CHANGED
@@ -43,6 +43,8 @@ export type PackageBuildOptions = {
43
43
  platform?: PackageBuildPlatform;
44
44
  banner?: string;
45
45
  externals?: Array<string>;
46
+ alias?: Record<string, string>;
47
+ mainFields?: Array<string>;
46
48
  globals?: Record<string, string>;
47
49
  configureTsdown?: ConfigureTsdown;
48
50
  tsconfig?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auklet",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "type": "module",
5
5
  "author": "chentao.arthur",
6
6
  "packageManager": "pnpm@10.27.0",
@@ -72,7 +72,7 @@
72
72
  "chokidar": "^5.0.0",
73
73
  "minimist": "^1.2.8",
74
74
  "typescript": "^6.0.3",
75
- "tailwindcss": "^4.2.4"
75
+ "conditional-export": "^1.1.0"
76
76
  },
77
77
  "devDependencies": {
78
78
  "@types/node": "^22.17.0",