How to import all components from a folder?
While developing with Vuetify.js, I found the <v-icon> component incredibly convenient. This inspired me to create my own icon components, allowing me to easily access all of my favorite icons. I eagerly gathered all the SVG files into a folder, only to realize… I had to manually import each icon as a component, one by one. 🤦🏽♂️
My initial attempt to streamline this process was with import * from './svg',
but I quickly hit a roadblock:
Failed to resolve import "./svg" from "./svg/index.js". Does the file exist?.
It dawned on me that I needed an index.js file in the folder, exporting every component. So, I was back to square one, facing the tedious task of manually importing and exporting each icon component.
A quick search on Stack Overflow seemed to offer a promising solution.
const files = require.context('.', false, /\.vue$/)
const modules = {}
files.keys().forEach((key) => {
if (key === './index.js') return
modules[key.replace(/(\\./|\\.vue)/g, '')] = files(key)
})
export default modules
However, my excitement was short-lived when the browser console threw up Uncaught ReferenceError: require is not defined at index.js. I discovered that require() is not a valid function in client-side JavaScript.
Determined to find a workaround, I decided to auto-generate the index.js file with a bash script. Although this approach still involves a bit of manual effort (I need to run the script each time I add a new component), it significantly reduces the hassle of individually verifying each filename.
Here's the script I crafted:
# Navigate to the script's directory
cd \"$(dirname \"$0\")\"
# Get a list of icon files, excluding index.js and import.sh
icons=$(ls --hide=index.js --hide=import.sh --format=single-column)
# Define the output file
output_file=\"index.js\"
# Clear the output file
> $output_file
# Generate import statements
for icon in $icons
do
name=$(basename -- \"$icon\")
name=\"${name%.*}\"
echo \"import $name from './$icon'\" >> $output_file
done
echo \"\" >> $output_file
echo \"export {\" >> $output_file
# Generate export statements
for icon in $icons
do
name=$(basename -- \"$icon\")
name=\"${name%.*}\"
echo \" $name,\" >> $output_file
done
echo \"}\" >> $output_file
echo \"\" >> $output_file
With this script in the subfolder, I simply run sudo ./import.sh and all my components are imported and exported in index.js. This allows me to use import * from './svg' seamlessly in other files.
That's my solution. I'm eager to hear your thoughts and suggestions on how to improve this process!