@modern-js/monorepo-tools 1.21.5 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -38
- package/dist/js/modern/cli/new.js +0 -3
- package/dist/js/modern/commands/build.js +4 -9
- package/dist/js/modern/dag/create.js +8 -15
- package/dist/js/modern/dag/edge-manager.js +0 -10
- package/dist/js/modern/dag/operator.js +14 -57
- package/dist/js/modern/dag/task.js +0 -18
- package/dist/js/modern/dag/utils.js +13 -31
- package/dist/js/modern/features/build/index.js +8 -19
- package/dist/js/modern/features/clear/index.js +0 -1
- package/dist/js/modern/features/deploy/index.js +7 -35
- package/dist/js/modern/features/dev/cmds.js +1 -0
- package/dist/js/modern/features/dev/create-task.js +2 -13
- package/dist/js/modern/features/dev/index.js +4 -11
- package/dist/js/modern/features/dev/watch-projects-state.js +0 -19
- package/dist/js/modern/features/install/index.js +0 -12
- package/dist/js/modern/index.js +1 -2
- package/dist/js/modern/log/multi-tasks-log.js +8 -31
- package/dist/js/modern/log/time.js +0 -3
- package/dist/js/modern/log/utils.js +0 -2
- package/dist/js/modern/package/index.js +0 -8
- package/dist/js/modern/parse-config/index.js +3 -6
- package/dist/js/modern/parse-config/monorepo.js +0 -23
- package/dist/js/modern/projects/check-project-change.js +4 -16
- package/dist/js/modern/projects/get-projects-by-packages-config.js +12 -29
- package/dist/js/modern/projects/get-projects-by-workspace-file.js +0 -16
- package/dist/js/modern/projects/get-projects.js +4 -29
- package/dist/js/modern/utils/install.js +0 -2
- package/dist/js/node/cli/build-watch.js +0 -3
- package/dist/js/node/cli/build.js +0 -3
- package/dist/js/node/cli/clear.js +0 -3
- package/dist/js/node/cli/deploy.js +0 -3
- package/dist/js/node/cli/index.js +0 -12
- package/dist/js/node/cli/install.js +0 -3
- package/dist/js/node/cli/new.js +0 -7
- package/dist/js/node/commands/build-watch.js +0 -6
- package/dist/js/node/commands/build.js +2 -14
- package/dist/js/node/commands/clear.js +0 -5
- package/dist/js/node/commands/deploy.js +0 -9
- package/dist/js/node/commands/index.js +0 -10
- package/dist/js/node/commands/install.js +0 -6
- package/dist/js/node/dag/create.js +8 -17
- package/dist/js/node/dag/edge-manager.js +0 -12
- package/dist/js/node/dag/index.js +0 -4
- package/dist/js/node/dag/operator.js +14 -65
- package/dist/js/node/dag/task.js +0 -23
- package/dist/js/node/dag/utils.js +12 -39
- package/dist/js/node/features/build/index.js +8 -29
- package/dist/js/node/features/clear/index.js +0 -15
- package/dist/js/node/features/deploy/index.js +7 -53
- package/dist/js/node/features/dev/cmds.js +1 -0
- package/dist/js/node/features/dev/create-task.js +2 -22
- package/dist/js/node/features/dev/index.js +4 -19
- package/dist/js/node/features/dev/watch-projects-state.js +0 -25
- package/dist/js/node/features/install/index.js +0 -25
- package/dist/js/node/hooks/index.js +0 -2
- package/dist/js/node/index.js +2 -16
- package/dist/js/node/locale/index.js +0 -4
- package/dist/js/node/log/error.js +0 -2
- package/dist/js/node/log/multi-tasks-log.js +8 -34
- package/dist/js/node/log/time.js +0 -10
- package/dist/js/node/log/utils.js +0 -4
- package/dist/js/node/package/index.js +0 -10
- package/dist/js/node/parse-config/index.js +3 -14
- package/dist/js/node/parse-config/monorepo.js +0 -34
- package/dist/js/node/projects/check-project-change.js +4 -33
- package/dist/js/node/projects/clear-memory-files.js +0 -8
- package/dist/js/node/projects/get-projects-by-packages-config.js +12 -41
- package/dist/js/node/projects/get-projects-by-workspace-file.js +0 -36
- package/dist/js/node/projects/get-projects.js +4 -37
- package/dist/js/node/utils/install.js +0 -11
- package/dist/js/node/utils/language.js +0 -2
- package/dist/types/dag/operator.d.ts +0 -3
- package/dist/types/dag/utils.d.ts +0 -1
- package/dist/types/features/dev/index.d.ts +0 -1
- package/dist/types/index.d.ts +0 -2
- package/dist/types/projects/get-projects.d.ts +0 -1
- package/package.json +13 -36
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
import { errorLog } from "../log/error";
|
|
2
2
|
import { EdgeManager } from "./edge-manager";
|
|
3
|
+
|
|
3
4
|
/**
|
|
4
5
|
* Calculate the number of packages which must be built before we reach
|
|
5
6
|
* the furthest away "root" node
|
|
6
7
|
*/
|
|
7
|
-
|
|
8
8
|
export const calculateCriticalPaths = project => {
|
|
9
9
|
var _project$dependent;
|
|
10
|
-
|
|
11
10
|
// Return the memoized value
|
|
12
11
|
if (project.criticalPathLength !== undefined) {
|
|
13
12
|
return project.criticalPathLength;
|
|
14
|
-
}
|
|
15
|
-
|
|
13
|
+
}
|
|
16
14
|
|
|
15
|
+
// If no dependents, we are in a "root"
|
|
17
16
|
if (((_project$dependent = project.dependent) === null || _project$dependent === void 0 ? void 0 : _project$dependent.length) === 0) {
|
|
18
17
|
project.criticalPathLength = 0;
|
|
19
18
|
return project.criticalPathLength;
|
|
20
19
|
} else {
|
|
21
20
|
var _project$dependent2;
|
|
22
|
-
|
|
23
21
|
// Otherwise we are as long as the longest package + 1
|
|
24
22
|
const depsLengths = [];
|
|
25
23
|
(_project$dependent2 = project.dependent) === null || _project$dependent2 === void 0 ? void 0 : _project$dependent2.forEach(dependentProject => depsLengths.push(calculateCriticalPaths(dependentProject)));
|
|
@@ -27,16 +25,13 @@ export const calculateCriticalPaths = project => {
|
|
|
27
25
|
return project.criticalPathLength;
|
|
28
26
|
}
|
|
29
27
|
};
|
|
30
|
-
|
|
31
28
|
const _recursiveGetDependencySkipCircleDeps = node => {
|
|
32
29
|
let allDeps = [];
|
|
33
30
|
const foundDepsNameSet = new Set([node.name]);
|
|
34
31
|
let queue = [node];
|
|
35
|
-
|
|
36
32
|
while (queue.length > 0) {
|
|
37
33
|
const checkNode = queue.pop();
|
|
38
34
|
const checkNodeDeps = checkNode.dependency || [];
|
|
39
|
-
|
|
40
35
|
if (checkNodeDeps.length > 0) {
|
|
41
36
|
const willIntoQueue = checkNodeDeps.filter(dep => !foundDepsNameSet.has(dep.name));
|
|
42
37
|
allDeps = [...allDeps, ...willIntoQueue];
|
|
@@ -44,71 +39,60 @@ const _recursiveGetDependencySkipCircleDeps = node => {
|
|
|
44
39
|
queue = [...queue, ...willIntoQueue];
|
|
45
40
|
}
|
|
46
41
|
}
|
|
47
|
-
|
|
48
42
|
return allDeps;
|
|
49
43
|
};
|
|
50
|
-
|
|
51
44
|
export const recursiveGetDependency = (project, skipCircleProjects = false) => {
|
|
52
45
|
if (skipCircleProjects) {
|
|
53
46
|
return _recursiveGetDependencySkipCircleDeps(project);
|
|
54
47
|
}
|
|
55
|
-
|
|
56
48
|
const dependency = project.dependency || [];
|
|
57
49
|
let allDependency = [...dependency];
|
|
58
|
-
|
|
59
50
|
for (const dependencyProject of dependency) {
|
|
60
51
|
allDependency = [...allDependency, ...recursiveGetDependency(dependencyProject)];
|
|
61
52
|
}
|
|
62
|
-
|
|
63
53
|
return allDependency;
|
|
64
|
-
};
|
|
54
|
+
};
|
|
65
55
|
|
|
56
|
+
// 拓扑排序
|
|
66
57
|
export const sortProjects = projects => {
|
|
67
58
|
const sortedQueue = []; // 排好序的队列
|
|
68
|
-
|
|
69
59
|
let readyIntoSortedQueue = []; // 用来准备放入 sortedQueue的数组
|
|
70
|
-
|
|
71
60
|
let queue = []; // 用来存放入度为0的节点
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
61
|
+
const edgeManager = new EdgeManager();
|
|
62
|
+
// 初始化队列queue
|
|
75
63
|
for (const project of projects) {
|
|
76
|
-
edgeManager.setEdge(project);
|
|
64
|
+
edgeManager.setEdge(project);
|
|
65
|
+
// 入度为0进队列
|
|
77
66
|
// TODO 可能存在多个 dagNodeFrom === 0 的节点
|
|
78
|
-
|
|
79
67
|
if (edgeManager.getEdge(project) === 0) {
|
|
80
68
|
queue.push(project);
|
|
81
69
|
}
|
|
82
|
-
}
|
|
83
|
-
|
|
70
|
+
}
|
|
84
71
|
|
|
72
|
+
// 加入最初入度为0的节点
|
|
85
73
|
sortedQueue.push([...queue]);
|
|
86
74
|
let shiftNodesCount = 0; // 计算出队列的节点数量,用于在最后判断是否存在环/依赖循环
|
|
87
75
|
|
|
88
76
|
while (queue.length > 0) {
|
|
89
77
|
const checkNode = queue.shift();
|
|
90
78
|
shiftNodesCount++;
|
|
91
|
-
|
|
92
79
|
for (const toNode of checkNode.dependent) {
|
|
93
80
|
edgeManager.reduceOneEdge(toNode);
|
|
94
|
-
|
|
95
81
|
if (edgeManager.getEdge(toNode) === 0) {
|
|
96
82
|
readyIntoSortedQueue.push(toNode);
|
|
97
83
|
}
|
|
98
84
|
}
|
|
99
|
-
|
|
100
85
|
if (queue.length === 0 && readyIntoSortedQueue.length > 0) {
|
|
101
86
|
queue = [...readyIntoSortedQueue];
|
|
102
87
|
sortedQueue.push([...readyIntoSortedQueue]);
|
|
103
88
|
readyIntoSortedQueue = [];
|
|
104
89
|
}
|
|
105
90
|
}
|
|
106
|
-
|
|
107
91
|
if (shiftNodesCount < projects.length) {
|
|
108
92
|
errorLog('Items with a dependency loop');
|
|
109
|
-
} else {
|
|
93
|
+
} else {
|
|
94
|
+
// console.info('No dependency loop');
|
|
110
95
|
}
|
|
111
|
-
|
|
112
96
|
return sortedQueue;
|
|
113
97
|
};
|
|
114
98
|
export const findCircle = projects => {
|
|
@@ -116,11 +100,9 @@ export const findCircle = projects => {
|
|
|
116
100
|
if (project.dependencyEdge > 0) {
|
|
117
101
|
return [...circleNodes, project];
|
|
118
102
|
}
|
|
119
|
-
|
|
120
103
|
return circleNodes;
|
|
121
104
|
}, []);
|
|
122
105
|
result = result.sort((a, b) => a.dependencyEdge - b.dependencyEdge);
|
|
123
|
-
|
|
124
106
|
while (result.length > 0) {
|
|
125
107
|
const checkNode = result.shift();
|
|
126
108
|
checkNode.dependencyEdge--;
|
|
@@ -3,7 +3,6 @@ import { execa, signale } from '@modern-js/utils';
|
|
|
3
3
|
import { checkProjectChangeByGit, checkProjectChangeByContent } from "../../projects/check-project-change";
|
|
4
4
|
import { errorLog } from "../../log/error";
|
|
5
5
|
import { MultitasksLogger } from "../../log/multi-tasks-log";
|
|
6
|
-
|
|
7
6
|
const createTask = (config, taskCmds = defaultBuildCmds, taskLogger) => {
|
|
8
7
|
const {
|
|
9
8
|
rootPath,
|
|
@@ -11,38 +10,30 @@ const createTask = (config, taskCmds = defaultBuildCmds, taskLogger) => {
|
|
|
11
10
|
disableContentHash = false,
|
|
12
11
|
enableGitHash = false
|
|
13
12
|
} = config;
|
|
14
|
-
|
|
15
13
|
const task = async project => {
|
|
16
|
-
console.info('run ', project.name);
|
|
17
|
-
|
|
14
|
+
console.info('run ', project.name);
|
|
15
|
+
// const taskTimeLog = timeLog.initTimeLog({ scope: '' });
|
|
18
16
|
if (!disableContentHash) {
|
|
19
17
|
const changed = await checkProjectChangeByContent(project);
|
|
20
|
-
|
|
21
18
|
if (!changed) {
|
|
22
19
|
console.info(`${project.name} content not change, skip`);
|
|
23
20
|
return;
|
|
24
21
|
}
|
|
25
22
|
}
|
|
26
|
-
|
|
27
23
|
if (enableGitHash) {
|
|
28
24
|
const changed = await checkProjectChangeByGit(project, rootPath);
|
|
29
|
-
|
|
30
25
|
if (!changed) {
|
|
31
26
|
console.info(`${project.name} not change, skip`);
|
|
32
27
|
return;
|
|
33
28
|
}
|
|
34
|
-
|
|
35
29
|
console.info(`${project.name} have changed in git history`);
|
|
36
30
|
}
|
|
37
|
-
|
|
38
31
|
const cmd = project.extra.scripts || {};
|
|
39
|
-
|
|
40
32
|
for (const taskCmd of taskCmds) {
|
|
41
33
|
if (cmd[taskCmd]) {
|
|
42
|
-
const prefix = `run ${project.name} ${taskCmd} script`;
|
|
43
|
-
|
|
34
|
+
const prefix = `run ${project.name} ${taskCmd} script`;
|
|
35
|
+
// timeLog.startTime(taskTimeLog, prefix);
|
|
44
36
|
signale.time(prefix);
|
|
45
|
-
|
|
46
37
|
try {
|
|
47
38
|
const childProcess = execa(packageManager, [taskCmd], {
|
|
48
39
|
cwd: project.extra.path,
|
|
@@ -55,8 +46,8 @@ const createTask = (config, taskCmds = defaultBuildCmds, taskLogger) => {
|
|
|
55
46
|
label: 'BUILD: '
|
|
56
47
|
}
|
|
57
48
|
});
|
|
58
|
-
await childProcess;
|
|
59
|
-
|
|
49
|
+
await childProcess;
|
|
50
|
+
// timeLog.endTime(taskTimeLog, prefix);
|
|
60
51
|
signale.timeEnd(prefix);
|
|
61
52
|
} catch (e) {
|
|
62
53
|
errorLog(project.name, e.message);
|
|
@@ -66,10 +57,8 @@ const createTask = (config, taskCmds = defaultBuildCmds, taskLogger) => {
|
|
|
66
57
|
}
|
|
67
58
|
}
|
|
68
59
|
};
|
|
69
|
-
|
|
70
60
|
return task;
|
|
71
61
|
};
|
|
72
|
-
|
|
73
62
|
const defaultBuildCmds = ['build'];
|
|
74
63
|
export const runBuildTask = async (projectName, operator, config, taskCmds = defaultBuildCmds) => {
|
|
75
64
|
const {
|
|
@@ -79,8 +68,8 @@ export const runBuildTask = async (projectName, operator, config, taskCmds = def
|
|
|
79
68
|
withDept = false
|
|
80
69
|
} = config;
|
|
81
70
|
const taskLogger = new MultitasksLogger();
|
|
82
|
-
const task = createTask(config, taskCmds, taskLogger);
|
|
83
|
-
|
|
71
|
+
const task = createTask(config, taskCmds, taskLogger);
|
|
72
|
+
// 优先级 onlySelf > withDept、disableWithDeps
|
|
84
73
|
if (onlySelf) {
|
|
85
74
|
await task(operator.getNodeData(projectName, {
|
|
86
75
|
checkExist: true
|
|
@@ -2,25 +2,20 @@ import * as path from 'path';
|
|
|
2
2
|
import { FileSystem, JsonFile } from '@rushstack/node-core-library';
|
|
3
3
|
import { fs, yaml, execa, logger, chalk, getPnpmVersion } from '@modern-js/utils';
|
|
4
4
|
import { WORKSPACE_FILE } from "../../constants";
|
|
5
|
-
|
|
6
5
|
const createCopyMap = (rootPath, targetProject, copyProjects, deployDir) => {
|
|
7
6
|
const map = new Map();
|
|
8
|
-
|
|
9
7
|
for (const project of copyProjects) {
|
|
10
8
|
const relativePath = path.relative(rootPath, project.extra.path);
|
|
11
9
|
const targetPath = path.join(deployDir, relativePath);
|
|
12
10
|
map.set(project.extra.path, targetPath);
|
|
13
11
|
}
|
|
14
|
-
|
|
15
12
|
const targetProjectDeployPath = path.join(deployDir, 'apps/app');
|
|
16
13
|
map.set(targetProject.extra.path, targetProjectDeployPath);
|
|
17
14
|
return map;
|
|
18
15
|
};
|
|
19
|
-
|
|
20
16
|
const createCopyFromMonorepoToDeployDirFn = (monorepoDir, deployDir) => filename => {
|
|
21
17
|
const sourcePath = path.join(monorepoDir, filename);
|
|
22
18
|
const destinationPath = path.join(deployDir, filename);
|
|
23
|
-
|
|
24
19
|
if (FileSystem.exists(sourcePath)) {
|
|
25
20
|
FileSystem.copyFile({
|
|
26
21
|
sourcePath,
|
|
@@ -28,31 +23,23 @@ const createCopyFromMonorepoToDeployDirFn = (monorepoDir, deployDir) => filename
|
|
|
28
23
|
});
|
|
29
24
|
}
|
|
30
25
|
};
|
|
31
|
-
|
|
32
26
|
const checkAndUpdatePMWorkspaces = deployDir => {
|
|
33
27
|
var _pkg$workspaces;
|
|
34
|
-
|
|
35
28
|
// pnpm-workspace
|
|
36
29
|
const pnpmWp = path.join(deployDir, WORKSPACE_FILE.PNPM);
|
|
37
|
-
|
|
38
30
|
if (fs.existsSync(pnpmWp)) {
|
|
39
31
|
const pnpmWorkspace = yaml.load(fs.readFileSync(pnpmWp, 'utf-8'));
|
|
40
|
-
|
|
41
32
|
if (pnpmWorkspace.packages && Array.isArray(pnpmWorkspace.packages)) {
|
|
42
33
|
pnpmWorkspace.packages.push('apps/**');
|
|
43
34
|
}
|
|
44
|
-
|
|
45
35
|
fs.writeFileSync(pnpmWp, yaml.dump(pnpmWorkspace));
|
|
46
36
|
}
|
|
47
|
-
|
|
48
37
|
const pkgPath = path.join(deployDir, WORKSPACE_FILE.YARN);
|
|
49
38
|
const pkg = JsonFile.load(pkgPath);
|
|
50
|
-
|
|
51
39
|
if ((_pkg$workspaces = pkg.workspaces) !== null && _pkg$workspaces !== void 0 && _pkg$workspaces.packages && Array.isArray(pkg.workspaces.packages)) {
|
|
52
40
|
pkg.workspaces.packages.push('app/**');
|
|
53
41
|
}
|
|
54
42
|
};
|
|
55
|
-
|
|
56
43
|
const generatorAndCopyRequiredFiles = (rootPath, deployDir) => {
|
|
57
44
|
// copy .npmrc
|
|
58
45
|
const copy = createCopyFromMonorepoToDeployDirFn(rootPath, deployDir);
|
|
@@ -64,29 +51,23 @@ const generatorAndCopyRequiredFiles = (rootPath, deployDir) => {
|
|
|
64
51
|
copy('tsconfig.json');
|
|
65
52
|
copy('modern.config.js'); // TODO: 暂时配置,要移除
|
|
66
53
|
// lock file
|
|
67
|
-
|
|
68
54
|
copy('pnpm-lock.yaml');
|
|
69
55
|
copy('yarn.lock');
|
|
70
|
-
copy('package-lock.json');
|
|
71
|
-
// because we deploy project to 'apps' dir
|
|
56
|
+
copy('package-lock.json');
|
|
72
57
|
|
|
58
|
+
// check workspaces config and add 'apps/**',
|
|
59
|
+
// because we deploy project to 'apps' dir
|
|
73
60
|
checkAndUpdatePMWorkspaces(deployDir);
|
|
74
61
|
};
|
|
75
|
-
|
|
76
62
|
const checkAndRunDeployCommand = async (monorepoPath, targetProject, packageManager) => {
|
|
77
63
|
var _targetProject$extra;
|
|
78
|
-
|
|
79
64
|
const scripts = ((_targetProject$extra = targetProject.extra) === null || _targetProject$extra === void 0 ? void 0 : _targetProject$extra.scripts) || {};
|
|
80
|
-
|
|
81
65
|
if (scripts.deploy) {
|
|
82
66
|
var _childProcess$stdout, _childProcess$stderr;
|
|
83
|
-
|
|
84
67
|
logger.info(`The 'deploy' command for the ${targetProject.name} is detected, so 'deploy' will be executed`);
|
|
85
68
|
let runDeployCommands = ['run', 'deploy'];
|
|
86
|
-
|
|
87
69
|
if (packageManager === 'pnpm') {
|
|
88
70
|
const pnpmVersion = await getPnpmVersion();
|
|
89
|
-
|
|
90
71
|
if (pnpmVersion.startsWith('6')) {
|
|
91
72
|
runDeployCommands = ['run', 'deploy', '--filter', targetProject.name];
|
|
92
73
|
} else {
|
|
@@ -95,7 +76,6 @@ const checkAndRunDeployCommand = async (monorepoPath, targetProject, packageMana
|
|
|
95
76
|
} else if (packageManager === 'yarn') {
|
|
96
77
|
runDeployCommands = ['workspace', targetProject.name, 'run', 'deploy'];
|
|
97
78
|
}
|
|
98
|
-
|
|
99
79
|
const cwd = packageManager === 'npm' ? targetProject.extra.path : monorepoPath;
|
|
100
80
|
const childProcess = execa(packageManager, runDeployCommands, {
|
|
101
81
|
cwd,
|
|
@@ -105,16 +85,15 @@ const checkAndRunDeployCommand = async (monorepoPath, targetProject, packageMana
|
|
|
105
85
|
(_childProcess$stderr = childProcess.stderr) === null || _childProcess$stderr === void 0 ? void 0 : _childProcess$stderr.pipe(process.stderr);
|
|
106
86
|
await childProcess;
|
|
107
87
|
}
|
|
108
|
-
};
|
|
109
|
-
|
|
88
|
+
};
|
|
110
89
|
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
111
91
|
const installDependency = async (deployDir, packageManager) => {
|
|
112
92
|
// TODO: 使用公共方法替换
|
|
113
93
|
const packageJsonPath = path.join(deployDir, 'package.json');
|
|
114
94
|
const packageJson = JsonFile.load(packageJsonPath);
|
|
115
95
|
const scripts = (packageJson === null || packageJson === void 0 ? void 0 : packageJson.scripts) || {};
|
|
116
96
|
let commands = [];
|
|
117
|
-
|
|
118
97
|
if (scripts.setup) {
|
|
119
98
|
logger.info(`The 'setup' command is detected, execute '${packageManager} run setup' to start installing the dependencies`);
|
|
120
99
|
commands = ['run', 'setup'];
|
|
@@ -122,7 +101,6 @@ const installDependency = async (deployDir, packageManager) => {
|
|
|
122
101
|
logger.info(`No 'setup' command detected, execute '${packageManager} install' to start installing dependencies`);
|
|
123
102
|
commands = ['install'];
|
|
124
103
|
}
|
|
125
|
-
|
|
126
104
|
logger.log(chalk.rgb(218, 152, 92)('Install Log:\n'));
|
|
127
105
|
const childProcess = execa(packageManager, commands, {
|
|
128
106
|
stdio: 'inherit',
|
|
@@ -133,9 +111,7 @@ const installDependency = async (deployDir, packageManager) => {
|
|
|
133
111
|
});
|
|
134
112
|
await childProcess;
|
|
135
113
|
};
|
|
136
|
-
|
|
137
114
|
const excludeDirs = (filePath, dirs) => dirs.some(dir => filePath.includes(dir));
|
|
138
|
-
|
|
139
115
|
const defaultDeployPath = 'output';
|
|
140
116
|
export const deploy = async (deployProjectNames, operator, config) => {
|
|
141
117
|
const {
|
|
@@ -154,7 +130,6 @@ export const deploy = async (deployProjectNames, operator, config) => {
|
|
|
154
130
|
const copyMap = createCopyMap(rootPath, currentProject, alldeps, realDeployPath);
|
|
155
131
|
await checkAndRunDeployCommand(rootPath, currentProject, packageManager);
|
|
156
132
|
FileSystem.ensureFolder(realDeployPath);
|
|
157
|
-
|
|
158
133
|
for (const [from, to] of copyMap) {
|
|
159
134
|
// https://rushstack.io/pages/api/node-core-library.ifilesystemcopyfilesasyncoptions/
|
|
160
135
|
FileSystem.copyFiles({
|
|
@@ -162,20 +137,17 @@ export const deploy = async (deployProjectNames, operator, config) => {
|
|
|
162
137
|
destinationPath: to,
|
|
163
138
|
// If true, then when copying symlinks, copy the target object instead of copying the link.
|
|
164
139
|
dereferenceSymlinks: false,
|
|
165
|
-
|
|
166
140
|
filter(filePath) {
|
|
167
141
|
if (excludeDirs(filePath, ['node_modules', 'dist'])) {
|
|
168
142
|
return false;
|
|
169
143
|
}
|
|
170
|
-
|
|
171
144
|
return true;
|
|
172
145
|
}
|
|
173
|
-
|
|
174
146
|
});
|
|
175
147
|
}
|
|
176
148
|
}
|
|
177
|
-
|
|
178
|
-
|
|
149
|
+
generatorAndCopyRequiredFiles(rootPath, realDeployPath);
|
|
150
|
+
// await installDependency(realDeployPath, packageManager);
|
|
179
151
|
|
|
180
152
|
logger.success(`Deploy success. The deploy dir is in '${rootPath}/output'`);
|
|
181
153
|
};
|
|
@@ -2,13 +2,12 @@ import { execa, logger } from '@modern-js/utils';
|
|
|
2
2
|
import { errorLog } from "../../log/error";
|
|
3
3
|
import * as timeLog from "../../log/time";
|
|
4
4
|
import { defaultBuildWatchCmds } from "./cmds";
|
|
5
|
-
|
|
6
5
|
const getFinalTaskCmds = (taskCmds, project) => {
|
|
7
|
-
let finalTaskCmds = [];
|
|
6
|
+
let finalTaskCmds = [];
|
|
7
|
+
// case1: ["build"]
|
|
8
8
|
// case2: ["dev", "build"]
|
|
9
9
|
// case3: ["dev", () => []]
|
|
10
10
|
// default: ['dev', 'build']
|
|
11
|
-
|
|
12
11
|
if (taskCmds.length === 1) {
|
|
13
12
|
finalTaskCmds = [taskCmds[0]];
|
|
14
13
|
} else if (taskCmds.length === 2 && typeof taskCmds[0] === 'string' && typeof taskCmds[1] === 'string') {
|
|
@@ -19,25 +18,20 @@ const getFinalTaskCmds = (taskCmds, project) => {
|
|
|
19
18
|
// 如果以上为满足,则默认使用build
|
|
20
19
|
finalTaskCmds = ['build'];
|
|
21
20
|
}
|
|
22
|
-
|
|
23
21
|
return finalTaskCmds;
|
|
24
22
|
};
|
|
25
|
-
|
|
26
23
|
export const createDependenciesTask = (config, taskCmds = defaultBuildWatchCmds, taskLogger) => {
|
|
27
24
|
const {
|
|
28
25
|
packageManager
|
|
29
26
|
} = config;
|
|
30
27
|
const timelogInstance = timeLog.initTimeLog();
|
|
31
|
-
|
|
32
28
|
const task = async project => {
|
|
33
29
|
const finalTaskCmds = getFinalTaskCmds(taskCmds, project);
|
|
34
30
|
const cmd = project.extra.scripts || {};
|
|
35
|
-
|
|
36
31
|
for (const taskCmd of finalTaskCmds) {
|
|
37
32
|
if (cmd[taskCmd]) {
|
|
38
33
|
const prefix = `run ${project.name} ${taskCmd} script`;
|
|
39
34
|
timeLog.startTime(timelogInstance, prefix);
|
|
40
|
-
|
|
41
35
|
try {
|
|
42
36
|
const childProcess = execa(packageManager, [taskCmd], {
|
|
43
37
|
cwd: project.extra.path,
|
|
@@ -54,25 +48,21 @@ export const createDependenciesTask = (config, taskCmds = defaultBuildWatchCmds,
|
|
|
54
48
|
} catch (e) {
|
|
55
49
|
errorLog(project.name, e);
|
|
56
50
|
}
|
|
57
|
-
|
|
58
51
|
timeLog.endTime(timelogInstance, prefix);
|
|
59
52
|
} else {
|
|
60
53
|
logger.info(`${project.name} not have ${taskCmd}, skip it.`);
|
|
61
54
|
}
|
|
62
55
|
}
|
|
63
56
|
};
|
|
64
|
-
|
|
65
57
|
return task;
|
|
66
58
|
};
|
|
67
59
|
export const createDevTask = (config, taskCmds = defaultBuildWatchCmds, taskLogger) => {
|
|
68
60
|
const {
|
|
69
61
|
packageManager
|
|
70
62
|
} = config;
|
|
71
|
-
|
|
72
63
|
const task = async project => {
|
|
73
64
|
const devCmds = [taskCmds[0]];
|
|
74
65
|
const cmd = project.extra.scripts || {};
|
|
75
|
-
|
|
76
66
|
for (const taskCmd of devCmds) {
|
|
77
67
|
if (cmd[taskCmd]) {
|
|
78
68
|
// const prefix = `run ${project.name} ${taskCmd} script`;
|
|
@@ -100,6 +90,5 @@ export const createDevTask = (config, taskCmds = defaultBuildWatchCmds, taskLogg
|
|
|
100
90
|
}
|
|
101
91
|
}
|
|
102
92
|
};
|
|
103
|
-
|
|
104
93
|
return task;
|
|
105
94
|
};
|
|
@@ -4,22 +4,17 @@ import { MultitasksLogger } from "../../log/multi-tasks-log";
|
|
|
4
4
|
import { WatchedProjectsState } from "./watch-projects-state";
|
|
5
5
|
import { defaultBuildWatchCmds } from "./cmds";
|
|
6
6
|
import { createDependenciesTask, createDevTask } from "./create-task";
|
|
7
|
-
|
|
8
7
|
const getIgnored = config => watchFilePath => {
|
|
9
8
|
// 默认忽略 node_modules 的变化和 dist 目录下文件的变化
|
|
10
9
|
const nodeModulesPattern = /(?:^|[\\/])node_modules/g;
|
|
11
|
-
|
|
12
10
|
if (nodeModulesPattern.test(watchFilePath) || watchFilePath.includes('dist')) {
|
|
13
11
|
return true;
|
|
14
12
|
}
|
|
15
|
-
|
|
16
13
|
if (config.ignoreMaybeChanged) {
|
|
17
14
|
return anymatch(config.ignoreMaybeChanged)(watchFilePath);
|
|
18
15
|
}
|
|
19
|
-
|
|
20
16
|
return false;
|
|
21
17
|
};
|
|
22
|
-
|
|
23
18
|
export const runBuildWatchTask = async (projectName, operator, config, taskCmds = defaultBuildWatchCmds) => {
|
|
24
19
|
const {
|
|
25
20
|
needInit = true
|
|
@@ -38,14 +33,14 @@ export const runBuildWatchTask = async (projectName, operator, config, taskCmds
|
|
|
38
33
|
disableGlobbing: true,
|
|
39
34
|
interval: 1000
|
|
40
35
|
});
|
|
41
|
-
watcher.add(watchedProjectState.getWatchedProjectsPath());
|
|
36
|
+
watcher.add(watchedProjectState.getWatchedProjectsPath());
|
|
42
37
|
|
|
38
|
+
// 可能会移除该判断和 neeInit 配置
|
|
43
39
|
if (needInit) {
|
|
44
40
|
await operator.traverseDependenciesToProject(projectName, async currentProject => {
|
|
45
41
|
await dependenciesTask(currentProject);
|
|
46
42
|
});
|
|
47
43
|
}
|
|
48
|
-
|
|
49
44
|
await new Promise(resolve => {
|
|
50
45
|
console.info('start watch');
|
|
51
46
|
watcher.on('all', async (eventName, changeFilePath) => {
|
|
@@ -53,9 +48,7 @@ export const runBuildWatchTask = async (projectName, operator, config, taskCmds
|
|
|
53
48
|
if (eventName === 'add') {
|
|
54
49
|
watchedProjectState.updateState();
|
|
55
50
|
}
|
|
56
|
-
|
|
57
51
|
const changedProject = watchedProjectState.getChangedProject(changeFilePath);
|
|
58
|
-
|
|
59
52
|
if (changedProject) {
|
|
60
53
|
await operator.traverseProjectToDependent(changedProject.name, async (currentProject, _, earlyFinish) => {
|
|
61
54
|
// 调试的项目跳过
|
|
@@ -63,7 +56,6 @@ export const runBuildWatchTask = async (projectName, operator, config, taskCmds
|
|
|
63
56
|
earlyFinish();
|
|
64
57
|
return;
|
|
65
58
|
}
|
|
66
|
-
|
|
67
59
|
if (watchedProjectState.watchProjectsName.includes(currentProject.name)) {
|
|
68
60
|
console.info('run build', currentProject.name);
|
|
69
61
|
await dependenciesTask(currentProject);
|
|
@@ -77,8 +69,9 @@ export const runBuildWatchTask = async (projectName, operator, config, taskCmds
|
|
|
77
69
|
}
|
|
78
70
|
});
|
|
79
71
|
resolve(null);
|
|
80
|
-
});
|
|
72
|
+
});
|
|
81
73
|
|
|
74
|
+
// 执行目标项目的 dev 任务
|
|
82
75
|
await devTask(operator.getNodeData(projectName, {
|
|
83
76
|
checkExist: true
|
|
84
77
|
}));
|
|
@@ -1,29 +1,20 @@
|
|
|
1
1
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
2
|
-
|
|
3
2
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
4
|
-
|
|
5
3
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
6
|
-
|
|
7
4
|
import * as path from 'path';
|
|
8
5
|
import { globby } from '@modern-js/utils';
|
|
9
6
|
export class WatchedProjectsState {
|
|
10
7
|
constructor(fromNodes, config) {
|
|
11
8
|
_defineProperty(this, "_config", void 0);
|
|
12
|
-
|
|
13
9
|
_defineProperty(this, "_fromNodes", void 0);
|
|
14
|
-
|
|
15
10
|
_defineProperty(this, "_watchProjects", void 0);
|
|
16
|
-
|
|
17
11
|
_defineProperty(this, "_projectsFileMap", void 0);
|
|
18
|
-
|
|
19
12
|
this._fromNodes = fromNodes;
|
|
20
13
|
this._config = config;
|
|
21
14
|
this._projectsFileMap = new Map();
|
|
22
15
|
this._watchProjects = {};
|
|
23
|
-
|
|
24
16
|
this._initState();
|
|
25
17
|
}
|
|
26
|
-
|
|
27
18
|
_initState() {
|
|
28
19
|
const globOption = {
|
|
29
20
|
cwd: this._config.rootPath,
|
|
@@ -34,41 +25,31 @@ export class WatchedProjectsState {
|
|
|
34
25
|
};
|
|
35
26
|
this._watchProjects = this._fromNodes.reduce((ret, node) => {
|
|
36
27
|
const files = globby.sync(`${node.extra.path}/**`, globOption);
|
|
37
|
-
|
|
38
28
|
for (const filePath of files) {
|
|
39
29
|
this._projectsFileMap.set(path.relative(this._config.rootPath, filePath), node.extra.path);
|
|
40
30
|
}
|
|
41
|
-
|
|
42
31
|
return _objectSpread(_objectSpread({}, ret), {}, {
|
|
43
32
|
[node.extra.path]: node
|
|
44
33
|
});
|
|
45
34
|
}, {});
|
|
46
35
|
}
|
|
47
|
-
|
|
48
36
|
getChangedProject(changedFilPath) {
|
|
49
37
|
if (this._projectsFileMap.has(changedFilPath)) {
|
|
50
38
|
const projectPath = this._projectsFileMap.get(changedFilPath);
|
|
51
|
-
|
|
52
39
|
return this._watchProjects[projectPath];
|
|
53
40
|
}
|
|
54
|
-
|
|
55
41
|
return undefined;
|
|
56
42
|
}
|
|
57
|
-
|
|
58
43
|
getWatchedProjectsPath() {
|
|
59
44
|
return Object.keys(this._watchProjects);
|
|
60
45
|
}
|
|
61
|
-
|
|
62
46
|
updateState() {
|
|
63
47
|
this._initState();
|
|
64
48
|
}
|
|
65
|
-
|
|
66
49
|
get watchProjects() {
|
|
67
50
|
return this._watchProjects;
|
|
68
51
|
}
|
|
69
|
-
|
|
70
52
|
get watchProjectsName() {
|
|
71
53
|
return Object.keys(this._watchProjects).map(projectPath => this._watchProjects[projectPath].name);
|
|
72
54
|
}
|
|
73
|
-
|
|
74
55
|
}
|
|
@@ -3,14 +3,12 @@ import { fs, yaml } from '@modern-js/utils';
|
|
|
3
3
|
import { JsonFile } from '@rushstack/node-core-library';
|
|
4
4
|
import { WORKSPACE_FILE } from "../../constants";
|
|
5
5
|
import { installByPackageManager } from "../../utils/install";
|
|
6
|
-
|
|
7
6
|
const replaceWorkspaces = ({
|
|
8
7
|
rootPath,
|
|
9
8
|
projectsInWorkspaces
|
|
10
9
|
}) => {
|
|
11
10
|
// pnpm
|
|
12
11
|
const pnpmWsFilePath = path.join(rootPath, WORKSPACE_FILE.PNPM);
|
|
13
|
-
|
|
14
12
|
if (fs.existsSync(pnpmWsFilePath)) {
|
|
15
13
|
const pnpmWorkspace = fs.readFileSync(pnpmWsFilePath, 'utf-8');
|
|
16
14
|
const originalPnpmWorkspaces = yaml.load(pnpmWorkspace);
|
|
@@ -21,14 +19,10 @@ const replaceWorkspaces = ({
|
|
|
21
19
|
yaml.dump(originalPnpmWorkspaces);
|
|
22
20
|
};
|
|
23
21
|
}
|
|
24
|
-
|
|
25
22
|
const pkgFilePath = path.join(rootPath, WORKSPACE_FILE.YARN);
|
|
26
|
-
|
|
27
23
|
if (fs.existsSync(pkgFilePath)) {
|
|
28
24
|
var _pkg$workspaces;
|
|
29
|
-
|
|
30
25
|
const pkg = JsonFile.load(pkgFilePath);
|
|
31
|
-
|
|
32
26
|
if (pkg !== null && pkg !== void 0 && (_pkg$workspaces = pkg.workspaces) !== null && _pkg$workspaces !== void 0 && _pkg$workspaces.packages) {
|
|
33
27
|
const originalPkg = pkg;
|
|
34
28
|
pkg.workspaces.packages = projectsInWorkspaces;
|
|
@@ -38,27 +32,22 @@ const replaceWorkspaces = ({
|
|
|
38
32
|
};
|
|
39
33
|
}
|
|
40
34
|
}
|
|
41
|
-
|
|
42
35
|
return false;
|
|
43
36
|
};
|
|
44
|
-
|
|
45
37
|
export const runInstallTask = async (projectNames, operator, config) => {
|
|
46
38
|
const {
|
|
47
39
|
rootPath,
|
|
48
40
|
packageManager
|
|
49
41
|
} = config;
|
|
50
42
|
let projectsInWorkspaces = [];
|
|
51
|
-
|
|
52
43
|
if (projectNames.length === 0) {
|
|
53
44
|
console.info('install all projects');
|
|
54
45
|
return;
|
|
55
46
|
}
|
|
56
|
-
|
|
57
47
|
for (const projectName of projectNames) {
|
|
58
48
|
const allDeps = operator.getNodeAllDependencyData(projectName);
|
|
59
49
|
projectsInWorkspaces = [...projectsInWorkspaces, path.relative(rootPath, operator.getNodeData(projectName).extra.path), ...allDeps.map(p => path.relative(rootPath, p.extra.path))];
|
|
60
50
|
}
|
|
61
|
-
|
|
62
51
|
const noDupProjectList = Array.from(new Set(projectsInWorkspaces));
|
|
63
52
|
const restorWorkspace = replaceWorkspaces({
|
|
64
53
|
rootPath,
|
|
@@ -68,7 +57,6 @@ export const runInstallTask = async (projectNames, operator, config) => {
|
|
|
68
57
|
rootPath,
|
|
69
58
|
removeLock: true
|
|
70
59
|
});
|
|
71
|
-
|
|
72
60
|
if (restorWorkspace) {
|
|
73
61
|
restorWorkspace();
|
|
74
62
|
}
|