Chore: Add codemod and betterer config to make barrel imports explicit (#80913)

* chore: add codemod for highlighting barrel imports

* style(frontend): add no-barrel-files plugin to betterer

* chore(betterer): update betterer file

* ci(frontend-metrics): track occurrences of barrel files being imported

* chore: clean up explicit barrel imports codemod script

* chore(codeowners): add explicit barrel imports script

* Add no-barrel-files plugin to betterer configuration

Co-Authored-By: LeventeBalogh <balogh.levente.hu@gmail.com>

---------

Co-authored-by: LeventeBalogh <balogh.levente.hu@gmail.com>
This commit is contained in:
Jack Westbrook
2024-04-15 16:36:19 +02:00
committed by GitHub
parent 453a75b767
commit 1dfd34ee79
8 changed files with 526 additions and 11 deletions

View File

@@ -11,6 +11,7 @@ ACCESSIBILITY_ERRORS="$(grep -oP '\"errors\":(\d+),' pa11y-ci-results.json | gre
DIRECTIVES="$(grep -r -o directive public/app/ | wc -l)"
CONTROLLERS="$(grep -r -oP 'class .*Ctrl' public/app/ | wc -l)"
LEGACY_FORMS="$(grep -r -oP 'LegacyForms;' public/app | wc -l)"
BARREL_IMPORTS="$(grep -r -oP '@todo: replace barrel import path' public/app | wc -l)"
CLASSNAME_PROP="$(grep -r -o -E --include="*.ts*" "\.*.className=\W.*\W.*" public/app | wc -l)"
EMOTION_IMPORTS="$(grep -r -o -E --include="*.ts*" --exclude="*.test*" "\{.*css.*\} from '@emotion/css'" public/app | wc -l)"
TS_FILES="$(find public/app -type f -name "*.ts*" -not -name "*.test*" | wc -l)"
@@ -29,6 +30,7 @@ echo -e "Accessibility errors: $ACCESSIBILITY_ERRORS"
echo -e "Directives: $DIRECTIVES"
echo -e "Controllers: $CONTROLLERS"
echo -e "Legacy forms: $LEGACY_FORMS"
echo -e "Barrel imports: $BARREL_IMPORTS"
echo -e "Total bundle folder size: $TOTAL_BUNDLE"
echo -e "Total outdated dependencies: $OUTDATED_DEPENDENCIES"
echo -e "Low vulnerabilities: $LOW_VULNERABILITIES"

View File

@@ -0,0 +1,39 @@
const fs = require('fs');
const path = require('path');
module.exports = function (fileInfo, api) {
const j = api.jscodeshift;
const root = j.withParser('tsx')(fileInfo.source);
const fileDir = path.dirname(fileInfo.path);
// Function to check if the path potentially points to a barrel file
const mightBeBarrelFileImport = (importPath) => {
const fullPath = path.join(fileDir, importPath);
if (fs.existsSync(fullPath) && fs.lstatSync(fullPath).isDirectory()) {
if (fs.existsSync(path.join(fullPath, 'index.ts')) || fs.existsSync(path.join(fullPath, 'index.js'))) {
return true;
}
}
return false;
};
// Udpate import declarations that import from barrel files
root
.find(j.ImportDeclaration)
.filter((path) => mightBeBarrelFileImport(path.node.source.value))
.forEach((path) => {
// Create a comment node
const comment = j.commentLine(' @todo: replace barrel import path');
// Attach the comment as a leading comment to the import declaration
if (!path.node.comments) {
path.node.comments = [];
}
path.node.comments.push(comment);
// Update the import path appending '/index'
path.node.source.value = path.node.source.value + '/index';
});
return root.toSource();
};