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
1 change: 0 additions & 1 deletion src/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ export const PACKAGE_JSON = 'package.json';
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';
export const TSUP_READY_MESSAGE = 'Watching for changes in';
7 changes: 7 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { Package } from '@manypkg/get-packages';

export interface PackageWithScripts extends Package {
packageJson: Package['packageJson'] & {
scripts?: Record<string, string>;
};
}
7 changes: 4 additions & 3 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { Package } from '@manypkg/get-packages';
import fs from 'fs';
import json5 from 'json5';

import type { PackageWithScripts } from './types.js';

async function pathExists(path: string) {
return fs.promises
.access(path)
Expand All @@ -21,8 +22,8 @@ export const readJson = async <T>(jsonFileAbsPath: string): Promise<T> => {

export const readPackageJson = async (
pkgJsonFilePath: string,
): Promise<Package['packageJson']> => {
return readJson<Package['packageJson']>(pkgJsonFilePath);
): Promise<PackageWithScripts['packageJson']> => {
return readJson<PackageWithScripts['packageJson']>(pkgJsonFilePath);
};

export const isDebug =
Expand Down
43 changes: 20 additions & 23 deletions src/workspace-dev.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import { getPackagesSync, type Package } from '@manypkg/get-packages';
import { getPackagesSync } from '@manypkg/get-packages';
import { spawn } from 'child_process';
import graphlib, { Graph } from 'graphlib';
import path from 'path';

import { join } from 'path';
import {
MODERN_MODULE_READY_MESSAGE,
PACKAGE_JSON,
PLUGIN_LOG_TITLE,
RSLIB_READY_MESSAGE,
TSUP_READY_MESSAGE,
} from './constant.js';
import { debugLog, Logger } from './logger.js';
import type { PackageWithScripts } from './types.js';
import { readPackageJson } from './utils.js';

interface GraphNode {
name: string;
packageJson: Package['packageJson'];
packageJson: PackageWithScripts['packageJson'];
path: string;
}

Expand All @@ -37,12 +36,12 @@ export class WorkspaceDevRunner {
private options: WorkspaceDevRunnerOptions;
private cwd: string;
private workspaceFileDir: string;
private packages: Package[] = [];
private packages: PackageWithScripts[] = [];
private graph: Graph;
private visited: Record<string, boolean>;
private visiting: Record<string, boolean>;
private matched: Record<string, boolean>;
private metaData!: Package['packageJson'];
private metaData!: PackageWithScripts['packageJson'];

constructor(options: WorkspaceDevRunnerOptions) {
this.options = {
Expand All @@ -59,7 +58,7 @@ export class WorkspaceDevRunner {
}

async init(): Promise<void> {
this.metaData = await readPackageJson(path.join(this.cwd, PACKAGE_JSON));
this.metaData = await readPackageJson(join(this.cwd, PACKAGE_JSON));
this.buildDependencyGraph();
debugLog(
'Dependency graph:\n' +
Expand All @@ -77,7 +76,7 @@ export class WorkspaceDevRunner {
)!;
this.packages = packages;

const initNode = (pkg: Package) => {
const initNode = (pkg: PackageWithScripts) => {
const { packageJson, dir } = pkg;
const { name, dependencies, devDependencies, peerDependencies } =
packageJson;
Expand Down Expand Up @@ -173,12 +172,15 @@ export class WorkspaceDevRunner {

visitNodes(node: string): Promise<void> {
return new Promise((resolve) => {
const { name, path } = this.getNode(node);
const { name, path, packageJson } = this.getNode(node);
const logger = new Logger({
name,
});

const config = this.options?.projects?.[name];
if (config?.skip) {
const command = config?.command ? config.command : 'dev';
const scripts = packageJson.scripts || {};
if (config?.skip || !scripts[command]) {
this.visited[node] = true;
this.visiting[node] = false;
debugLog(`Skip visit node: ${node}`);
Expand All @@ -187,18 +189,14 @@ export class WorkspaceDevRunner {
}
this.visiting[node] = true;

const child = spawn(
'npm',
['run', config?.command ? config.command : 'dev'],
{
cwd: path,
env: {
...process.env,
FORCE_COLOR: '3',
},
shell: true,
const child = spawn('npm', ['run', command], {
cwd: path,
env: {
...process.env,
FORCE_COLOR: '3',
},
);
shell: true,
});

child.stdout.on('data', async (data) => {
const stdout = data.toString();
Expand All @@ -213,7 +211,6 @@ export class WorkspaceDevRunner {
const matchResult = match
? match(stdout)
: stdout.match(RSLIB_READY_MESSAGE) ||
stdout.match(MODERN_MODULE_READY_MESSAGE) ||
stdout.match(TSUP_READY_MESSAGE);

if (matchResult) {
Expand Down