Skip to content

Instantly share code, notes, and snippets.

@rileyjshaw
Created March 10, 2023 03:58
Show Gist options
  • Save rileyjshaw/0d3c8462e094f6b0103bcdb1ff65ce95 to your computer and use it in GitHub Desktop.
Save rileyjshaw/0d3c8462e094f6b0103bcdb1ff65ce95 to your computer and use it in GitHub Desktop.
A quick script to organize loose React components
/**
* Moves a React component into its own folder in <src>/components/, adds an index.js for
* cleaner imports, and updates the import path in other files.
*
* Based loosely on the structure shown in https://www.joshwcomeau.com/react/file-structure.
*
*
* Usage
* =====
*
* Move this script into the root of your project, update SRC_DIR, then pass in the component’s name:
*
* node move-component.js ComponentNameWithoutExtension
*
* That’s all! You’ll probably want to modify this script first; it was quickly written with
* a specific project in mind.
*
*/
import fs from 'fs';
import path from 'path';
const SRC_DIR = './src';
const COMPONENT_NAME = process.argv[2];
const walk = (dir, files = []) => {
try {
const list = fs.readdirSync(dir);
list.forEach(file => {
file = path.join(dir, file);
const stat = fs.statSync(file);
if (stat && stat.isDirectory()) {
// Recurse into subdir
walk(file, files);
} else {
// Is a file
files.push(file);
}
});
return files;
} catch (error) {
console.error(`Error when walking dir ${dir}`, error);
}
};
const edit = (filePath, oldImportString, newImportString) => {
const oldContent = fs.readFileSync(filePath, { encoding: 'utf8' });
if (!oldImportString.test(oldContent)) {
return;
}
const newContent = oldContent.replace(oldImportString, newImportString);
fs.writeFileSync(filePath, newContent, { encoding: 'utf-8' });
console.log(`Updated import in: ${filePath}`);
};
const main = () => {
const oldPath = `${SRC_DIR}/${COMPONENT_NAME}.jsx`;
if (!fs.existsSync(oldPath)) {
throw new Error(`File ${oldPath} does not exist.`);
}
// The file exists; edit all imports to reference the new location.
const oldImportString = new RegExp(`from '\\..*/${COMPONENT_NAME}'`, 'gi');
const newImportString = `from '/components/${COMPONENT_NAME}'`;
walk(SRC_DIR).forEach(filePath => edit(filePath, oldImportString, newImportString));
// Move the file.
const newDir = `${SRC_DIR}/components/${COMPONENT_NAME}`;
const newPath = `${newDir}/${COMPONENT_NAME}.jsx`;
fs.mkdirSync(newDir);
fs.rename(oldPath, newPath, function (err) {
if (err) throw err;
console.log(`Moved ${COMPONENT_NAME} into a new folder.`);
});
// Create an index file.
const indexPath = `${newDir}/index.js`;
fs.writeFileSync(
indexPath,
`export * from './${COMPONENT_NAME}';\nexport { default } from './${COMPONENT_NAME}';\n`,
{
encoding: 'utf-8',
}
);
};
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment