[Vuejs]-Map .vue files in the components folder and export it as a json

0👍

Check the example, it also scan the folder recursively

Be aware of this structure:

components
└───user
│   │   Card.vue
└───product
    │   Card.vue

If the component from different folder have same name then it will override file and will output something like this:

{ Card: ".../src/components/product/Card.vue"}
const path = require('path');
const fs = require('fs/promises');

async function getFiles(dir) {
    const dirents = await fs.readdir(dir, { withFileTypes: true });
    const files = await Promise.all(
        dirents.map((dirent) => {
            const res = path.resolve(dir, dirent.name);
            return dirent.isDirectory() ? getFiles(res) : res;
        })
    );
    return files.flat();
}

function createComponentsMapJsonPlugin() {
    return {
        apply: (compiler) => {
            compiler.hooks.done.tapPromise('CreateComponentsMapJsonPlugin', async () => {
                const componentsDir = path.join(__dirname, 'src/components');
                const outputPath = path.resolve(process.cwd(), 'componentsMap.json');

                const filesList = await getFiles(componentsDir);
                const filesMap = filesList.reduce((acc, filePath) => {
                    const formattedPath = filePath.replace(/\\/g, '/');
                    const file = formattedPath.split('/').at(-1);

                    if (file.endsWith('.vue') && file !== 'index.vue') {
                        acc[file.replace('.vue', '')] = formattedPath;
                    }

                    return acc;
                }, {});

                return fs.writeFile(outputPath, JSON.stringify(filesMap));
            });
        }
    };
}

module.exports = {
    configureWebpack: (config) => {
        config.plugins.push(createComponentsMapJsonPlugin());
    }
};

Leave a comment