DEV Community

Adrian Chan Yong Qian
Adrian Chan Yong Qian

Posted on

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (1)

Collapse
 
damian_cyrus profile image
Damian Cyrus

I don't know if that is the right way, but it is a good idea.

Some other though could be to generate the file with node.js, and integrate it in your build process. You can check for changes automatically and run a write script. All done with JavaScript.

Good luck with your project!