Skip to content

Commit c51e551

Browse files
committed
feat: support pkg options
issue: #682
1 parent 2e2abbd commit c51e551

File tree

20 files changed

+837
-84
lines changed

20 files changed

+837
-84
lines changed

.changeset/slimy-walls-tease.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@ice/pkg': minor
3+
---
4+
5+
feat: support `pkg` options

packages/pkg/src/core/createPkg.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import { Context, CustomFormatTaskCreator, ExtendsPluginAPI, TaskConfig, UserCon
44
import taskRegisterPlugin from '../plugins/component.js';
55
import { userConfigSchema } from '../config/schema.js';
66
import { createMessageBuilder, fromZodError } from 'zod-validation-error';
7-
import { registerTasks } from './registerTasks.js';
7+
import { registerPkgTasks, registerTasks } from './registerTasks.js';
88
import { initContextTasks } from './initContextTasks.js';
9+
import { resolvePackage, runPkgPlugins } from './pkg.js';
910

1011
export interface CreatePkgOptions {
1112
rootDir: string;
@@ -105,7 +106,15 @@ export async function createPkg(options: CreatePkgOptions) {
105106
throw prettyError;
106107
}
107108

108-
registerTasks(ctx, customFormats);
109+
const pkgs = await resolvePackage(ctx);
110+
await runPkgPlugins(ctx, pkgs);
111+
112+
if (pkgs.length) {
113+
await registerPkgTasks(ctx, pkgs);
114+
} else {
115+
// when pkg is preset, no need to register old tasks
116+
registerTasks(ctx, customFormats);
117+
}
109118

110119
initContextTasks(ctx);
111120

packages/pkg/src/core/initContextTasks.ts

Lines changed: 84 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { BuildTask, BundleUserConfig, Context, DeclarationUserConfig } from '../types.js'; // 添加 .js 后缀
2-
import { formatEntry, getTransformDefaultOutputDir } from '../helpers/getTaskIO.js'; // 添加 .js 后缀
3-
import getDefaultDefineValues from '../helpers/getDefaultDefineValues.js'; // 添加 .js 后缀
4-
import { stringifyObject } from '../utils.js'; // 添加 .js 后缀
5-
import { getDefaultBundleSwcConfig, getDefaultTransformSwcConfig } from '../helpers/defaultSwcConfig.js'; // 添加 .js 后缀
6-
import { merge, mergeWith } from 'es-toolkit/object';
1+
import { BuildTask, BundleUserConfig, Context, DeclarationUserConfig } from '../types.js';
2+
import { formatEntry, getTransformDefaultOutputDir } from '../helpers/getTaskIO.js';
3+
import getDefaultDefineValues from '../helpers/getDefaultDefineValues.js';
4+
import { stringifyObject } from '../utils.js';
5+
import { merge, mergeWith, omit } from 'es-toolkit/object';
76
import path from 'node:path';
7+
import { groupBy } from 'es-toolkit';
88

99
const mergeDefaults: typeof merge = (target, source) => {
1010
return mergeWith(target, source, (targetValue, sourceValue) => {
@@ -33,49 +33,64 @@ const defaultDeclarationUserConfig = {
3333
export function initContextTasks(ctx: Context) {
3434
const tasks = ctx.getTaskConfig() as BuildTask[];
3535

36-
for (const buildTask of tasks) {
36+
const { declaration: declarationTasks, buildable: buildableTasks } = groupBy(tasks, (task) =>
37+
task.config.type === 'declaration' ? 'declaration' : 'buildable',
38+
);
39+
40+
// 1. init all tasks except declaration
41+
for (const buildTask of buildableTasks) {
3742
initTask(buildTask, ctx);
3843
}
44+
45+
// 2. init declaration based on transform tasks
46+
for (const buildTask of declarationTasks ?? []) {
47+
initDeclarationTask(buildTask, ctx, buildableTasks);
48+
}
3949
}
4050

41-
/**
42-
* @internal export for test
43-
*/
44-
export function initTask(
45-
buildTask: BuildTask,
46-
{ userConfig, rootDir, command }: Pick<Context, 'userConfig' | 'rootDir' | 'command'>,
47-
) {
48-
const { config, name: taskName } = buildTask;
51+
type InitTaskOptions = Pick<Context, 'userConfig' | 'rootDir' | 'command'>;
4952

50-
config.entry = formatEntry(config.entry ?? userConfig.entry);
51-
config.alias ??= userConfig.alias;
53+
function initSharedTask(buildTask: BuildTask, options: InitTaskOptions) {
54+
const { userConfig, command } = options;
55+
const { config } = buildTask;
56+
const { pkg } = config;
57+
58+
config.entry = formatEntry(config.entry ?? pkg?.entry ?? userConfig.entry);
59+
config.alias ??= mergeDefaults({ ...pkg?.alias }, userConfig.alias ?? {});
5260
// Configure define
5361
config.define = Object.assign(
5462
// Note: The define values in bundle mode will be defined (according to the `modes` value)
5563
// in generating rollup options. But when the command is test, we don't need to get the rollup options.
5664
// So in test, we assume the mode is 'development'.
5765
command === 'test' ? getDefaultDefineValues('development') : {},
58-
stringifyObject(config.define ?? userConfig.define ?? {}),
66+
stringifyObject(userConfig.define ?? {}),
67+
stringifyObject(pkg?.define ?? {}),
68+
stringifyObject(config.define ?? {}),
5969
);
6070

61-
config.sourcemap ??= userConfig.sourceMaps ?? command === 'start';
62-
config.jsxRuntime ??= userConfig.jsxRuntime;
71+
config.sourcemap ??= pkg?.sourceMaps ?? userConfig.sourceMaps ?? command === 'start';
72+
config.jsxRuntime ??= pkg?.jsxRuntime ?? userConfig.jsxRuntime;
73+
}
74+
75+
/**
76+
* @internal export for test
77+
*/
78+
export function initTask(buildTask: BuildTask, options: InitTaskOptions) {
79+
const { userConfig, rootDir, command } = options;
80+
const { config, name: taskName } = buildTask;
81+
const { pkg } = config;
82+
83+
initSharedTask(buildTask, options);
6384

6485
const expectedMode = command === 'build' ? 'production' : 'development';
6586

6687
if (config.type === 'bundle') {
6788
const bundleConfig = userConfig.bundle ?? {};
6889
config.modes ??= bundleConfig.modes ?? [expectedMode];
69-
config.engine ??= bundleConfig.engine;
70-
const defaultBundleSwcConfig = getDefaultBundleSwcConfig(config);
71-
config.swcCompileOptions =
72-
typeof config.modifySwcCompileOptions === 'function'
73-
? config.modifySwcCompileOptions(defaultBundleSwcConfig)
74-
: merge(defaultBundleSwcConfig, config.swcCompileOptions || {});
7590
// TODO: 判断下这个东西是否真的有用
7691
// Set outputDir to process.env for CI
7792
process.env.ICE_PKG_BUNDLE_OUTPUT_DIR = config.outputDir;
78-
const originMinifyConfig = bundleConfig.minify ?? defaultBundleUserConfig.minify ?? {};
93+
const originMinifyConfig = pkg?.minify ?? bundleConfig.minify ?? defaultBundleUserConfig.minify ?? {};
7994
let { jsMinify, cssMinify } = config;
8095
if (typeof originMinifyConfig === 'object') {
8196
jsMinify ??= getMinifyFunction(originMinifyConfig.js);
@@ -88,39 +103,60 @@ export function initTask(
88103
config.jsMinify = jsMinify;
89104
config.cssMinify = cssMinify;
90105

106+
config.outputDir ??= pkg?.outputDir ?? bundleConfig.outputDir ?? defaultBundleUserConfig.outputDir;
107+
108+
if (pkg) {
109+
mergeDefaults(config, omit(pkg, ['id', 'pluginInfos', 'id', 'target', 'module', 'declaration', 'outputDir']));
110+
}
91111
mergeDefaults(config, bundleConfig);
92112
mergeDefaults(config, defaultBundleUserConfig);
93113
} else if (config.type === 'transform') {
94114
config.modes ??= [expectedMode];
95-
config.outputDir ??= getTransformDefaultOutputDir(rootDir, taskName);
96-
const defaultTransformSwcConfig = getDefaultTransformSwcConfig(config, expectedMode);
97-
config.swcCompileOptions =
98-
typeof config.modifySwcCompileOptions === 'function'
99-
? config.modifySwcCompileOptions(defaultTransformSwcConfig)
100-
: merge(defaultTransformSwcConfig, config.swcCompileOptions || {});
115+
config.outputDir ??= pkg?.outputDir ?? getTransformDefaultOutputDir(rootDir, taskName, config);
101116
} else if (config.type === 'declaration') {
102-
const { declaration: declarationConfig } = userConfig;
103-
if (declarationConfig === false) {
104-
throw new Error('Cannot disable declaration when transform formats is not empty.');
105-
}
106-
config.outputMode ??=
107-
declarationConfig === true
108-
? defaultDeclarationUserConfig.outputMode
109-
: (declarationConfig.outputMode ?? defaultDeclarationUserConfig.outputMode);
110-
// 这个 output 仅仅用于生成正确的 .d.ts 的 alias,不做实际输出目录
111-
config.outputDir = path.resolve(rootDir, config.transformFormats[0]);
112-
if (config.outputMode === 'unique') {
113-
config.declarationOutputDirs = [path.resolve(rootDir, 'typings')];
114-
} else {
115-
config.declarationOutputDirs = config.transformFormats.map((format) => path.resolve(rootDir, format));
116-
}
117+
// should run in initDeclarationTask
117118
} else {
118119
throw new Error('Invalid task type.');
119120
}
120121

121122
return buildTask;
122123
}
123124

125+
/**
126+
* 需要判断 entry 是否一致,对于不一致的 entry,理论上要生成多个 declaration task
127+
* @internal export for test
128+
*/
129+
export function initDeclarationTask(buildTask: BuildTask, options: InitTaskOptions, allTasks: BuildTask[]) {
130+
const { userConfig, rootDir } = options;
131+
const { config } = buildTask;
132+
const { declaration: declarationConfig } = userConfig;
133+
if (config.type !== 'declaration') {
134+
throw new Error('initDeclarationTask only allow declaration task');
135+
}
136+
if (declarationConfig === false) {
137+
throw new Error('Cannot disable declaration when transform formats is not empty.');
138+
}
139+
initSharedTask(buildTask, options);
140+
config.outputMode ??=
141+
declarationConfig === true
142+
? defaultDeclarationUserConfig.outputMode
143+
: (declarationConfig.outputMode ?? defaultDeclarationUserConfig.outputMode);
144+
const allOutputDirs = allTasks
145+
.map((v) => {
146+
return v.config.type === 'transform' ? v.config.outputDir! : '';
147+
})
148+
.filter(Boolean);
149+
// 这个 output 仅仅用于生成正确的 .d.ts 的 alias,不做实际输出目录
150+
config.outputDir = allOutputDirs[0];
151+
if (config.outputMode === 'unique') {
152+
config.declarationOutputDirs = [path.resolve(rootDir, 'typings')];
153+
} else {
154+
config.declarationOutputDirs = allOutputDirs;
155+
}
156+
157+
return buildTask;
158+
}
159+
124160
function getMinifyFunction(minify: boolean | ((mode: string, command: string) => unknown)) {
125161
switch (typeof minify) {
126162
case 'boolean':

0 commit comments

Comments
 (0)