Open gajus opened 2 years ago
@gajus,
Work is in progress to add parsing of JavaScript and other file types to enable ignoring imports and related things. See: #2684
In the meantime, you can use a configuration like this:
cspell-node.config.cjs
const fs = require('fs');
const path = require('path');
/**
* Search for `package.json`
* @param {string} from - search `from` directory.
* @returns {string} - path to package.json
*/
function findNearestPackageJson(from) {
from = path.resolve(from);
const parent = path.dirname(from);
if (!from || parent === from) {
return;
}
const pkg = path.join(from, 'package.json');
if (fs.existsSync(pkg)) {
return pkg;
}
return findNearestPackageJson(parent);
}
/**
* Load the nearest package.json
* @param {string} cwd
* @returns
*/
function loadPackage(cwd) {
const pkgFile = findNearestPackageJson(cwd);
console.log('found: %o', pkgFile);
if (!pkgFile) return;
return JSON.parse(fs.readFileSync(pkgFile, 'utf-8'));
}
function determinePackageNamesAndMethods(cwd = process.cwd()) {
const pkg = loadPackage(cwd) || {};
const packageNames = Object.keys(pkg.dependencies || {}).concat(Object.keys(pkg.devDependencies || {}));
const setOfWords = new Set(packageNames.flatMap((name) => name.replace(/[@]/g, '').split('/')));
const words = [...setOfWords];
return { words };
}
module.exports = {
words: determinePackageNamesAndMethods().words,
};
cspell.json
{
"import": ["./cspell-node.config.cjs"]
}
My solution. I have a shared project with cspell.json
. Every other project of mine has a symlink to this file, therefore any words added in one project are available to the others.
In any project, I can call this to refresh my list of words. This handles entries like @hapi/hapijs
, which need to be turned into two:
node -e "import('../utils/src/listDependencies.js').then(m => m.listDependencies())"
import fs from 'fs';
const keys = Object.keys;
export const listDependencies = () => {
const { dependencies, devDependencies } = JSON.parse(fs.readFileSync('./package.json'));
const packages = keys(dependencies).concat(keys(devDependencies));
const packagesNames = packages.reduce((acc, p) => [...acc, ...p.replace('@', '').split('/')] , []);
fs.writeFileSync('./.vscode/packages-words.txt', packagesNames.join('\n'));
};
"dictionaryDefinitions": [
{
"name": "packages-words",
"path": "./packages-words.txt"
}
],
"dictionaries": [
"packages-words"
],
@Jason3S brilliant work-around, thanks! Here's my adjustment to handle package names like @fontsource/roboto
:
function determinePackageNamesAndMethods(cwd = process.cwd()) {
const package = loadPackage(cwd) || {};
const packageNames = Object.keys(package.dependencies || {}).concat(Object.keys(package.devDependencies || {}));
const nameSet = new Set();
packageNames.forEach(name => nameSet.add(...name.replace('@', '').split('/')));
return [...nameSet];
}
module.exports = {
words: determinePackageNamesAndMethods(),
};
@gajus,
Work is in progress to add parsing of JavaScript and other file types to enable ignoring imports and related things. See: #2684
In the meantime, you can use a configuration like this:
cspell-node.config.js
const fs = require('fs'); const path = require('path'); /** * Search for `package.json` * @param {string} from - search `from` directory. * @returns {string} - path to package.json */ function findNearestPackageJson(from) { from = path.resolve(from); const parent = path.dirname(from); if (!from || parent === from) { return; } const pkg = path.join(from, 'package.json'); if (fs.existsSync(pkg)) { return pkg; } return findNearestPackageJson(parent); } /** * Load the nearest package.json * @param {string} cwd * @returns */ function loadPackage(cwd) { const pkgFile = findNearestPackageJson(cwd); console.log('found: %o', pkgFile) if (!pkgFile) return; return JSON.parse(fs.readFileSync(pkgFile, 'utf-8')); } function determinePackageNamesAndMethods(cwd = process.cwd()) { const package = loadPackage(cwd) || {}; const packageNames = Object.keys(package.dependencies || {}).concat(Object.keys(package.devDependencies || {})); return { packageNames }; } module.exports = { words: determinePackageNamesAndMethods().packageNames, };
cspell.json
{ "import": ["./cspell-node.config.js"] }
This gives me Configuration Error: Failed to read config file: "/home/.../cspell-node.config.js"
@wvhulle,
This gives me
Configuration Error: Failed to read config file: "/home/.../cspell-node.config.js"
You might need to make it a .cjs
file if you are running it in a "module" package.
CSpell will not load a .mjs or ESM module files.
I have changed https://github.com/streetsidesoftware/cspell/issues/3215#issuecomment-1181992508 to reflect the need for a .cjs
file.
Could we have a dependency parser like this built into cspell or a plugin?
@nickmccurdy This bugged me for a while too.
I ended up just creating a $ make cSpell
cmd in my make file, but you can easily add to as a task to run on folder open of vscode. I used the jq
util to parse package.json and generate a custom dictionary text.
Then I just added custom dict config to .vscode/settings.json
Here is my version with monorepo support:
Is your feature request related to a problem? Please describe.
At the moment, we have to pretty much whitelist every package name in our dictionary.
Describe the solution you'd like
It would be nice if cspell had an option to read names from package.json dependencies and add them to the dictionary.
Describe alternatives you've considered
We manually add all package names to the dictionary, but it causes unnecessary noise in the dictionary file.
Additional context Add any other context or screenshots about the feature request here.