diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 32c99305535d6..af75f4ac59e14 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -265,6 +265,13 @@ $ cd docs $ BUILD_DOCS_DEV=1 ./build-docs.sh ``` +### Tooling Assists +#### Jetbrains (WebStorm/IntelliJ) +This project uses lerna and utilizes symlinks inside nested node_modules directories. You may encounter an issue during +indexing where the IDE attempts to index these directories and keeps following links until the process runs out of +available memory and crashes. To fix this, you can run ```node ./scripts/jetbrains-remove-node-modules.js``` to exclude +these directories. + ## Dependencies ### Adding Dependencies diff --git a/scripts/jetbrains-remove-node-modules.js b/scripts/jetbrains-remove-node-modules.js new file mode 100644 index 0000000000000..875ebfbc3b231 --- /dev/null +++ b/scripts/jetbrains-remove-node-modules.js @@ -0,0 +1,60 @@ +const fs = require('fs'); +const path = require('path'); +const os = require('os'); + +const getAllChildDirectories = (dir) => fs.readdirSync(dir).map(name => path.join(dir, name.toString())).filter(name => fs.lstatSync(name).isDirectory()); +const isNodeModulesDirectory = (name) => name.toString().endsWith('node_modules'); + +function getAllNodeModulesPaths(dir) { + let nodeModulesPaths = []; + getAllChildDirectories(dir).forEach(name => { + if (isNodeModulesDirectory(name)) { + console.log('Excluding ' + name); + nodeModulesPaths.push(name); + } else { + const subNodeModulesPaths = getAllNodeModulesPaths(name); + nodeModulesPaths = nodeModulesPaths.concat(subNodeModulesPaths); + } + }); + return nodeModulesPaths; +} + +// Should be run at the root directory +if (!fs.existsSync('lerna.json')) { + throw new Error('This script should be run from the root of the repo.'); +} + +const nodeModulesPaths = getAllNodeModulesPaths('.'); + +// Hardcoded exclusions for this project (in addition to node_modules) +const exclusions = nodeModulesPaths.map(path => ``); +exclusions.push(''); +exclusions.push(''); +exclusions.push(''); +exclusions.push(''); + +exclusionsString = exclusions.join(os.EOL); + +// Let filename be passed in as an override +let fileName = process.argv[2] || process.cwd().split('/').slice(-1).pop() + '.iml'; + +// Jetbrains IDEs store iml in .idea except for IntelliJ, which uses root. +if (fs.existsSync('.idea/' + fileName)) { + fileName = '.idea/' + fileName; +} else if (!fs.existsSync(fileName)) { + throw new Error('iml file not found in .idea or at root. Please pass in a path explicitly as the first argument.'); +} + +// Keep the contents. We are only updating exclusions. +const exclusionInfo = fs.readFileSync(fileName); + +const toWrite = exclusionInfo.toString().replace(/(?:\s.+)+\/content>/m, `${os.EOL}${exclusionsString}${os.EOL}`); + +console.log(os.EOL + 'Writing to file...'); + +// "Delete" the file first to avoid strange concurrent use errors. +fs.unlinkSync(fileName); + +fs.writeFileSync(fileName, toWrite); + +console.log('Done!');