Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit fcda1c9

Browse files
committedNov 4, 2024··
add runnerGroup
1 parent 8e10e4b commit fcda1c9

File tree

11 files changed

+105
-50
lines changed

11 files changed

+105
-50
lines changed
 

‎examples/react-component/build.config.mts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export default defineConfig({
2121
// declaration: false,
2222
sourceMaps: false,
2323
bundle: {
24-
formats: ['esm'],
24+
formats: ['esm', 'es2017'],
2525
// modes: ['production', 'development']
2626
// development: true,
2727
},

‎packages/pkg/src/commands/build.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import fse from 'fs-extra';
22
import { getBuildTasks } from '../helpers/getBuildTasks.js';
33
import type { Context, OutputResult } from '../types.js';
4-
import { parallelPromiseAll } from '../utils.js';
54
import { RunnerLinerTerminalReporter } from '../helpers/runnerReporter.js';
65
import { getTaskRunners } from '../helpers/getTaskRunners.js';
6+
import { RunnerGroup } from '../helpers/runnerGroup.js';
77

88
export default async function build(context: Context) {
99
const { applyHook, commandArgs } = context;
@@ -32,8 +32,10 @@ export default async function build(context: Context) {
3232
const tasks = getTaskRunners(buildTasks, context)
3333

3434
try {
35-
const results = parallelPromiseAll(tasks.map(task => () => task.run()))
3635
const terminal = new RunnerLinerTerminalReporter(tasks)
36+
const taskGroup = new RunnerGroup(tasks)
37+
38+
const results = taskGroup.run()
3739
terminal.start()
3840

3941
const outputResults: OutputResult[] = await results

‎packages/pkg/src/commands/start.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import type {
66
Context,
77
WatchChangedFile,
88
} from '../types.js';
9-
import { parallelPromiseAll } from '../utils.js';
109
import { RunnerLinerTerminalReporter } from '../helpers/runnerReporter.js';
1110
import { getTaskRunners } from '../helpers/getTaskRunners.js';
11+
import { RunnerGroup } from '../helpers/runnerGroup.js';
1212

1313
export default async function start(context: Context) {
1414
const { applyHook, commandArgs } = context;
@@ -41,8 +41,10 @@ export default async function start(context: Context) {
4141

4242
const tasks = getTaskRunners(buildTasks, context)
4343

44-
const results = parallelPromiseAll(tasks.map(task => () => task.run()))
4544
const terminal = new RunnerLinerTerminalReporter(tasks)
45+
const taskGroup = new RunnerGroup(tasks)
46+
47+
const results = taskGroup.run()
4648
terminal.start()
4749

4850
const outputResults: OutputResult[] = await results
@@ -55,9 +57,9 @@ export default async function start(context: Context) {
5557

5658
async function runChangedCompile(changedFiles: WatchChangedFile[]) {
5759
try {
58-
const results = parallelPromiseAll(tasks.map(task => () => task.run(changedFiles)))
60+
const newResults = taskGroup.run(changedFiles)
5961
terminal.start()
60-
const newOutputResults: OutputResult[] = await results
62+
const newOutputResults: OutputResult[] = await newResults
6163
terminal.pause()
6264

6365
await applyHook('after.start.compile', newOutputResults);

‎packages/pkg/src/helpers/runner.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export enum RunnerStatus {
1111

1212
export type RunnerHandler<T> = (runner: Runner<T>, updatedFiles?: WatchChangedFile[]) => Promise<T>
1313

14-
export class Runner<T = unknown> extends TypedEventEmitter<{
14+
export abstract class Runner<T = unknown> extends TypedEventEmitter<{
1515
status: RunnerStatus,
1616
progress: [number, number],
1717
mark: string
@@ -42,17 +42,24 @@ export class Runner<T = unknown> extends TypedEventEmitter<{
4242
return this.status === RunnerStatus.Running
4343
}
4444

45-
constructor(public context: TaskRunnerContext, private handler: RunnerHandler<T>) {
45+
// this task is not to run in main thread.
46+
get isParallel(): boolean {
47+
return false;
48+
}
49+
50+
constructor(public context: TaskRunnerContext) {
4651
super()
4752
this.name = context.buildTask.name
4853
}
4954

55+
abstract doRun(files?: WatchChangedFile[]): Promise<T>
56+
5057
async run(files?: WatchChangedFile[]) {
5158
if (!this.taskRunning) {
5259
this.metrics = {}
5360
this.updateStatus(RunnerStatus.Running)
5461
this.mark(TASK_MARK)
55-
let running = this.handler(this, files)
62+
let running = this.doRun(files)
5663
running = running.then((data) => {
5764
this.mark(TASK_MARK)
5865
return data
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Runner } from './runner.js';
2+
import { WatchChangedFile } from '../types.js';
3+
import { concurrentPromiseAll } from '../utils.js';
4+
5+
export class RunnerGroup<T> {
6+
private parallelRunners: Runner<T>[] = [];
7+
private concurrentRunners: Runner<T>[] = [];
8+
9+
constructor(public runners: Runner<T>[]) {
10+
for (const runner of runners) {
11+
if (runner.isParallel) {
12+
this.parallelRunners.push(runner);
13+
} else {
14+
this.concurrentRunners.push(runner)
15+
}
16+
}
17+
}
18+
19+
async run(changedFiles?: WatchChangedFile[]): Promise<T[]> {
20+
const parallelPromise = Promise.all(this.parallelRunners.map(runner => runner.run(changedFiles)))
21+
const concurrentPromise = concurrentPromiseAll(this.concurrentRunners.map(runner => () => runner.run(changedFiles)), 1)
22+
23+
const [parallelResults, concurrentResults] = await Promise.all([parallelPromise, concurrentPromise])
24+
25+
return [...parallelResults, ...concurrentResults]
26+
}
27+
}

‎packages/pkg/src/helpers/runnerReporter.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ export class RunnerLinerTerminalReporter {
134134
private logFinished(runner: Runner) {
135135
const { status, context } = runner
136136
if (status === RunnerStatus.Finished) {
137-
const items: string[] = [chalk.green(figures.tick), chalk.dim(runner.name)];
137+
// TODO: for error
138+
const items: string[] = [chalk.green(figures.tick), chalk.cyan(runner.name)];
138139

139140
items.push(formatTimeCost(runner.getMetric(TASK_MARK).cost));
140141

‎packages/pkg/src/tasks/bundle.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,11 @@ export class BundleRunner extends Runner<OutputResult> {
3131
private result: Error | OutputResult | null;
3232
private readonly executors = [];
3333
constructor(taskRunningContext: TaskRunnerContext) {
34-
super(taskRunningContext, async (_, files) => {
35-
return this.runHandler(files)
36-
});
34+
super(taskRunningContext);
3735
this.rollupOptions = getRollupOptions(taskRunningContext.buildContext, taskRunningContext)
3836
}
3937

40-
private async runHandler(changedFiles: WatchChangedFile[]): Promise<OutputResult> {
38+
async doRun(changedFiles: WatchChangedFile[]): Promise<OutputResult> {
4139
const { rollupOptions, context } = this
4240
if (context.watcher) {
4341
if (this.watcher) {
@@ -144,7 +142,7 @@ class WatchEmitter<T extends Record<string, (...parameters: any) => any>> extend
144142
// eslint-disable-next-line no-return-assign
145143
return this.awaitedHandlers[event] || (this.awaitedHandlers[event] = []);
146144
}
147-
once(eventName: string | symbol, listener: (...args: any[]) => void): this {
145+
override once(eventName: string | symbol, listener: (...args: any[]) => void): this {
148146
const handle = (...args) => {
149147
this.off(eventName, handle);
150148
return listener.apply(this, args);

‎packages/pkg/src/tasks/declaration.ts

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,52 @@
11
import path from 'node:path';
22
import cp from 'node:child_process'
3+
import { fileURLToPath } from 'node:url';
34
import { OutputResult, TaskRunnerContext } from '../types.js';
45
import globby from 'globby'
5-
import { fileURLToPath } from 'node:url';
6-
import { Runner, RunnerHandler } from '../helpers/runner.js';
6+
import { Runner } from '../helpers/runner.js';
77
import { Rpc } from '../helpers/rpc.js';
88
import { DeclarationMainMethods, DeclarationWorkerMethods } from './declaration.rpc.js';
99

1010
const dirname = path.dirname(fileURLToPath(import.meta.url))
1111

1212
export function createDeclarationTask(context: TaskRunnerContext) {
13-
return new Runner<OutputResult>(context, runDeclaration)
13+
return new DeclarationRunner(context)
1414
}
1515

16-
const runDeclaration: RunnerHandler<OutputResult> = async (task) => {
17-
// TODO: 应该使用和 transform 一致的目录
18-
const files = await globby('src/**/*.{ts,tsx,mts,cts}', {
19-
cwd: task.context.buildContext.rootDir,
20-
onlyFiles: true,
21-
ignore: ['**/*.d.{ts,mts,cts}'],
22-
absolute: true,
23-
})
24-
const child = cp.fork(path.join(dirname, './declaration.worker.js'), {})
25-
const rpc = new Rpc<DeclarationWorkerMethods, DeclarationMainMethods>({
26-
postMessage: e => child.send(e as any),
27-
onMessage: handler => child.on('message', handler)
28-
}, {
29-
})
16+
class DeclarationRunner extends Runner<OutputResult> {
17+
override get isParallel() {
18+
return true;
19+
}
20+
21+
async doRun() {
22+
const { context } = this
23+
// TODO: 应该使用和 transform 一致的目录
24+
const files = await globby('src/**/*.{ts,tsx,mts,cts}', {
25+
cwd: context.buildContext.rootDir,
26+
onlyFiles: true,
27+
ignore: ['**/*.d.{ts,mts,cts}'],
28+
absolute: true,
29+
})
30+
const child = cp.fork(path.join(dirname, './declaration.worker.js'), {})
31+
const rpc = new Rpc<DeclarationWorkerMethods, DeclarationMainMethods>({
32+
postMessage: e => child.send(e as any),
33+
onMessage: handler => child.on('message', handler)
34+
}, {
35+
})
3036

31-
await rpc.call('run', [{
32-
files,
33-
rootDir: task.context.buildContext.rootDir,
34-
outputDir: task.context.buildTask.config.outputDir,
35-
alias: task.context.buildTask.config.alias
36-
}])
37+
await rpc.call('run', [{
38+
files,
39+
rootDir: context.buildContext.rootDir,
40+
outputDir: context.buildTask.config.outputDir,
41+
alias: context.buildTask.config.alias
42+
}])
3743

38-
child.kill()
44+
child.kill()
3945

40-
return {
41-
taskName: task.context.buildTask.name,
42-
outputs: [],
43-
outputFiles: [],
46+
return {
47+
taskName: context.buildTask.name,
48+
outputs: [],
49+
outputFiles: [],
50+
}
4451
}
4552
}

‎packages/pkg/src/tasks/transform.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,28 @@ import type {
1111
OutputFile,
1212
OutputResult,
1313
TaskRunnerContext,
14-
TransformTaskConfig,
14+
TransformTaskConfig, WatchChangedFile,
1515
} from '../types.js';
1616
import type { RollupOptions, SourceMapInput } from 'rollup';
1717
import { getTransformEntryDirs } from '../helpers/getTaskIO.js';
1818
import { getRollupOptions } from '../helpers/getRollupOptions.js';
1919
import { Runner } from '../helpers/runner.js';
2020

2121
export function createTransformTask(taskRunnerContext: TaskRunnerContext) {
22-
const rollupOptions = getRollupOptions(taskRunnerContext.buildContext, taskRunnerContext)
23-
return new Runner<OutputResult>(taskRunnerContext, (task, updatedFiles) => {
24-
return runTransform(task, rollupOptions, updatedFiles?.map(file => file.path))
25-
})
22+
return new TransformRunner(taskRunnerContext)
23+
}
24+
25+
class TransformRunner extends Runner<OutputResult> {
26+
private rollupOptions: RollupOptions;
27+
28+
constructor(taskRunnerContext: TaskRunnerContext) {
29+
super(taskRunnerContext);
30+
this.rollupOptions = getRollupOptions(taskRunnerContext.buildContext, taskRunnerContext)
31+
}
32+
33+
override doRun(files?: WatchChangedFile[]): Promise<OutputResult> {
34+
return runTransform(this, this.rollupOptions, files?.map(file => file.path))
35+
}
2636
}
2737

2838
async function runTransform(

‎packages/pkg/src/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ export const getBuiltInPlugins = () => [
400400
require.resolve('./plugins/component.js'),
401401
];
402402

403-
export async function parallelPromiseAll<T>(tasks: (() => Promise<T>)[], limit = 3): Promise<T[]> {
403+
export async function concurrentPromiseAll<T>(tasks: (() => Promise<T>)[], limit = 3): Promise<T[]> {
404404
const size = tasks.length
405405
const results: T[] = new Array(size)
406406
let i = 0

‎packages/pkg/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"baseUrl": "./",
55
"rootDir": "src",
66
"outDir": "lib",
7+
"noImplicitOverride": true
78
},
89
"include": ["src"]
910
}

0 commit comments

Comments
 (0)
Please sign in to comment.