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!