Skip to content

Instantly share code, notes, and snippets.

@Arkellys
Last active March 19, 2024 09:23
Show Gist options
  • Save Arkellys/aa7d31e66cf527d4f9d6af23f1ad4415 to your computer and use it in GitHub Desktop.
Save Arkellys/aa7d31e66cf527d4f9d6af23f1ad4415 to your computer and use it in GitHub Desktop.
Example of bash script to create a new React (sub-)component file and folder and add the export into an index file automatically.

The script will allow creating a new component in the folder src/components. If the given path ends with a component name (detection is made if the last part of the path is in PascalCase), then it will detect the new component created is a sub-component and put it in an subComponents folder. A new export is automatically added (and sorted alphabetically) into the index.js file of the parent folder.

Variables

  • validFolders → List of folders where a new component can be created
  • subComponentFolderName → Name of the folder for sub-components

Example

Initial folder structure:

src/
└── components/
    ├── Parent/
    │   └── Parent.js
    └── index.js

Initial src/components/index.js:

export { default as Parent } from "./Parent/Parent";

Creating a new component:

node ".bin/create-component.sh"
Enter folder path: src/components
Enter component name: NewParent

New folder structure:

src/
└── components/
    ├── NewParent/
    │   └── NewParent.js
    ├── Parent/
    │   └── Parent.js
    └── index.js

New src/components/index.js:

export { default as NewParent } from "./NewParent/NewParent";
export { default as Parent } from "./Parent/Parent";

Creating a new sub-component:

node ".bin/create-component.sh"
Enter folder path: src/components/NewParent
Enter component name: NewChild

New folder structure:

src/
└── components/
    ├── NewParent/
    │   ├── subComponents/
    │   │   ├── NewChild/
    │   │   │   └── NewChild.js
    │   │   └── index.js
    │   └── NewParent.js
    ├── Parent/
    │   └── Parent.js
    └── index.js
#!/bin/bash
pascalCasePattern='^[A-Z][a-zA-Z0-9]*$'
# Set component path
read -p "Enter folder path: " folderPath
validFolders=("src/components(?:/[^/]+)*")
pattern=$(IFS=\| ; echo "${validFolders[*]}")
if ! echo "$folderPath" | grep -Eq "^($pattern)"; then
echo -e "\e[1;31mError: \e[0;31mcomponents are only allowed in folders: ${pattern}\e[0m"
exit 1
fi
# Go to the given path
cd "$folderPath" || { echo -e "\e[1;31mError: \e[0;31mpath \`${folderPath}\` does not exist.\e[0m"; exit 1; }
# Set component name
read -p "Enter component name: " componentName
if ! echo "$componentName" | grep -Eq "$pascalCasePattern"; then
echo -e "\e[1;31mError: \e[0;31mcomponent name must be in PascalCase.\e[0m"
exit 1
fi
# Set parent folder
lastPathPart=$(basename "$folderPath")
subComponentFolderName="subComponents"
isSubComponent=$(echo "$lastPathPart" | grep -Eq "$pascalCasePattern" && echo true || echo false)
parentFolder="$([ "$isSubComponent" = true ] && echo "${subComponentFolderName}/" || echo "")"
echo -e "\e[34m\nCreating new $( [ "$isSubComponent" = true ] && echo "sub-" || echo "" )component...\n\e[0m"
# Create the component folder
mkdir -p "${parentFolder}${componentName}"
echo -e "\e[0;32mNew folder \`\e[1;32m${parentFolder}${componentName}\e[0;32m\` created\e[0m"
# Create the component file with boilerplate code
printf "const ${componentName} = () => {\n\n};\n\nexport default ${componentName};" \
> "${parentFolder}${componentName}/${componentName}.js"
echo -e "\e[0;32mNew file \`\e[1;32m${componentName}.js\e[0;32m\` created\e[0m"
# Update (or create) the `index.js` file with the new export
printf "/*eslint-disable*/\nexport { default as ${componentName} } from \"./${componentName}/${componentName}\";" \
>> "${parentFolder}index.js"
echo -e "\e[0;32mExport added to \e[1;32m\`index.js\`\e[0;32m\e[0m"
# Sort the exports alphabetically
if [ -e "${parentFolder}index.js" ]; then
cat "${parentFolder}index.js" | grep '^export' | sort > temp_index.js
mv temp_index.js "${parentFolder}index.js"
fi
# Run ESLint on the new created files
sed -e 's:/[*]eslint-disable[*]/::g' -i "${parentFolder}index.js"
npx eslint --fix "**/${parentFolder}index.js" "**/${componentName}/${componentName}.js" || true
# Go back to root
echo -e "\e[1;32m\nDone!\n\e[0m"
cd -
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment