Skip to content

Commit 51f375c

Browse files
PRoIISHAANIishaan Tanwarnemesifier
authored
[fix] Remove unused dependencies, add check to run-qa-checks #484
Closes #484 --------- Co-authored-by: Iishaan Tanwar <iishaantanwar@MacBook-Air-3.local> Co-authored-by: Federico Capoano <f.capoano@openwisp.io>
1 parent 7e42d6b commit 51f375c

File tree

9 files changed

+2405
-2623
lines changed

9 files changed

+2405
-2623
lines changed

.github/workflows/ci.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ jobs:
1818
with:
1919
ref: ${{ github.event.pull_request.head.sha }}
2020

21+
- name: Set up Node.js
22+
uses: actions/setup-node@v6
23+
with:
24+
node-version-file: ".nvmrc"
25+
2126
- name: Get yarn cache directory path
2227
id: yarn-cache-dir-path
2328
run: echo "::set-output name=dir::$(yarn cache dir)"
@@ -50,6 +55,11 @@ jobs:
5055
steps:
5156
- uses: actions/checkout@v6
5257

58+
- name: Set up Node.js
59+
uses: actions/setup-node@v6
60+
with:
61+
node-version-file: ".nvmrc"
62+
5363
- name: Get yarn cache directory path
5464
id: yarn-cache-dir-path
5565
run: echo "::set-output name=dir::$(yarn cache dir)"

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
lts/krypton

knip.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"$schema": "https://unpkg.com/knip@5/schema.json",
3+
"project": ["src/**/*.js", "test/**/*.js"],
4+
"ignore": ["examples/**", "lib/js/**", "public/**", "scripts/**"],
5+
"ignoreBinaries": ["wait-on"]
6+
}

lib/js/echarts-gl.min.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "netjsongraph.js",
33
"version": "0.3.0",
44
"description": "NetJSON NetworkGraph visualizer",
5-
"main": "index.js",
5+
"main": "src/js/netjsongraph.js",
66
"scripts": {
77
"test": "jest --silent",
88
"dev": "webpack serve --open --mode development",
@@ -55,7 +55,6 @@
5555
"@babel/preset-env": "^7.23.9",
5656
"@testing-library/jest-dom": "^6.4.2",
5757
"@types/jest": "^30.0.0",
58-
"acorn": "^8.11.3",
5958
"copy-webpack-plugin": "^13.0.0",
6059
"coveralls": "^3.1.1",
6160
"css-loader": "^7.1.2",
@@ -67,15 +66,16 @@
6766
"eslint-plugin-jsx-a11y": "^6.8.0",
6867
"eslint-plugin-react": "^7.33.2",
6968
"html-webpack-plugin": "^5.6.0",
70-
"husky": "^9.0.11",
7169
"identity-obj-proxy": "^3.0.0",
7270
"jest": "^30.0.3",
7371
"jest-environment-jsdom": "^30.0.5",
72+
"knip": "^5.81.0",
7473
"lint-staged": "^16.1.0",
7574
"prettier": "^3.6.2",
7675
"selenium-webdriver": "^4.29.0",
7776
"style-loader": "^4.0.0",
7877
"terser-webpack-plugin": "^5.3.10",
78+
"typescript": "^5.9.3",
7979
"webpack": "^5.90.3",
8080
"webpack-cli": "^6.0.1",
8181
"webpack-dev-server": "^5.0.2"

public/example_templates/netjsonmap-indoormap-overlay.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@
151151
},
152152
});
153153
netjsonmap.render();
154+
// needed for selenium tests
154155
window._geoMap = netjsonmap;
155156

156157
function createIndoorMapContainer() {

run-qa-checks

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ openwisp-qa-check --skip-checkmigrations \
1515
--skip-checkendline \
1616
--csslinter \
1717
--jslinter
18+
19+
node scripts/ci-knip.js

scripts/ci-knip.js

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
const {execSync} = require("child_process");
2+
3+
function parseAndReportKnipResults(result) {
4+
const issues = {
5+
dependencies: new Set(),
6+
devDependencies: new Set(),
7+
unresolved: new Set(),
8+
unusedFiles: new Set(),
9+
unusedExports: [],
10+
};
11+
12+
let hasIssues = false;
13+
14+
// Check for unused files
15+
if (result.files && result.files.length > 0) {
16+
result.files.forEach((file) => issues.unusedFiles.add(file));
17+
hasIssues = true;
18+
}
19+
20+
// Parse each file's issues
21+
if (result.issues && result.issues.length > 0) {
22+
result.issues.forEach((fileIssue) => {
23+
if (fileIssue.dependencies && fileIssue.dependencies.length > 0) {
24+
fileIssue.dependencies.forEach((dep) => issues.dependencies.add(dep));
25+
hasIssues = true;
26+
}
27+
if (fileIssue.devDependencies && fileIssue.devDependencies.length > 0) {
28+
fileIssue.devDependencies.forEach((dep) => issues.devDependencies.add(dep));
29+
hasIssues = true;
30+
}
31+
if (fileIssue.unresolved && fileIssue.unresolved.length > 0) {
32+
fileIssue.unresolved.forEach((item) => issues.unresolved.add(item.name));
33+
hasIssues = true;
34+
}
35+
if (fileIssue.exports && fileIssue.exports.length > 0) {
36+
fileIssue.exports.forEach((exp) => {
37+
issues.unusedExports.push({
38+
file: fileIssue.file,
39+
name: exp.name,
40+
});
41+
});
42+
hasIssues = true;
43+
}
44+
});
45+
}
46+
47+
if (hasIssues) {
48+
console.error("❌ Knip found issues:\n");
49+
if (issues.dependencies.size > 0) {
50+
console.error("Unused dependencies:");
51+
Array.from(issues.dependencies)
52+
.sort()
53+
.forEach((d) => console.error(` - ${d.name}`));
54+
console.error("");
55+
}
56+
if (issues.devDependencies.size > 0) {
57+
console.error("Unused devDependencies:");
58+
Array.from(issues.devDependencies)
59+
.sort()
60+
.forEach((d) => console.error(` - ${d.name}`));
61+
console.error("");
62+
}
63+
if (issues.unresolved.size > 0) {
64+
console.error("Unresolved imports:");
65+
Array.from(issues.unresolved)
66+
.sort()
67+
.forEach((d) => console.error(` - ${d}`));
68+
console.error("");
69+
}
70+
if (issues.unusedFiles.size > 0) {
71+
console.error("Unused files:");
72+
Array.from(issues.unusedFiles)
73+
.sort()
74+
.forEach((f) => console.error(` - ${f}`));
75+
console.error("");
76+
}
77+
if (issues.unusedExports.length > 0) {
78+
console.error("Unused exports:");
79+
issues.unusedExports
80+
.sort((a, b) => a.file.localeCompare(b.file))
81+
.forEach((exp) => console.error(` - ${exp.name} (${exp.file})`));
82+
console.error("");
83+
}
84+
return true; // has issues
85+
}
86+
return false; // no issues
87+
}
88+
89+
try {
90+
const output = execSync("npx knip --reporter json", {
91+
encoding: "utf-8",
92+
stdio: ["pipe", "pipe", "pipe"],
93+
});
94+
const result = JSON.parse(output);
95+
const hasIssues = parseAndReportKnipResults(result);
96+
if (hasIssues) {
97+
process.exit(1);
98+
}
99+
console.log("✅ Knip passed: no issues found");
100+
} catch (error) {
101+
if (error.stdout) {
102+
try {
103+
const result = JSON.parse(error.stdout);
104+
parseAndReportKnipResults(result);
105+
} catch (parseError) {
106+
console.error("❌ Knip failed (could not parse JSON output):");
107+
console.error(error.message);
108+
}
109+
} else {
110+
console.error("❌ Knip failed:");
111+
console.error(error.message);
112+
}
113+
process.exit(1);
114+
}

0 commit comments

Comments
 (0)