diff --git a/cspell.json b/cspell.json
index a33d89adf..4eef9272b 100644
--- a/cspell.json
+++ b/cspell.json
@@ -147,6 +147,7 @@
"Kearney",
"keyof",
"Khatri",
+ "knip",
"Konstantin",
"l’objectif",
"layed",
diff --git a/knip.config.js b/knip.config.js
new file mode 100644
index 000000000..c51d9c146
--- /dev/null
+++ b/knip.config.js
@@ -0,0 +1,40 @@
+export default {
+ workspaces: {
+ ".": {
+ entry: ["src/plugins/*", "scripts/**"],
+ project: ["src/**", "scripts/**"],
+ ignore: [
+ "scripts/build/config.js",
+ "scripts/build/build-javascript-module.js",
+ "scripts/tools/**",
+ ],
+ ignoreDependencies: [
+ "eslint-formatter-friendly",
+ "ts-expect",
+ "renovate",
+ ],
+ ignoreBinaries: ["test-coverage", "renovate-config-validator"],
+ },
+ website: {
+ entry: [
+ "siteConfig.js",
+ "core/Footer.js",
+ "pages/**/*.js",
+ "static/**/*.js",
+ ],
+ ignoreDependencies: [
+ "docusaurus",
+ "codemirror",
+ "highlight.js",
+ "@babel/preset-react",
+ ],
+ ignoreBinaries: ["docusaurus-build", "docusaurus-version"],
+ ignore: ["pages/en/**"],
+ },
+ "scripts/tools/bundle-test": {},
+ "scripts/tools/eslint-plugin-prettier-internal-rules": {},
+ "scripts/release": {
+ entry: ["release.js"],
+ },
+ },
+};
diff --git a/package.json b/package.json
index abafe1690..804092484 100644
--- a/package.json
+++ b/package.json
@@ -89,6 +89,7 @@
"postcss-scss": "4.0.9",
"postcss-selector-parser": "2.2.3",
"postcss-values-parser": "2.0.1",
+ "regexp-util": "2.0.0",
"remark-footnotes": "2.0.0",
"remark-math": "3.0.1",
"remark-parse": "8.0.3",
@@ -109,12 +110,10 @@
"@eslint/compat": "1.1.1",
"@eslint/eslintrc": "3.1.0",
"@eslint/js": "9.10.0",
- "@glimmer/reference": "0.92.0",
"@stylistic/eslint-plugin-js": "2.7.2",
"@types/eslint__js": "8.42.3",
"@types/estree": "1.0.5",
"@types/file-entry-cache": "5.0.4",
- "@types/jest": "29.5.12",
"@typescript-eslint/eslint-plugin": "8.4.0",
"benchmark": "2.1.4",
"browserslist": "4.23.3",
@@ -144,6 +143,7 @@
"jest-snapshot-serializer-ansi": "2.1.0",
"jest-snapshot-serializer-raw": "2.0.0",
"jest-watch-typeahead": "2.2.2",
+ "knip": "5.30.1",
"magic-string": "0.30.11",
"npm-run-all2": "6.2.2",
"prettier": "3.3.3",
@@ -177,6 +177,7 @@
"lint:spellcheck": "cspell --no-progress --relative --dot --gitignore",
"lint:deps": "node ./scripts/check-deps.js",
"lint:blog": "node ./scripts/lint-blog.js",
+ "lint:knip": "knip",
"fix": "run-s fix:eslint fix:prettier",
"fix:eslint": "yarn lint:eslint --fix",
"fix:prettier": "yarn lint:prettier --write",
diff --git a/src/cli/utils.js b/src/cli/utils.js
index 22a213667..c683b416c 100644
--- a/src/cli/utils.js
+++ b/src/cli/utils.js
@@ -107,7 +107,7 @@ const normalizeToPosix =
? (filepath) => filepath.replaceAll("\\", "/")
: (filepath) => filepath;
-export const { isNonEmptyArray, partition, omit } = sharedWithCli.utils;
+export const { omit } = sharedWithCli.utils;
export {
createHash,
groupBy,
diff --git a/src/config/prettier-config/loaders.js b/src/config/prettier-config/loaders.js
index 0a2d95a81..e640c56da 100644
--- a/src/config/prettier-config/loaders.js
+++ b/src/config/prettier-config/loaders.js
@@ -72,4 +72,4 @@ const loaders = {
};
export default loaders;
-export { loadConfigFromPackageJson, loadConfigFromPackageYaml, readJson };
+export { loadConfigFromPackageJson, loadConfigFromPackageYaml };
diff --git a/src/document/utils.js b/src/document/utils.js
index 742bcbda0..98da38327 100644
--- a/src/document/utils.js
+++ b/src/document/utils.js
@@ -346,37 +346,6 @@ function cleanDoc(doc) {
return mapDoc(doc, (currentDoc) => cleanDocFn(currentDoc));
}
-function normalizeParts(parts) {
- const newParts = [];
-
- const restParts = parts.filter(Boolean);
- while (restParts.length > 0) {
- const part = restParts.shift();
-
- if (!part) {
- continue;
- }
-
- if (Array.isArray(part)) {
- restParts.unshift(...part);
- continue;
- }
-
- if (
- newParts.length > 0 &&
- typeof newParts.at(-1) === "string" &&
- typeof part === "string"
- ) {
- newParts[newParts.length - 1] += part;
- continue;
- }
-
- newParts.push(part);
- }
-
- return newParts;
-}
-
function replaceEndOfLine(doc, replacement = literalline) {
return mapDoc(doc, (currentDoc) =>
typeof currentDoc === "string"
@@ -408,7 +377,6 @@ export {
getDocType,
inheritLabel,
mapDoc,
- normalizeParts,
propagateBreaks,
removeLines,
replaceEndOfLine,
diff --git a/src/index.js b/src/index.js
index 8e93876a7..62b9884de 100644
--- a/src/index.js
+++ b/src/index.js
@@ -25,9 +25,7 @@ import {
normalizeOptionSettings,
} from "./main/support.js";
import { createIsIgnoredFunction } from "./utils/ignore.js";
-import isNonEmptyArray from "./utils/is-non-empty-array.js";
import omit from "./utils/object-omit.js";
-import partition from "./utils/partition.js";
/**
* @param {*} fn
@@ -99,8 +97,6 @@ const sharedWithCli = {
fastGlob,
createTwoFilesPatch,
utils: {
- isNonEmptyArray,
- partition,
omit,
},
mockable,
diff --git a/src/language-css/utils/index.js b/src/language-css/utils/index.js
index c3c78145b..d78cab4a5 100644
--- a/src/language-css/utils/index.js
+++ b/src/language-css/utils/index.js
@@ -405,12 +405,10 @@ export {
isInlineValueCommentNode,
isKeyframeAtRuleKeywords,
isKeyInValuePairNode,
- isKeyValuePairInParenGroupNode,
isKeyValuePairNode,
isLeftCurlyBraceNode,
isMathOperatorNode,
isMediaAndSupportsKeywords,
- isModuloNode,
isMultiplicationNode,
isParenGroupNode,
isPostcssSimpleVarNode,
diff --git a/src/language-css/utils/stringify-node.js b/src/language-css/utils/stringify-node.js
deleted file mode 100644
index cef9d39e1..000000000
--- a/src/language-css/utils/stringify-node.js
+++ /dev/null
@@ -1,23 +0,0 @@
-function stringifyNode(node) {
- if (node.groups) {
- const open = node.open?.value || "";
- const groups = node.groups
- .map((currentValue) => stringifyNode(currentValue))
- .join(node.groups[0]?.type === "comma_group" ? "," : "");
- const close = node.close?.value || "";
-
- return open + groups + close;
- }
-
- const before = node.raws?.before || "";
- const quote = node.raws?.quote || "";
- const atword = node.type === "atword" ? "@" : "";
- const value = node.value || "";
- const unit = node.unit || "";
- const group = node.group ? stringifyNode(node.group) : "";
- const after = node.raws?.after || "";
-
- return before + quote + atword + value + quote + unit + group + after;
-}
-
-export default stringifyNode;
diff --git a/src/language-html/print/tag.js b/src/language-html/print/tag.js
index ec1051320..8ccbf5153 100644
--- a/src/language-html/print/tag.js
+++ b/src/language-html/print/tag.js
@@ -384,7 +384,6 @@ export {
printClosingTag,
printClosingTagEnd,
printClosingTagEndMarker,
- printClosingTagStart,
printClosingTagStartMarker,
printClosingTagSuffix,
printOpeningTag,
diff --git a/src/language-html/utils/index.js b/src/language-html/utils/index.js
index a3c852ae9..679124397 100644
--- a/src/language-html/utils/index.js
+++ b/src/language-html/utils/index.js
@@ -630,12 +630,10 @@ export {
getLastDescendant,
getLeadingAndTrailingHtmlWhitespace,
getNodeCssStyleDisplay,
- getNodeCssStyleWhiteSpace,
getTextValueParts,
getUnescapedAttributeValue,
hasPrettierIgnore,
htmlTrimPreserveIndentation,
- htmlWhitespaceUtils,
inferElementParser,
isDanglingSpaceSensitiveNode,
isIndentationSensitiveNode,
@@ -644,7 +642,6 @@ export {
isScriptLikeTag,
isTextLikeNode,
isTrailingSpaceSensitiveNode,
- isUnknownNamespace,
isVueCustomBlock,
isVueNonHtmlBlock,
isVueScriptTag,
@@ -653,7 +650,6 @@ export {
isVueSlotAttribute,
isWhitespaceSensitiveNode,
preferHardlineAsLeadingSpaces,
- preferHardlineAsTrailingSpaces,
shouldPreserveContent,
unescapeQuoteEntities,
};
diff --git a/src/language-js/embed/utils.js b/src/language-js/embed/utils.js
index e63e64b3a..7406a11de 100644
--- a/src/language-js/embed/utils.js
+++ b/src/language-js/embed/utils.js
@@ -100,5 +100,4 @@ export {
hasLanguageComment,
isAngularComponentStyles,
isAngularComponentTemplate,
- isAsConstExpression,
};
diff --git a/src/language-js/print/comment.js b/src/language-js/print/comment.js
index f7c93bef7..e940a36c1 100644
--- a/src/language-js/print/comment.js
+++ b/src/language-js/print/comment.js
@@ -44,4 +44,4 @@ function printIndentableBlockComment(comment) {
];
}
-export { isIndentableBlockComment, printComment };
+export { printComment };
diff --git a/src/language-js/print/decorators.js b/src/language-js/print/decorators.js
index 67e01f9ec..b0b7076a4 100644
--- a/src/language-js/print/decorators.js
+++ b/src/language-js/print/decorators.js
@@ -87,7 +87,6 @@ function hasDecoratorsBeforeExport(node) {
}
export {
- hasDecoratorsBeforeExport,
printClassMemberDecorators,
printDecorators,
printDecoratorsBeforeExport,
diff --git a/src/main/range-util.js b/src/main/range-util.js
index 2fe5f7ad4..a3a2e250b 100644
--- a/src/main/range-util.js
+++ b/src/main/range-util.js
@@ -259,4 +259,4 @@ function calculateRange(text, opts, ast) {
};
}
-export { calculateRange, findNodeAtOffset };
+export { calculateRange };
diff --git a/website/playground/BottomBar.js b/website/playground/BottomBar.js
deleted file mode 100644
index cac102cfc..000000000
--- a/website/playground/BottomBar.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import * as React from "react";
-import * as ReactDOM from "react-dom";
-
-const root = document.getElementById("bottom-bar");
-
-export default function BottomBar({ left, right }) {
- return ReactDOM.createPortal(
-
- {left}
- {right}
- ,
- root,
- );
-}
diff --git a/website/playground/sidebar/options.js b/website/playground/sidebar/options.js
index 03c8cfb4b..c759f155c 100644
--- a/website/playground/sidebar/options.js
+++ b/website/playground/sidebar/options.js
@@ -2,7 +2,7 @@ import * as React from "react";
import { Checkbox, NumberInput, Select } from "./inputs.js";
-export function BooleanOption({ option, value, onChange }) {
+function BooleanOption({ option, value, onChange }) {
function maybeInvert(value) {
return option.inverted ? !value : value;
}
@@ -16,7 +16,7 @@ export function BooleanOption({ option, value, onChange }) {
);
}
-export function ChoiceOption({ option, value, onChange }) {
+function ChoiceOption({ option, value, onChange }) {
return (