Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,11 @@ interface projects {
*/
match?: (stdout: string) => boolean;
/**
* Whether to skip starting the current sub-project. Default is `false`.
* Useful for sub-projects that do not need to be started.
*/
skip?: boolean;
* Whether to skip starting the current sub-project. The default value is `false`, typically used to skip sub-projects that don't need to be started.
* When the value is `true`, pruning will be performed on the specified project, meaning that this project and all its direct and indirect dependencies will not be started by the plugin.
* When the value is `only`, starting the specified project will be skipped, but no pruning will be performed, meaning that the project's direct and indirect dependencies will still be started by the plugin.
*/
skip?: boolean | 'only';
}


Expand Down
4 changes: 3 additions & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@ interface Projects {
match?: (stdout: string) => boolean;
/**
* 是否跳过当前子项目的启动,默认值为 `false`,通常用于跳过一些不需要启动的子项目。
* 当值为 `true` 时,会从指定项目进行剪枝,这意味着该项目以及他的所有直接和间接依赖都不会被插件启动。
* 当值为 `only` 时,会跳过指定项目的启动,但不会进行剪枝,这意味着该项目的直接和间接依赖仍然会被插件启动。
*/
skip?: boolean;
skip?: boolean | 'only';
}

// 例如,配置 lib1 子项目,用 build:watch 命令启动,匹配 watch success 日志
Expand Down
2 changes: 1 addition & 1 deletion src/constant.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const PACKAGE_JSON = 'package.json';
export const DEBUG_LOG_TITLE = '[Rsbuild Workspace Dev Plugin]: ';
export const PLUGIN_LOG_TITLE = '[Rsbuild Workspace Dev Plugin]: ';

export const RSLIB_READY_MESSAGE = 'build complete, watching for changes';
export const MODERN_MODULE_READY_MESSAGE = 'Watching for file changes';
Expand Down
6 changes: 3 additions & 3 deletions src/logger.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import chalk from 'chalk';
import { DEBUG_LOG_TITLE } from './constant.js';
import { PLUGIN_LOG_TITLE } from './constant.js';
import { isDebug } from './utils.js';

enum LogType {
Expand All @@ -26,7 +26,7 @@ export class Logger {
this.name = name;
this.stdout = '';
this.stderr = '';
this.logTitle = DEBUG_LOG_TITLE;
this.logTitle = PLUGIN_LOG_TITLE;
}

appendLog(type: 'stdout' | 'stderr', log: string) {
Expand Down Expand Up @@ -71,7 +71,7 @@ export class Logger {
}
}

export const debugLog = (msg: string, prefix = DEBUG_LOG_TITLE) => {
export const debugLog = (msg: string, prefix = PLUGIN_LOG_TITLE) => {
if (isDebug) {
console.log(prefix + msg);
}
Expand Down
13 changes: 13 additions & 0 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,20 @@ export function pluginWorkspaceDev(
cwd: rootPath,
...options,
});
await runner.init();
await runner.start();
Logger.setEndBanner();
});

api.onBeforeBuild(async ({ isWatch, isFirstCompile }) => {
if (!isWatch || !isFirstCompile) {
return;
}

const runner = new WorkspaceDevRunner({
cwd: rootPath,
...options,
});
await runner.init();
await runner.start();
Logger.setEndBanner();
Expand Down
43 changes: 29 additions & 14 deletions src/workspace-dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import graphlib, { Graph } from 'graphlib';
import path from 'path';

import {
DEBUG_LOG_TITLE,
MODERN_MODULE_READY_MESSAGE,
PACKAGE_JSON,
PLUGIN_LOG_TITLE,
RSLIB_READY_MESSAGE,
TSUP_READY_MESSAGE,
} from './constant.js';
Expand All @@ -27,7 +27,7 @@ export interface WorkspaceDevRunnerOptions {
{
match?: (stdout: string) => boolean;
command?: string;
skip?: boolean;
skip?: boolean | 'only';
}
>;
startCurrent?: boolean;
Expand Down Expand Up @@ -86,6 +86,10 @@ export class WorkspaceDevRunner {
packageJson,
path: dir,
};
const skip = this.options.projects?.[name]?.skip;
if (skip === true) {
return;
}
this.graph.setNode(name, node);
this.visited[name] = false;
this.visiting[name] = false;
Expand All @@ -103,14 +107,21 @@ export class WorkspaceDevRunner {
(p) => p.packageJson.name === depName,
);

const skip = this.options.projects?.[depName]?.skip;
if (isInternalDep) {
this.graph.setEdge(packageName, depName);
this.checkGraph();
const depPackage = packages.find(
(pkg) => pkg.packageJson.name === depName,
)!;
if (!this.getNode(depName)) {
initNode(depPackage);
if (skip !== true) {
this.graph.setEdge(packageName, depName);
this.checkGraph();
const depPackage = packages.find(
(pkg) => pkg.packageJson.name === depName,
)!;
if (!this.getNode(depName)) {
initNode(depPackage);
}
} else {
debugLog(
`Prune project ${depName} and its dependencies because it is marked as skip: true`,
);
}
}
}
Expand All @@ -122,10 +133,13 @@ export class WorkspaceDevRunner {
checkGraph() {
const cycles = graphlib.alg.findCycles(this.graph);
const nonSelfCycles = cycles.filter((c) => c.length !== 1);
debugLog(`cycles check: ${cycles}`);
if (nonSelfCycles.length) {
const nonSkipCycles = nonSelfCycles.filter((group) => {
const isSkip = group.some((node) => this.options.projects?.[node]?.skip);
return !isSkip;
});
if (nonSkipCycles.length) {
throw new Error(
`${DEBUG_LOG_TITLE}Dependency graph do not allow cycles.`,
`${PLUGIN_LOG_TITLE} Cycle dependency graph found: ${nonSkipCycles}, you should config projects in plugin options to skip someone, or fix the cycle dependency. Otherwise, a loop of dev will occur.`,
);
}
}
Expand All @@ -143,7 +157,8 @@ export class WorkspaceDevRunner {
const canStart = dependencies.every((dep) => {
const selfStart = node === dep;
const isVisiting = this.visiting[dep];
const isVisited = selfStart || this.visited[dep];
const skipDep = this.options.projects?.[dep]?.skip;
const isVisited = selfStart || this.visited[dep] || skipDep;
return isVisited && !isVisiting;
});

Expand All @@ -167,7 +182,7 @@ export class WorkspaceDevRunner {
this.visited[node] = true;
this.visiting[node] = false;
debugLog(`Skip visit node: ${node}`);
logger.emitLogOnce('stdout', `skip visit node: ${name}`);
logger.emitLogOnce('stdout', `Skip visit node: ${name}`);
return this.start().then(() => resolve());
}
this.visiting[node] = true;
Expand Down