【发布时间】:2019-09-05 10:15:44
【问题描述】:
我有一个复杂的 NodeJS 应用程序,由几个 yarn 工作区包组成。以下 gulpconfig.ts 文件为整个包集定义了一个 gulp 构建任务:
import { series, parallel, TaskFunction, src, dest } from 'gulp';
import gulpTslint from 'gulp-tslint';
import { createProject } from 'gulp-typescript';
import tslint, { Linter } from 'tslint';
import { resolve } from 'path';
import { DestOptions } from 'vinyl-fs';
import { exec } from 'child_process';
import { promisify } from 'util';
const execPromise = promisify(exec);
interface GulpTasks {
[key: string]: TaskFunction;
}
type TaskFunctionCallback = (error?: any) => void;
class Project {
public projectFiles: NodeJS.ReadWriteStream;
public constructor(
public readonly projectDirectory: string,
public readonly sourcemaps: boolean = false,
) {
this.projectFiles = src('./src/**/*.ts', { cwd: projectDirectory, sourcemaps });
}
public lint(): this {
this.projectFiles = this.projectFiles.pipe(
gulpTslint({
tslint,
configuration: resolve(__dirname, 'tslint.json'),
program: Linter.createProgram(
resolve(this.projectDirectory, 'tsconfig.json'),
this.projectDirectory,
),
}),
);
return this;
}
public build(): this {
const opts: DestOptions = {};
if (this.sourcemaps) {
opts.sourcemaps = true;
}
this.projectFiles = this.projectFiles
.pipe(createProject(resolve(this.projectDirectory, 'tsconfig.build.json'))())
.pipe(dest(resolve(this.projectDirectory, 'dist'), opts));
return this;
}
}
const buildDatabase = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
new Project(resolve(__dirname, 'server/database')).build().projectFiles;
const buildSharedCommon = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
new Project(resolve(__dirname, 'shared/common')).lint().build().projectFiles;
const buildSharedFrontoffice = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
new Project(resolve(__dirname, 'shared/frontoffice')).lint().build().projectFiles;
const buildSharedBackoffice = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
new Project(resolve(__dirname, 'shared/backoffice')).lint().build().projectFiles;
const buildClientCommon = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
new Project(resolve(__dirname, 'client/common')).lint().build().projectFiles;
const buildClientFrontoffice = async (cb: TaskFunctionCallback): Promise<unknown> =>
execPromise('yarn run build', { cwd: 'client/frontoffice' });
const buildClientBackoffice = async (cb: TaskFunctionCallback): Promise<unknown> =>
execPromise('yarn run build', { cwd: 'client/backoffice' });
const buildServerCommon = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
new Project(resolve(__dirname, 'server/common')).lint().build().projectFiles;
const buildServerFrontoffice = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
new Project(resolve(__dirname, 'server/frontoffice')).lint().build().projectFiles;
const buildServerBackoffice = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
new Project(resolve(__dirname, 'server/backoffice')).lint().build().projectFiles;
const tasks: GulpTasks = {
build: parallel(
buildDatabase,
series(
buildSharedCommon,
parallel(buildSharedBackoffice, buildSharedFrontoffice),
parallel(
series(buildClientCommon, parallel(buildClientFrontoffice, buildClientBackoffice)),
series(buildServerCommon, parallel(buildServerFrontoffice, buildServerBackoffice)),
),
),
),
};
export = tasks;
由于我的应用程序的结构,buildServerCommon 依赖于 buildDatabase。但是 buildDatabase 不依赖任何东西,并且需要很长时间,这就是为什么我与其他部分并行启动它的原因。
不过,通过上述设置,buildDatabase 可能(并且确实)在 buildServerCommon 启动之后完成。
我怎样才能使 buildServerCommon 仅在 buildDatabase 和 buildSharedCommon 之后启动,但仍让其他一切尽早启动?
基本上,在我的依赖树中:
- 我有“客户端”、“服务器”和“共享”包文件夹。
- “{client,server,shared}/common”是同一软件包文件夹中的“frontoffice”和“backoffice”软件包所必需的。
- “shared/{common,frontoffice,backoffice}”是各个包的“客户端”和“服务器”都需要的。
- “server/database”比较特殊,只存在于“server”中,是“server/common”需要的。
我尝试使用
const tasks: GulpTasks = {
build: series(
parallel(buildSharedCommon, buildDatabase),
parallel(buildServerCommon, buildSharedFrontoffice, buildSharedBackoffice),
parallel(
series(buildClientCommon, parallel(buildClientFrontoffice, buildClientBackoffice)),
parallel(buildServerFrontoffice, buildServerBackoffice),
),
),
};
但这并不是最优的,因为 buildSharedFrontoffice 和 buildSharedBackoffice 在 buildDatabase 完成之前不会被编译,并且从那里客户端也被不必要地延迟了。
【问题讨论】:
标签: node.js typescript gulp