auklet 0.0.11 → 0.0.13

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 (31) hide show
  1. package/dist/build/bundleConfig.d.ts +6 -0
  2. package/dist/build/bundleConfig.js +80 -0
  3. package/dist/build/moduleConfig.d.ts +5 -0
  4. package/dist/build/moduleConfig.js +46 -0
  5. package/dist/build/tsdown/common.d.ts +30 -0
  6. package/dist/build/tsdown/common.js +29 -0
  7. package/dist/build/tsdown/context.d.ts +23 -0
  8. package/dist/build/tsdown/context.js +53 -0
  9. package/dist/build/tsdown/define.d.ts +9 -0
  10. package/dist/build/tsdown/define.js +29 -0
  11. package/dist/build/tsdown/dependencies.d.ts +16 -0
  12. package/dist/build/tsdown/dependencies.js +65 -0
  13. package/dist/build/tsdown/entries.d.ts +8 -0
  14. package/dist/build/tsdown/entries.js +48 -0
  15. package/dist/build/tsdown/types.d.ts +38 -0
  16. package/dist/build/tsdown/types.js +0 -0
  17. package/dist/build/tsdownConfig.d.ts +6 -11
  18. package/dist/build/tsdownConfig.js +5 -312
  19. package/dist/css/production/format/componentWriter.js +3 -7
  20. package/dist/css/production/format/entryWriter.js +5 -4
  21. package/dist/css/production/format/externalWriter.d.ts +1 -1
  22. package/dist/css/production/format/externalWriter.js +2 -3
  23. package/dist/css/production/format/moduleWriter.d.ts +1 -1
  24. package/dist/css/production/format/moduleWriter.js +2 -3
  25. package/dist/css/production/format/shared.d.ts +3 -2
  26. package/dist/css/production/format/shared.js +7 -2
  27. package/dist/css/production/format/sourceWriter.d.ts +1 -1
  28. package/dist/css/production/format/sourceWriter.js +2 -2
  29. package/dist/css/production/format/themeWriter.js +6 -5
  30. package/dist/css/production/packageEntryWriter.js +2 -3
  31. package/package.json +1 -1
@@ -0,0 +1,6 @@
1
+ import type { UserConfig } from 'tsdown/config';
2
+ import type { BuildContext, TsdownFormat } from '#auklet/build/tsdown/types';
3
+ export declare function createBundleConfigs(
4
+ context: BuildContext,
5
+ formats: Array<TsdownFormat>,
6
+ ): UserConfig[];
@@ -0,0 +1,80 @@
1
+ import { getBundleEntry } from '#auklet/build/tsdown/entries';
2
+ import {
3
+ getIifeAlwaysBundle,
4
+ getIifeGlobals,
5
+ } from '#auklet/build/tsdown/dependencies';
6
+ import {
7
+ configureTsdown,
8
+ createCommonConfig,
9
+ } from '#auklet/build/tsdown/common';
10
+ const formatMap = {
11
+ cjs: '.cjs',
12
+ iife: '.global.js',
13
+ esm: ['.js', '.mjs'],
14
+ };
15
+ const createBundleInputOptions = (context, format) => {
16
+ const mainFields =
17
+ context.mainFields ??
18
+ (format === 'iife' ? ['browser', 'module', 'main'] : undefined);
19
+ return (options) => {
20
+ if (!mainFields) return options;
21
+ return {
22
+ ...options,
23
+ resolve: {
24
+ ...options.resolve,
25
+ mainFields,
26
+ },
27
+ };
28
+ };
29
+ };
30
+ export function createBundleConfigs(context, formats) {
31
+ const outputConfigs = [];
32
+ let hasDtsConfig = false;
33
+ for (const format of formats) {
34
+ const extnames = formatMap[format];
35
+ for (const extname of Array.isArray(extnames) ? extnames : [extnames]) {
36
+ const emitDts = !hasDtsConfig;
37
+ outputConfigs.push({ format, extname, dts: emitDts });
38
+ hasDtsConfig ||= emitDts;
39
+ }
40
+ }
41
+ return outputConfigs.map(({ format, extname, dts }) => {
42
+ const deps =
43
+ format === 'iife'
44
+ ? {
45
+ neverBundle: context.peerExternal,
46
+ alwaysBundle: getIifeAlwaysBundle(context),
47
+ onlyBundle: false,
48
+ }
49
+ : {
50
+ neverBundle: context.packageExternal,
51
+ };
52
+ const inputOptions =
53
+ context.mainFields || format === 'iife'
54
+ ? createBundleInputOptions(context, format)
55
+ : undefined;
56
+ return configureTsdown(
57
+ context,
58
+ {
59
+ ...createCommonConfig(context, deps),
60
+ entry: getBundleEntry(context.packageRoot),
61
+ format,
62
+ globalName: context.globalName,
63
+ outDir: context.output,
64
+ dts,
65
+ treeshake: true,
66
+ banner: context.banner,
67
+ outExtensions: () => ({
68
+ js: extname,
69
+ }),
70
+ outputOptions: {
71
+ entryFileNames: `[name]${extname}`,
72
+ chunkFileNames: `[name]-[hash]${extname}`,
73
+ globals: format === 'iife' ? getIifeGlobals(context) : {},
74
+ },
75
+ inputOptions,
76
+ },
77
+ { kind: 'bundle', format },
78
+ );
79
+ });
80
+ }
@@ -0,0 +1,5 @@
1
+ import type { UserConfig } from 'tsdown/config';
2
+ import type { BuildContext } from '#auklet/build/tsdown/types';
3
+ export declare function createModuleConfigs(
4
+ context: BuildContext,
5
+ ): UserConfig[];
@@ -0,0 +1,46 @@
1
+ import path from 'node:path';
2
+ import {
3
+ configureTsdown,
4
+ createCommonConfig,
5
+ } from '#auklet/build/tsdown/common';
6
+ import { getModuleEntries } from '#auklet/build/tsdown/entries';
7
+ const createModuleConfig = (context, commonConfig, entry, format, outDir) => {
8
+ return configureTsdown(
9
+ context,
10
+ {
11
+ ...commonConfig,
12
+ entry,
13
+ format,
14
+ outDir,
15
+ dts: true,
16
+ unbundle: true,
17
+ outExtensions: () => ({
18
+ js: '.js',
19
+ dts: '.d.ts',
20
+ }),
21
+ },
22
+ { kind: 'module', format },
23
+ );
24
+ };
25
+ export function createModuleConfigs(context) {
26
+ const commonConfig = createCommonConfig(context, {
27
+ neverBundle: context.packageExternal,
28
+ });
29
+ const entry = getModuleEntries(context.packageRoot);
30
+ return [
31
+ createModuleConfig(
32
+ context,
33
+ commonConfig,
34
+ entry,
35
+ 'esm',
36
+ path.join(context.output, 'es'),
37
+ ),
38
+ createModuleConfig(
39
+ context,
40
+ commonConfig,
41
+ entry,
42
+ 'cjs',
43
+ path.join(context.output, 'lib'),
44
+ ),
45
+ ];
46
+ }
@@ -0,0 +1,30 @@
1
+ import type { UserConfig } from 'tsdown/config';
2
+ import type {
3
+ BuildContext,
4
+ ConfigureTsdownOptions,
5
+ TsdownDeps,
6
+ } from '#auklet/build/tsdown/types';
7
+ export declare function createCommonConfig(
8
+ context: BuildContext,
9
+ deps: TsdownDeps,
10
+ ): {
11
+ cwd: string;
12
+ root: string;
13
+ clean: false;
14
+ sourcemap: false;
15
+ tsconfig: string;
16
+ target: NonNullable<import('../../types').PackageBuildTarget | undefined>;
17
+ platform: NonNullable<import('../../types').PackageBuildPlatform | undefined>;
18
+ alias: Record<string, string>;
19
+ deps: import('node_modules/tsdown/dist/types-CQaSBA5U.mjs').L;
20
+ define: {
21
+ __TEST__: string;
22
+ __VERSION__: string;
23
+ __DEV__: string;
24
+ };
25
+ };
26
+ export declare function configureTsdown(
27
+ context: BuildContext,
28
+ config: UserConfig,
29
+ options: ConfigureTsdownOptions,
30
+ ): UserConfig;
@@ -0,0 +1,29 @@
1
+ export function createCommonConfig(context, deps) {
2
+ return {
3
+ cwd: context.packageRoot,
4
+ root: context.packageRoot,
5
+ clean: false,
6
+ sourcemap: false,
7
+ tsconfig: context.tsconfig,
8
+ target: context.target,
9
+ platform: context.platform,
10
+ alias: context.alias,
11
+ deps,
12
+ define: {
13
+ __TEST__: 'false',
14
+ __VERSION__: JSON.stringify(context.pkg.version),
15
+ __DEV__:
16
+ '(typeof process !== "undefined" ? (process.env?.NODE_ENV !== "production") : false)',
17
+ },
18
+ };
19
+ }
20
+ export function configureTsdown(context, config, options) {
21
+ return (
22
+ context.configureTsdown?.(config, {
23
+ ...options,
24
+ packageRoot: context.packageRoot,
25
+ output: context.output,
26
+ packageName: context.pkg.name,
27
+ }) ?? config
28
+ );
29
+ }
@@ -0,0 +1,23 @@
1
+ import type { PackageBuildOptions } from '#auklet/types';
2
+ import type { PackageJsonLike } from '#auklet/build/tsdown/types';
3
+ export declare function createBuildContext(
4
+ packageRoot: string,
5
+ options: PackageBuildOptions,
6
+ output: string,
7
+ ): {
8
+ pkg: PackageJsonLike;
9
+ banner: string;
10
+ packageRoot: string;
11
+ output: string;
12
+ runtimeDependencyNames: string[];
13
+ packageExternal: string[];
14
+ peerExternal: string[];
15
+ alias: Record<string, string>;
16
+ mainFields: string[] | undefined;
17
+ globals: Record<string, string>;
18
+ globalName: string;
19
+ platform: import('#auklet/types').PackageBuildPlatform;
20
+ target: import('#auklet/types').PackageBuildTarget;
21
+ configureTsdown: import('#auklet/types').ConfigureTsdown | undefined;
22
+ tsconfig: string;
23
+ };
@@ -0,0 +1,53 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import {
4
+ getPeerExternal,
5
+ getPackageExternal,
6
+ } from '#auklet/build/tsdown/dependencies';
7
+ const getGlobalName = (pkg) => {
8
+ return (pkg?.name ?? '')
9
+ .replace(/@/g, '')
10
+ .split(/[/-]/g)
11
+ .map((label) => label[0].toUpperCase() + label.slice(1))
12
+ .join('');
13
+ };
14
+ const findWorkspaceTsconfig = (packageRoot) => {
15
+ let current = packageRoot;
16
+ while (true) {
17
+ const tsconfig = path.join(current, 'tsconfig.json');
18
+ if (fs.existsSync(tsconfig)) return tsconfig;
19
+ const parent = path.dirname(current);
20
+ if (parent === current) return path.join(packageRoot, 'tsconfig.json');
21
+ current = parent;
22
+ }
23
+ };
24
+ export function createBuildContext(packageRoot, options, output) {
25
+ const pkg = JSON.parse(
26
+ fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'),
27
+ );
28
+ const banner =
29
+ options.banner ??
30
+ '/*!\n' +
31
+ ` * ${pkg.name}.js v${pkg.version}\n` +
32
+ (pkg.author ? ` * (c) ${new Date().getFullYear()} ${pkg.author}\n` : '') +
33
+ ' */';
34
+ return {
35
+ pkg,
36
+ banner,
37
+ packageRoot,
38
+ output,
39
+ runtimeDependencyNames: Object.keys(pkg.dependencies ?? {}),
40
+ packageExternal: getPackageExternal(pkg, options),
41
+ peerExternal: getPeerExternal(pkg, options),
42
+ alias: options.alias ?? {},
43
+ mainFields: options.mainFields,
44
+ globals: options.globals ?? {},
45
+ globalName: getGlobalName(pkg),
46
+ platform: options.platform,
47
+ target: options.target,
48
+ configureTsdown: options.configureTsdown,
49
+ tsconfig: options.tsconfig
50
+ ? path.resolve(packageRoot, options.tsconfig)
51
+ : findWorkspaceTsconfig(packageRoot),
52
+ };
53
+ }
@@ -0,0 +1,9 @@
1
+ import type { AukletConfig } from '#auklet/types';
2
+ export type { TsdownFormat } from '#auklet/build/tsdown/types';
3
+ export declare function defineKernelPackageConfigFromOptions(
4
+ packageRoot?: string,
5
+ config?: AukletConfig,
6
+ ): import('tsdown/config').UserConfig[];
7
+ export declare function defineKernelPackageConfigFromFile(
8
+ packageRoot?: string,
9
+ ): Promise<import('tsdown/config').UserConfig[]>;
@@ -0,0 +1,29 @@
1
+ import { loadAukletConfig } from '#auklet/configLoader';
2
+ import { normalizeAukletConfig } from '#auklet/config';
3
+ import { createBundleConfigs } from '#auklet/build/bundleConfig';
4
+ import { createModuleConfigs } from '#auklet/build/moduleConfig';
5
+ import { createBuildContext } from '#auklet/build/tsdown/context';
6
+ export function defineKernelPackageConfigFromOptions(
7
+ packageRoot = process.cwd(),
8
+ config = {},
9
+ ) {
10
+ const normalizedConfig = normalizeAukletConfig(config);
11
+ const buildOptions = normalizedConfig.build;
12
+ const formats = buildOptions.formats;
13
+ const context = createBuildContext(
14
+ packageRoot,
15
+ buildOptions,
16
+ normalizedConfig.output,
17
+ );
18
+ const bundleConfigs = createBundleConfigs(context, formats);
19
+ const moduleConfigs = normalizedConfig.modules
20
+ ? createModuleConfigs(context)
21
+ : [];
22
+ return [...bundleConfigs, ...moduleConfigs];
23
+ }
24
+ export async function defineKernelPackageConfigFromFile(
25
+ packageRoot = process.cwd(),
26
+ ) {
27
+ const config = await loadAukletConfig(packageRoot, { cacheBust: true });
28
+ return defineKernelPackageConfigFromOptions(packageRoot, config);
29
+ }
@@ -0,0 +1,16 @@
1
+ import type { PackageBuildOptions } from '#auklet/types';
2
+ import type { BuildContext, PackageJsonLike } from '#auklet/build/tsdown/types';
3
+ export declare function getPackageExternal(
4
+ pkg: PackageJsonLike,
5
+ options: PackageBuildOptions,
6
+ ): string[];
7
+ export declare function getPeerExternal(
8
+ pkg: PackageJsonLike,
9
+ options: PackageBuildOptions,
10
+ ): string[];
11
+ export declare function getIifeGlobals(context: BuildContext): {
12
+ [x: string]: string;
13
+ };
14
+ export declare function getIifeAlwaysBundle(
15
+ context: BuildContext,
16
+ ): (id: string) => boolean;
@@ -0,0 +1,65 @@
1
+ import { parseModuleId } from 'conditional-export';
2
+ const getExternal = (names) => {
3
+ const external = new Set();
4
+ for (const name of names) {
5
+ external.add(name);
6
+ external.add(`${name}/*`);
7
+ }
8
+ return [...external];
9
+ };
10
+ const getDependencyGlobalName = (name) => {
11
+ return name
12
+ .replace(/^@/, '')
13
+ .split(/[/-]/g)
14
+ .filter(Boolean)
15
+ .map((label) => label[0].toUpperCase() + label.slice(1))
16
+ .join('');
17
+ };
18
+ export function getPackageExternal(pkg, options) {
19
+ return getExternal([
20
+ ...Object.keys(pkg.dependencies ?? {}),
21
+ ...Object.keys(pkg.peerDependencies ?? {}),
22
+ ...Object.keys(pkg.optionalDependencies ?? {}),
23
+ ...Object.keys(pkg.devDependencies ?? {}),
24
+ ...(options.externals ?? []),
25
+ ]);
26
+ }
27
+ export function getPeerExternal(pkg, options) {
28
+ return [
29
+ ...new Set([
30
+ ...Object.keys(pkg.peerDependencies ?? {}),
31
+ ...(options.externals ?? []),
32
+ ]),
33
+ ];
34
+ }
35
+ export function getIifeGlobals(context) {
36
+ return {
37
+ ...Object.fromEntries(
38
+ context.peerExternal.map((name) => [name, getDependencyGlobalName(name)]),
39
+ ),
40
+ ...context.globals,
41
+ };
42
+ }
43
+ // React 本体 external,jsx-runtime 这层小入口 bundle 进产物。
44
+ export function getIifeAlwaysBundle(context) {
45
+ const warnedParseFailures = new Set();
46
+ const peerDependencies = new Set(context.peerExternal);
47
+ const runtimeDependencies = new Set(context.runtimeDependencyNames);
48
+ return (id) => {
49
+ if (id === 'react/jsx-runtime' || id === 'react/jsx-dev-runtime') {
50
+ return peerDependencies.has('react');
51
+ }
52
+ try {
53
+ id = parseModuleId(id).name;
54
+ } catch (error) {
55
+ if (!warnedParseFailures.has(id)) {
56
+ warnedParseFailures.add(id);
57
+ console.warn(
58
+ `[auklet:build] Unable to parse module id for IIFE bundle dependency classification: ${id}`,
59
+ error,
60
+ );
61
+ }
62
+ }
63
+ return peerDependencies.has(id) ? false : runtimeDependencies.has(id);
64
+ };
65
+ }
@@ -0,0 +1,8 @@
1
+ export declare function getBundleEntry(packageRoot: string): {
2
+ index: string;
3
+ };
4
+ export declare function getModuleEntries(packageRoot: string):
5
+ | Record<string, string>
6
+ | {
7
+ index: string;
8
+ };
@@ -0,0 +1,48 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ const toPosixPath = (value) => {
4
+ return value.split(path.sep).join('/');
5
+ };
6
+ export function getBundleEntry(packageRoot) {
7
+ const tsEntry = 'src/index.ts';
8
+ const tsxEntry = 'src/index.tsx';
9
+ if (fs.existsSync(path.join(packageRoot, tsEntry))) {
10
+ return { index: tsEntry };
11
+ }
12
+ if (fs.existsSync(path.join(packageRoot, tsxEntry))) {
13
+ return { index: tsxEntry };
14
+ }
15
+ return { index: tsEntry };
16
+ }
17
+ export function getModuleEntries(packageRoot) {
18
+ const sourceRoot = path.join(packageRoot, 'src');
19
+ const entries = {};
20
+ if (!fs.existsSync(sourceRoot)) {
21
+ return getBundleEntry(packageRoot);
22
+ }
23
+ const collect = (dir) => {
24
+ const dirEntries = fs
25
+ .readdirSync(dir, { withFileTypes: true })
26
+ .sort((a, b) => a.name.localeCompare(b.name));
27
+ for (const dirEntry of dirEntries) {
28
+ const file = path.join(dir, dirEntry.name);
29
+ if (dirEntry.isDirectory()) {
30
+ if (dirEntry.name !== '__tests__') collect(file);
31
+ continue;
32
+ }
33
+ if (!/\.(ts|tsx)$/.test(dirEntry.name)) continue;
34
+ if (/\.d\.ts$/.test(dirEntry.name)) continue;
35
+ if (/\.(spec|test)\.(ts|tsx)$/.test(dirEntry.name)) continue;
36
+ const sourceRelative = toPosixPath(path.relative(packageRoot, file));
37
+ const entryName = toPosixPath(path.relative(sourceRoot, file)).replace(
38
+ /\.(ts|tsx)$/,
39
+ '',
40
+ );
41
+ entries[entryName] ??= sourceRelative;
42
+ }
43
+ };
44
+ collect(sourceRoot);
45
+ return Object.keys(entries).length > 0
46
+ ? entries
47
+ : getBundleEntry(packageRoot);
48
+ }
@@ -0,0 +1,38 @@
1
+ import type { UserConfig } from 'tsdown/config';
2
+ import type {
3
+ ConfigureTsdownContext,
4
+ PackageBuildFormat,
5
+ PackageBuildOptions,
6
+ } from '#auklet/types';
7
+ export type TsdownFormat = PackageBuildFormat;
8
+ export type PackageJsonLike = {
9
+ name?: string;
10
+ version?: string;
11
+ author?: string;
12
+ dependencies?: Record<string, string>;
13
+ peerDependencies?: Record<string, string>;
14
+ optionalDependencies?: Record<string, string>;
15
+ devDependencies?: Record<string, string>;
16
+ };
17
+ export type BuildContext = {
18
+ packageRoot: string;
19
+ tsconfig: string;
20
+ output: string;
21
+ pkg: PackageJsonLike;
22
+ runtimeDependencyNames: Array<string>;
23
+ packageExternal: Array<string>;
24
+ peerExternal: Array<string>;
25
+ alias: Record<string, string>;
26
+ mainFields?: Array<string>;
27
+ globals: Record<string, string>;
28
+ banner: string;
29
+ globalName: string;
30
+ target: NonNullable<PackageBuildOptions['target']>;
31
+ platform: NonNullable<PackageBuildOptions['platform']>;
32
+ configureTsdown?: PackageBuildOptions['configureTsdown'];
33
+ };
34
+ export type TsdownDeps = NonNullable<UserConfig['deps']>;
35
+ export type ConfigureTsdownOptions = Pick<
36
+ ConfigureTsdownContext,
37
+ 'kind' | 'format'
38
+ >;
File without changes
@@ -1,12 +1,7 @@
1
- import type { UserConfig } from 'tsdown/config';
2
- import type { AukletConfig, PackageBuildFormat } from '#auklet/types';
3
- export type TsdownFormat = PackageBuildFormat;
4
- export declare function defineKernelPackageConfigFromOptions(
5
- packageRoot?: string,
6
- config?: AukletConfig,
7
- ): UserConfig[];
8
- export declare function defineKernelPackageConfigFromFile(
9
- packageRoot?: string,
10
- ): Promise<UserConfig[]>;
11
- declare const _default: Promise<UserConfig[]>;
1
+ export {
2
+ type TsdownFormat,
3
+ defineKernelPackageConfigFromFile,
4
+ defineKernelPackageConfigFromOptions,
5
+ } from '#auklet/build/tsdown/define';
6
+ declare const _default: Promise<import('tsdown/config').UserConfig[]>;
12
7
  export default _default;
@@ -1,313 +1,6 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import { loadAukletConfig } from '#auklet/configLoader';
4
- import { normalizeAukletConfig } from '#auklet/config';
5
- const formatMap = {
6
- cjs: '.cjs',
7
- iife: '.global.js',
8
- esm: ['.js', '.mjs'],
9
- };
10
- const getExternal = (names) => {
11
- const external = new Set();
12
- for (const name of names) {
13
- external.add(name);
14
- external.add(`${name}/*`);
15
- }
16
- return [...external];
17
- };
18
- const getPackageExternal = (pkg, options) => {
19
- return getExternal([
20
- ...Object.keys(pkg.dependencies ?? {}),
21
- ...Object.keys(pkg.peerDependencies ?? {}),
22
- ...Object.keys(pkg.optionalDependencies ?? {}),
23
- ...Object.keys(pkg.devDependencies ?? {}),
24
- ...(options.externals ?? []),
25
- ]);
26
- };
27
- const getPeerExternal = (pkg, options) => {
28
- return [
29
- ...new Set([
30
- ...Object.keys(pkg.peerDependencies ?? {}),
31
- ...(options.externals ?? []),
32
- ]),
33
- ];
34
- };
35
- const getDependencyGlobalName = (name) => {
36
- return name
37
- .replace(/^@/, '')
38
- .split(/[/-]/g)
39
- .filter(Boolean)
40
- .map((label) => label[0].toUpperCase() + label.slice(1))
41
- .join('');
42
- };
43
- const getIifeGlobals = (context) => {
44
- return {
45
- ...Object.fromEntries(
46
- context.peerExternal.map((name) => [name, getDependencyGlobalName(name)]),
47
- ),
48
- ...context.globals,
49
- };
50
- };
51
- const getIifeAlwaysBundle = (context) => {
52
- const names = new Set(context.runtimeDependencyNames);
53
- if (context.peerExternal.includes('react')) {
54
- names.add('react/jsx-runtime');
55
- names.add('react/jsx-dev-runtime');
56
- }
57
- return [...names];
58
- };
59
- const getGlobalName = (pkg) => {
60
- return (pkg?.name ?? '')
61
- .replace(/@/g, '')
62
- .split(/[/-]/g)
63
- .map((label) => label[0].toUpperCase() + label.slice(1))
64
- .join('');
65
- };
66
- const findWorkspaceTsconfig = (packageRoot) => {
67
- let current = packageRoot;
68
- while (true) {
69
- const tsconfig = path.join(current, 'tsconfig.json');
70
- if (fs.existsSync(tsconfig)) return tsconfig;
71
- const parent = path.dirname(current);
72
- if (parent === current) return path.join(packageRoot, 'tsconfig.json');
73
- current = parent;
74
- }
75
- };
76
- const getBundleEntry = (packageRoot) => {
77
- const tsEntry = 'src/index.ts';
78
- const tsxEntry = 'src/index.tsx';
79
- if (fs.existsSync(path.join(packageRoot, tsEntry))) {
80
- return { index: tsEntry };
81
- }
82
- if (fs.existsSync(path.join(packageRoot, tsxEntry))) {
83
- return { index: tsxEntry };
84
- }
85
- return { index: tsEntry };
86
- };
87
- const toPosixPath = (value) => {
88
- return value.split(path.sep).join('/');
89
- };
90
- const getModuleEntries = (packageRoot) => {
91
- const sourceRoot = path.join(packageRoot, 'src');
92
- const entries = {};
93
- if (!fs.existsSync(sourceRoot)) {
94
- return getBundleEntry(packageRoot);
95
- }
96
- const collect = (dir) => {
97
- const dirEntries = fs
98
- .readdirSync(dir, { withFileTypes: true })
99
- .sort((a, b) => a.name.localeCompare(b.name));
100
- for (const dirEntry of dirEntries) {
101
- const file = path.join(dir, dirEntry.name);
102
- if (dirEntry.isDirectory()) {
103
- if (dirEntry.name !== '__tests__') collect(file);
104
- continue;
105
- }
106
- if (!/\.(ts|tsx)$/.test(dirEntry.name)) continue;
107
- if (/\.d\.ts$/.test(dirEntry.name)) continue;
108
- if (/\.(spec|test)\.(ts|tsx)$/.test(dirEntry.name)) continue;
109
- const sourceRelative = toPosixPath(path.relative(packageRoot, file));
110
- const entryName = toPosixPath(path.relative(sourceRoot, file)).replace(
111
- /\.(ts|tsx)$/,
112
- '',
113
- );
114
- entries[entryName] ??= sourceRelative;
115
- }
116
- };
117
- collect(sourceRoot);
118
- return Object.keys(entries).length > 0
119
- ? entries
120
- : getBundleEntry(packageRoot);
121
- };
122
- const createBuildContext = (packageRoot, options, output) => {
123
- const pkg = JSON.parse(
124
- fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'),
125
- );
126
- const banner =
127
- options.banner ??
128
- '/*!\n' +
129
- ` * ${pkg.name}.js v${pkg.version}\n` +
130
- (pkg.author
131
- ? ` * (c) 2026-${new Date().getFullYear()} ${pkg.author}\n`
132
- : '') +
133
- ' */';
134
- return {
135
- pkg,
136
- banner,
137
- packageRoot,
138
- output,
139
- runtimeDependencyNames: Object.keys(pkg.dependencies ?? {}),
140
- packageExternal: getPackageExternal(pkg, options),
141
- peerExternal: getPeerExternal(pkg, options),
142
- alias: options.alias ?? {},
143
- mainFields: options.mainFields,
144
- globals: options.globals ?? {},
145
- globalName: getGlobalName(pkg),
146
- platform: options.platform,
147
- target: options.target,
148
- configureTsdown: options.configureTsdown,
149
- tsconfig: options.tsconfig
150
- ? path.resolve(packageRoot, options.tsconfig)
151
- : findWorkspaceTsconfig(packageRoot),
152
- };
153
- };
154
- const createCommonConfig = (context, deps) => {
155
- return {
156
- cwd: context.packageRoot,
157
- root: context.packageRoot,
158
- clean: false,
159
- sourcemap: false,
160
- tsconfig: context.tsconfig,
161
- target: context.target,
162
- platform: context.platform,
163
- alias: context.alias,
164
- deps,
165
- define: {
166
- __TEST__: 'false',
167
- __VERSION__: JSON.stringify(context.pkg.version),
168
- __DEV__:
169
- '(typeof process !== "undefined" ? (process.env?.NODE_ENV !== "production") : false)',
170
- },
171
- };
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
- };
188
- const configureTsdown = (context, config, options) => {
189
- return (
190
- context.configureTsdown?.(config, {
191
- ...options,
192
- packageRoot: context.packageRoot,
193
- output: context.output,
194
- packageName: context.pkg.name,
195
- }) ?? config
196
- );
197
- };
198
- const createBundleConfigs = (context, formats) => {
199
- const outputConfigs = [];
200
- let hasDtsConfig = false;
201
- for (const format of formats) {
202
- const extnames = formatMap[format];
203
- for (const extname of Array.isArray(extnames) ? extnames : [extnames]) {
204
- const emitDts = !hasDtsConfig;
205
- outputConfigs.push({ format, extname, dts: emitDts });
206
- hasDtsConfig ||= emitDts;
207
- }
208
- }
209
- return outputConfigs.map(({ format, extname, dts }) => {
210
- const deps =
211
- format === 'iife'
212
- ? {
213
- neverBundle: context.peerExternal,
214
- alwaysBundle: getIifeAlwaysBundle(context),
215
- onlyBundle: false,
216
- }
217
- : {
218
- neverBundle: context.packageExternal,
219
- };
220
- const inputOptions =
221
- context.mainFields || format === 'iife'
222
- ? createBundleInputOptions(context, format)
223
- : undefined;
224
- return configureTsdown(
225
- context,
226
- {
227
- ...createCommonConfig(context, deps),
228
- entry: getBundleEntry(context.packageRoot),
229
- format,
230
- globalName: context.globalName,
231
- outDir: context.output,
232
- dts,
233
- treeshake: true,
234
- banner: context.banner,
235
- outExtensions: () => ({
236
- js: extname,
237
- }),
238
- outputOptions: {
239
- entryFileNames: `[name]${extname}`,
240
- chunkFileNames: `[name]-[hash]${extname}`,
241
- globals: format === 'iife' ? getIifeGlobals(context) : {},
242
- },
243
- inputOptions,
244
- },
245
- { kind: 'bundle', format },
246
- );
247
- });
248
- };
249
- const createModuleConfig = (context, commonConfig, entry, format, outDir) => {
250
- return configureTsdown(
251
- context,
252
- {
253
- ...commonConfig,
254
- entry,
255
- format,
256
- outDir,
257
- dts: true,
258
- unbundle: true,
259
- outExtensions: () => ({
260
- js: '.js',
261
- dts: '.d.ts',
262
- }),
263
- },
264
- { kind: 'module', format },
265
- );
266
- };
267
- const createModuleConfigs = (context) => {
268
- const commonConfig = createCommonConfig(context, {
269
- neverBundle: context.packageExternal,
270
- });
271
- const entry = getModuleEntries(context.packageRoot);
272
- return [
273
- createModuleConfig(
274
- context,
275
- commonConfig,
276
- entry,
277
- 'esm',
278
- path.join(context.output, 'es'),
279
- ),
280
- createModuleConfig(
281
- context,
282
- commonConfig,
283
- entry,
284
- 'cjs',
285
- path.join(context.output, 'lib'),
286
- ),
287
- ];
288
- };
289
- export function defineKernelPackageConfigFromOptions(
290
- packageRoot = process.cwd(),
291
- config = {},
292
- ) {
293
- const normalizedConfig = normalizeAukletConfig(config);
294
- const buildOptions = normalizedConfig.build;
295
- const formats = buildOptions.formats;
296
- const context = createBuildContext(
297
- packageRoot,
298
- buildOptions,
299
- normalizedConfig.output,
300
- );
301
- const bundleConfigs = createBundleConfigs(context, formats);
302
- const moduleConfigs = normalizedConfig.modules
303
- ? createModuleConfigs(context)
304
- : [];
305
- return [...bundleConfigs, ...moduleConfigs];
306
- }
307
- export async function defineKernelPackageConfigFromFile(
308
- packageRoot = process.cwd(),
309
- ) {
310
- const config = await loadAukletConfig(packageRoot, { cacheBust: true });
311
- return defineKernelPackageConfigFromOptions(packageRoot, config);
312
- }
1
+ import { defineKernelPackageConfigFromFile } from '#auklet/build/tsdown/define';
2
+ export {
3
+ defineKernelPackageConfigFromFile,
4
+ defineKernelPackageConfigFromOptions,
5
+ } from '#auklet/build/tsdown/define';
313
6
  export default defineKernelPackageConfigFromFile(process.cwd());
@@ -1,6 +1,5 @@
1
- import fs from 'node:fs';
2
1
  import path from 'node:path';
3
- import { emptyModuleEntryComment } from '#auklet/css/production/format/shared';
2
+ import { writeStyleFile } from '#auklet/css/production/format/shared';
4
3
  import { toPosixPath } from '#auklet/utils';
5
4
  export class ComponentStyleEntryWriter {
6
5
  config;
@@ -36,12 +35,9 @@ export class ComponentStyleEntryWriter {
36
35
  this.resolver.toOutputStyleSpecifier(specifier, outRoot),
37
36
  );
38
37
  }
39
- fs.mkdirSync(styleDir, { recursive: true });
40
- fs.writeFileSync(
38
+ writeStyleFile(
41
39
  target,
42
- root.nodes?.length
43
- ? this.styleProcessor.stringify(root)
44
- : emptyModuleEntryComment,
40
+ root.nodes?.length ? this.styleProcessor.stringify(root) : '',
45
41
  );
46
42
  outputs.push(target);
47
43
  }
@@ -1,7 +1,9 @@
1
- import fs from 'node:fs';
2
1
  import path from 'node:path';
3
2
  import { createStyleEntryParts } from '#auklet/css/core/style/entries';
4
- import { toRelativeImportSpecifier } from '#auklet/css/production/format/shared';
3
+ import {
4
+ writeStyleFile,
5
+ toRelativeImportSpecifier,
6
+ } from '#auklet/css/production/format/shared';
5
7
  export class StyleEntryWriter {
6
8
  config;
7
9
  packageContext;
@@ -47,8 +49,7 @@ export class StyleEntryWriter {
47
49
  }
48
50
  }
49
51
  if (!root.nodes?.length) return null;
50
- fs.mkdirSync(path.dirname(target), { recursive: true });
51
- fs.writeFileSync(target, this.styleProcessor.stringify(root));
52
+ writeStyleFile(target, this.styleProcessor.stringify(root));
52
53
  return target;
53
54
  }
54
55
  }
@@ -1,4 +1,4 @@
1
- import type { FormatWriterOptions } from '#auklet/css/production/format/shared';
1
+ import { type FormatWriterOptions } from '#auklet/css/production/format/shared';
2
2
  export declare class ExternalStyleWriter {
3
3
  private readonly config;
4
4
  private readonly packageContext;
@@ -1,6 +1,6 @@
1
- import fs from 'node:fs';
2
1
  import path from 'node:path';
3
2
  import { createExternalEntryParts } from '#auklet/css/core/style/entries';
3
+ import { writeStyleFile } from '#auklet/css/production/format/shared';
4
4
  export class ExternalStyleWriter {
5
5
  config;
6
6
  packageContext;
@@ -29,8 +29,7 @@ export class ExternalStyleWriter {
29
29
  );
30
30
  }
31
31
  }
32
- fs.mkdirSync(path.dirname(target), { recursive: true });
33
- fs.writeFileSync(
32
+ writeStyleFile(
34
33
  target,
35
34
  root.nodes?.length ? this.styleProcessor.stringify(root) : '',
36
35
  );
@@ -1,4 +1,4 @@
1
- import type { FormatWriterOptions } from '#auklet/css/production/format/shared';
1
+ import { type FormatWriterOptions } from '#auklet/css/production/format/shared';
2
2
  export declare class ModuleStyleWriter {
3
3
  private readonly config;
4
4
  private readonly packageContext;
@@ -1,5 +1,5 @@
1
- import fs from 'node:fs';
2
1
  import path from 'node:path';
2
+ import { writeStyleFile } from '#auklet/css/production/format/shared';
3
3
  export class ModuleStyleWriter {
4
4
  config;
5
5
  packageContext;
@@ -24,8 +24,7 @@ export class ModuleStyleWriter {
24
24
  }
25
25
  }
26
26
  if (!root.nodes?.length) return null;
27
- fs.mkdirSync(path.dirname(target), { recursive: true });
28
- fs.writeFileSync(target, this.styleProcessor.stringify(root));
27
+ writeStyleFile(target, this.styleProcessor.stringify(root));
29
28
  return target;
30
29
  }
31
30
  }
@@ -3,8 +3,8 @@ import type {
3
3
  ModuleStyleBuildConfig,
4
4
  ResolvedModuleStyleBuildContext,
5
5
  } from '#auklet/types';
6
- export declare const emptyModuleEntryComment =
7
- '/* Empty style entry kept so automated tooling can resolve this module CSS path. */\n';
6
+ export declare const emptyStyleFileComment =
7
+ '/* Empty style file kept so automated tooling can resolve this CSS path. */\n';
8
8
  export type FormatWriterOptions = {
9
9
  config: ModuleStyleBuildConfig;
10
10
  context: ResolvedModuleStyleBuildContext;
@@ -18,3 +18,4 @@ export declare function toRelativeImportSpecifier(
18
18
  fromDir: string,
19
19
  file: string,
20
20
  ): string;
21
+ export declare function writeStyleFile(file: string, code: string): void;
@@ -1,8 +1,13 @@
1
+ import fs from 'node:fs';
1
2
  import path from 'node:path';
2
3
  import { toPosixPath } from '#auklet/utils';
3
- export const emptyModuleEntryComment =
4
- '/* Empty style entry kept so automated tooling can resolve this module CSS path. */\n';
4
+ export const emptyStyleFileComment =
5
+ '/* Empty style file kept so automated tooling can resolve this CSS path. */\n';
5
6
  export function toRelativeImportSpecifier(fromDir, file) {
6
7
  const relative = toPosixPath(path.relative(fromDir, file));
7
8
  return relative.startsWith('.') ? relative : `./${relative}`;
8
9
  }
10
+ export function writeStyleFile(file, code) {
11
+ fs.mkdirSync(path.dirname(file), { recursive: true });
12
+ fs.writeFileSync(file, code.trim() ? code : emptyStyleFileComment);
13
+ }
@@ -1,4 +1,4 @@
1
- import type { FormatWriterOptions } from '#auklet/css/production/format/shared';
1
+ import { type FormatWriterOptions } from '#auklet/css/production/format/shared';
2
2
  export declare class SourceStyleFileWriter {
3
3
  private readonly sourceRoot;
4
4
  constructor(options: FormatWriterOptions);
@@ -1,5 +1,6 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
+ import { writeStyleFile } from '#auklet/css/production/format/shared';
3
4
  export class SourceStyleFileWriter {
4
5
  sourceRoot;
5
6
  constructor(options) {
@@ -9,8 +10,7 @@ export class SourceStyleFileWriter {
9
10
  for (const sourceFile of files) {
10
11
  const relative = path.relative(this.sourceRoot, sourceFile);
11
12
  const target = path.join(outRoot, relative);
12
- fs.mkdirSync(path.dirname(target), { recursive: true });
13
- fs.copyFileSync(sourceFile, target);
13
+ writeStyleFile(target, fs.readFileSync(sourceFile, 'utf8'));
14
14
  }
15
15
  }
16
16
  }
@@ -2,7 +2,10 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { THEMES_DIR } from '#auklet/css/constants';
4
4
  import { createThemeEntryParts } from '#auklet/css/core/style/entries';
5
- import { toRelativeImportSpecifier } from '#auklet/css/production/format/shared';
5
+ import {
6
+ writeStyleFile,
7
+ toRelativeImportSpecifier,
8
+ } from '#auklet/css/production/format/shared';
6
9
  export class ThemeStyleWriter {
7
10
  config;
8
11
  packageContext;
@@ -36,8 +39,7 @@ export class ThemeStyleWriter {
36
39
  this.styleProcessor.appendStyleContent(root, content, stylePath);
37
40
  }
38
41
  const target = path.join(themesDir, `${themeName}.css`);
39
- fs.mkdirSync(path.dirname(target), { recursive: true });
40
- fs.writeFileSync(
42
+ writeStyleFile(
41
43
  target,
42
44
  root.nodes?.length ? this.styleProcessor.stringify(root) : '',
43
45
  );
@@ -71,8 +73,7 @@ export class ThemeStyleWriter {
71
73
  }
72
74
  }
73
75
  if (!root.nodes?.length) continue;
74
- fs.mkdirSync(targetDir, { recursive: true });
75
- fs.writeFileSync(target, this.styleProcessor.stringify(root));
76
+ writeStyleFile(target, this.styleProcessor.stringify(root));
76
77
  outputs.push(target);
77
78
  }
78
79
  return outputs;
@@ -1,5 +1,5 @@
1
- import fs from 'node:fs';
2
1
  import path from 'node:path';
2
+ import { writeStyleFile } from '#auklet/css/production/format/shared';
3
3
  import { getGlobalStyleDependencies } from '#auklet/css/core/style/dependencies';
4
4
  // Builds the package-level style entry at `dist/index.css` by aggregating local themes, dependencies, and source styles.
5
5
  export class PackageStyleEntryWriter {
@@ -41,12 +41,11 @@ export class PackageStyleEntryWriter {
41
41
  }
42
42
  }
43
43
  if (!root.nodes?.length) return null;
44
- fs.mkdirSync(this.outputRoot, { recursive: true });
45
44
  const target = path.join(
46
45
  this.outputRoot,
47
46
  this.config.output.indexStyleFile,
48
47
  );
49
- fs.writeFileSync(target, this.styleProcessor.stringify(root));
48
+ writeStyleFile(target, this.styleProcessor.stringify(root));
50
49
  return target;
51
50
  }
52
51
  get outputRoot() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auklet",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "type": "module",
5
5
  "author": "chentao.arthur",
6
6
  "packageManager": "pnpm@10.27.0",