Skip to content

Commit

Permalink
chore(dev): NPM package dependency analyser and removal of unused ones
Browse files Browse the repository at this point in the history
  • Loading branch information
danielweck committed Dec 20, 2024
1 parent ffec1ff commit ca69894
Show file tree
Hide file tree
Showing 12 changed files with 288 additions and 3,338 deletions.
6 changes: 0 additions & 6 deletions lerna.json

This file was deleted.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
"jest": "^29.7.0",
"json": "^11.0.0",
"json-diff": "^0.9.0",
"lerna": "^4.0.0",
"micromatch": "^4.0.8",
"mkdirp": "^1.0.4",
"rimraf": "^3.0.2",
Expand Down
4 changes: 2 additions & 2 deletions packages/ace-axe-runner-electron/src/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ const ACE_ELECTRON_HTTP_PROTOCOL = "acehttps";

// NO_HTTP_REMOVE
// const express = require('express');
// const portfinder = require('portfinder');
// const portfinder = requir_e('portfinder');
// // const http = require('http');
// const https = require('https');
// const generateSelfSignedData = require('./selfsigned').generateSelfSignedData;
// const generateSelfSignedData = requir_e('./selfsigned').generateSelfSignedData;
// let expressApp;
// let httpServer;
// let port;
Expand Down
2 changes: 1 addition & 1 deletion packages/ace-axe-runner-electron/src/selfsigned.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// NO_HTTP_REMOVE
// const selfsigned = require('selfsigned');
// const selfsigned = requir_e('selfsigned');
// const { v4: uuidv4 } = require('uuid');

// function generateSelfSignedData() {
Expand Down
2 changes: 1 addition & 1 deletion packages/ace-axe-runner-puppeteer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"main": "lib/index.js",
"dependencies": {
"@daisy/puppeteer-utils": "1.3.3-alpha.6",
"puppeteer": "^23.10.4"
"puppeteer": "^23.11.1"
},
"publishConfig": {
"access": "public"
Expand Down
1 change: 0 additions & 1 deletion packages/ace-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
"@daisy/epub-utils": "1.3.3-alpha.6",
"@daisy/axe-core-for-ace": "4.10.2-canary.2",
"file-url": "^3.0.0",
"h5o": "^0.11.3",
"p-map": "^4.0.0",
"tmp": "^0.2.3",
"winston": "^3.17.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,3 @@ function buildH5O() {
}

buildH5O();

2 changes: 1 addition & 1 deletion packages/ace-core/src/checker/checker-chromium.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ tmp.setGracefulCleanup();

const scripts = [
// require.resolve('../scripts/function-bind-bound-object.js'),
require.resolve('../scripts/vendor/outliner.min.js'),
// require.resolve('../scripts/vendor/outliner.min.js'),
path.resolve(require.resolve('@daisy/axe-core-for-ace'), '../axe.js'),
// require.resolve('../scripts/axe-patch-aria-roles.js'),
// require.resolve('../scripts/axe-patch-is-aria-role-allowed.js'),
Expand Down
2 changes: 1 addition & 1 deletion packages/jest-env-puppeteer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"main": "lib/index.js",
"dependencies": {
"jest-environment-node": "^29.7.0",
"puppeteer": "^23.10.4"
"puppeteer": "^23.11.1"
},
"publishConfig": {
"access": "public"
Expand Down
182 changes: 182 additions & 0 deletions scripts/findImportedButNonInstalledNpmPackages.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import fs from "fs";
import path from "path";

const importedNpmPackages = new Set();

const ignoreds = [
/^@daisy\/.+/,
// BUILD TOOLS not used in source code:
/^i18next-json-sync$/,
/^@jest-runner\/.+/,
/^jest.*/,
/^@kayahr\/.+/,
/^babel-.+/,
/^rimraf$/,
/^cpy-cli$/,
/^json$/,
/^json-diff$/,
/^cross-spawn$/,
/^cross-env$/,
// NODEJS built-in packages:
/^original-fs$/, // ELECTRON special
/^process$/,
/^events$/,
/^stream$/,
/^child_process$/,
/^fs$/,
/^url$/,
/^path$/,
/^util$/,
/^os$/,
/^https?$/,
/^assert$/,
/^crypto$/,
/^node:.+$/
];

const regExp_fileExt = /\.[jt]sx?$/i;
const regExp_imports = /((\s+from\s+)|(require\s*\(\s*))["']([^\.][^"']+)["']/g;

async function processDir(folderPath) {
if (path.basename(folderPath) === "node_modules") return [];
if (path.basename(folderPath) === "lib") return [];
if (path.basename(folderPath) === "report-template-assets") return [];

let packageDeps = [];

const fileNames = await fs.promises.readdir(folderPath);
for (const fileName of fileNames) {
const filePath = path.join(folderPath, fileName);
const stat = await fs.promises.stat(filePath);
const isFile = stat.isFile();
if (isFile && fileName === "package.json") {
const jsonStr = await fs.promises.readFile(filePath, {
encoding: "utf8"
});
const json = JSON.parse(jsonStr);
packageDeps = Array.from(
new Set(
packageDeps.concat(
Object.keys(json.dependencies || {}).concat(
Object.keys(json.devDependencies || {})
.concat(Object.keys(json.peerDependencies || {}))
.concat(Object.keys(json.optionalDependencies || {}))
)
)
)
);
} else if (isFile && regExp_fileExt.test(path.extname(fileName))) {
const src = await fs.promises.readFile(filePath, { encoding: "utf8" });
const matches = src.matchAll(regExp_imports);
for (const match of matches) {
// console.log("--> ", JSON.stringify(match, null, 4));
let captured = match[4];
if (!ignoreds.find(ignored => ignored.test(captured))) {
const slashIndex = captured.indexOf("/");
if (slashIndex > 0) {
if (!captured.startsWith("@")) {
captured = captured.substring(0, slashIndex);
} else {
const slashIndex2 = captured.indexOf("/", slashIndex + 1);
if (slashIndex2 > 0) {
captured = captured.substring(0, slashIndex2);
}
}
}
// if (!importedNpmPackages.has(captured)) {
// const isRequire = !!match[3];
// // const isImport = !!match[2];
// console.log("============> ", isRequire ? "REQUIRE" : "IMPORT", captured);
// }
// console.log(JSON.stringify(match, null, 4));
importedNpmPackages.add(captured);
}
// else {
// console.log("IGNORED:: ", JSON.stringify(match, null, 4));
// ignoreds.forEach((ignored) => {
// if (ignored.test(captured)) {
// console.log(">> ", ignored);
// }
// })
// }
}
} else if (stat.isDirectory()) {
packageDeps = Array.from(
new Set(packageDeps.concat(await processDir(filePath)))
);
}
}
return packageDeps;
}

let errored = false;
try {
let packageDeps = await processDir(path.join(process.cwd(), "packages"));
packageDeps = Array.from(
new Set(
packageDeps.concat(await processDir(path.join(process.cwd(), "tests")))
)
);
packageDeps = Array.from(
new Set(
packageDeps.concat(await processDir(path.join(process.cwd(), "scripts")))
)
);

const jsonStr = await fs.promises.readFile(
path.join(process.cwd(), "package.json"),
{ encoding: "utf8" }
);
const json = JSON.parse(jsonStr);
// console.log(JSON.stringify(json.dependencies, null, 4));
// console.log(JSON.stringify(json.devDpendencies, null, 4));
// console.log(JSON.stringify(json.peerDpendencies, null, 4));
const deps = packageDeps
.concat(
Array.from(
new Set(
Object.keys(json.dependencies || {}).concat(
Object.keys(json.devDependencies || {})
.concat(Object.keys(json.peerDependencies || {}))
.concat(Object.keys(json.optionalDependencies || {}))
)
)
)
)
.filter(dep => !ignoreds.find(ignored => ignored.test(dep)))
.sort();
console.log("PACKAGE DEPENDENCIES:", JSON.stringify(deps, null, 4));
console.log(
"PACKAGE IMPORTS:",
JSON.stringify(Array.from(importedNpmPackages).sort(), null, 4)
);
for (const importedNpmPackage of importedNpmPackages) {
if (!deps.find(dep => dep === importedNpmPackage)) {
console.error(
"!!!!!!!!! Package import'ed/require'd but not in package.json dependencies:",
importedNpmPackage
);
errored = true;
}
}
for (const dep of deps) {
if (!importedNpmPackages.has(dep)) {
console.error(
"!!!!!!!!! package.json dependencies not import'ed/require'd:",
dep
);
errored = true;
}
}
} catch (err) {
console.error("ERROR!");
console.error(err);
errored = true;
}
if (errored) {
console.error(">>>>>>>>>>>>>> NOK :(");
process.exit(1);
} else {
console.log(">>>>>>>>>>>>>> OK :)");
process.exit(0);
}
2 changes: 1 addition & 1 deletion scripts/watch.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Watch files for changes and rebuild (copy from 'src/' to `lib/`) if changed
* Watch files for changes and rebuild (copy fro_m 'src/' to `lib/`) if changed
*
* Inspired from Jest’s build scripts:
* https://github.com/facebook/jest/tree/master/scripts
Expand Down
Loading

0 comments on commit ca69894

Please sign in to comment.