forked from teambit/bit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfind-unused-packages.js
90 lines (83 loc) · 3.17 KB
/
find-unused-packages.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
const fs = require('fs-extra');
const globby = require('globby');
const { parse } = require('comment-json');
const pkgJson = require('../package.json');
const allDeps = [...Object.keys(pkgJson.dependencies), ...Object.keys(pkgJson.devDependencies)];
const workspaceJson = fs.readFileSync(`${__dirname}/../workspace.jsonc`, 'utf8');
const workspaceJsonParsed = parse(workspaceJson);
const policy = workspaceJsonParsed['teambit.dependencies/dependency-resolver'].policy;
const workspacePackages = [...Object.keys(policy.dependencies), ...Object.keys(policy.peerDependencies)];
const sourceCode = ['src', 'scopes', 'e2e'];
const sourceCodeAbs = sourceCode.map((dir) => `${__dirname}/../${dir}`);
const sourceFiles = globby.sync(sourceCodeAbs);
let unused = [...allDeps];
let unusedWorkspace = [...workspacePackages];
const used = [];
// these are not mentioned in the code, but still needed
const whitelist = [
'pino-pretty', // needed for the logger. (although it has no import/require in the code)
'regenerator-runtime',
'babel-plugin-ramda',
'eslint-plugin-mocha',
'eslint-plugin-promise',
'gh-release',
'mocha-circleci-reporter',
'mocha-junit-reporter',
'prettier-eslint',
'type-coverage',
'@yarnpkg/plugin-pack',
'graceful-fs', // might be used as a peer by other stuff
'mz', // needs to check what happens if gets removed.
'npm', // needed for e2e tests
'cross-env', // needed for e2e tests on Windows
'@typescript-eslint/typescript-estree', // required for @typescript-eslint/parser in .eslintrc.js
];
used.push(...whitelist);
unused = unused.filter((dep) => !whitelist.includes(dep));
unusedWorkspace = unusedWorkspace.filter((dep) => !whitelist.includes(dep));
const isDepUsed = (content, dep) =>
content.includes(`'${dep}'`) ||
content.includes(`"${dep}"`) ||
content.includes(`'${dep}/`) ||
content.includes(`"${dep}/`);
sourceFiles.forEach((file) => {
const content = fs.readFileSync(file, 'utf8');
unused.forEach((dep) => {
if (isDepUsed(content, dep)) {
console.log('! found ', dep);
unused = unused.filter((d) => d !== dep);
used.push(dep);
}
});
unusedWorkspace.forEach((dep) => {
if (isDepUsed(content, dep)) {
console.log('! found ', dep);
unusedWorkspace = unusedWorkspace.filter((d) => d !== dep);
used.push(dep);
}
});
});
unused.forEach((dep) => {
if (dep.startsWith('@types/')) {
const pkg = dep.replace('@types/', '');
if (used.includes(pkg)) {
unused = unused.filter((d) => d !== dep);
used.push(dep);
}
}
});
unusedWorkspace.forEach((dep) => {
if (dep.startsWith('@types/')) {
const pkg = dep.replace('@types/', '');
if (used.includes(pkg)) {
unusedWorkspace = unusedWorkspace.filter((d) => d !== dep);
used.push(dep);
}
}
});
console.log('[-] unused packages in package.json', unused);
console.log('[-] unused packages in workspace.jsonc', unusedWorkspace);
console.log('[-] total packages', allDeps.length + workspacePackages.length);
console.log('[-] total packages in use:', used.length);
console.log('[-] total packages in package.json not in use:', unused.length);
console.log('[-] total packages in workspace.jsonc not in use:', unusedWorkspace.length);