s00d / webpack-shell-plugin-next

Run shell commands either before or after webpack 4 and 5 builds
MIT License
92 stars 12 forks source link

Seems to fire before webpack is done...? #29

Closed DorkForce closed 3 years ago

DorkForce commented 3 years ago

SETUP: I've got some copy stuff going on in my scripts, to literally copy the source code into a /src directory of the package I intend to create. Don't ask why; I don't want to do that, but oh well. Anyway, that's working but it's copying more folders than I want. I'd like to see: /dist/src/MyKewlComponent/ but it turns out to be /dist/src/src/js/components/MyKewlComponent/.

Problem with webpack-shell-plugin-next: I'm using this plugin to try to just MOVE the component(s) folder(s) up a few directories after the copy is done. However, it seems to process BEFORE the webpack job even runs... I see the commands being attempted, in the output, and then after that I see the results of the copy.

Portion of my code:

const configureCopy = function (leJob, relPath, fileName, distSubdir) {
    distSubdir = distSubdir ? leJob.sourceName + '/' + distSubdir : '';
    let ignoredFiles = ["**/*stories.js", "**/*test.js"]
    if (leJob.ignoredFiles) {
        ignoredFiles = ignoredFiles.concat(leJob.ignoredFiles);
    }

    let plugins = [];
    plugins.push(
        new CopyPlugin({
            patterns: [
                {
                    from: path.posix.resolve(`${relPath}${fileName ? fileName : ''}`).replace(/\\/g, "/"),
                    to: path.resolve(__dirname, `dist/${distSubdir || leJob.sourceName}`),
                    globOptions: {
                        ignore: ignoredFiles,
                    },
                    info: { minimized: true },
                    transform(content) {
                        return parseReplace(content, leJob);
                    },
                },
            ],
        })
    );
    plugins.push(new IgnoreEmitPlugin(/nondist.js$/));
    plugins.push(arrangeCleanup(leJob)); // <------------------------ here I add the Shell Plugin. Tried adding it first, too.

    return {
        name: `copy__${leJob.sourceName}_to_${leJob.packedName}`,
        entry: { nondist: path.resolve(__dirname, `src/js/index.js`), },   // for the copyPlugin, this does not seem to matter, esp with IgnoreEmitPlugin
        output: { path: path.resolve(__dirname, "dist"), }, // this line is not needed as default is dist
        plugins: plugins,
    };
}

const arrangeCleanup = function (job) {
    /*
        The commands here wind up rendering like:
        cd C:\Workspace\my-project\dist\components\src\src\js\components
        move MyKewlComponent ../../../
    */
    let commands = [];
    job.otherSources.forEach((oSrc) => {
        const folderName = oSrc.substr(0, oSrc.lastIndexOf('/'));
        const commandChangeDir = `cd ${path.resolve(__dirname, 'dist', job.sourceName, 'src', 'src', 'js', 'components')}`;
        const commandMoveDir = `move ${folderName} ../../../`;
        commands.push(commandChangeDir);
        commands.push(commandMoveDir);
    })
    commands.push(`cd ${path.resolve(__dirname)}`);
    return new WebpackShellPluginNext({
        onAfterDone: { // <------------------ I tried all the other stages, too
            scripts: commands,
            blocking: true,
            parallel: false
        }
    });
}

... I must be doing this wrong. Am I?

DorkForce commented 3 years ago

I'm pretty sure this was related to the fact that I wanted this plugin to run after other plugins - not necessarily the compile. Couldn't figure it out, so I created a node script to take care of it after Webpack was done.

Dobby89 commented 3 years ago

@DorkForce Any chance of sharing your script? :D

DorkForce commented 3 years ago

Sure -- note that I made this generic, removing project file names, descriptions, of course:

/* 
 *  ./.webpack/jobs.js
 */

const compileJobs = [
    {
        entry: "src/index-comp.js",
        name: "index",
        output: "dist/comp/",
        description: 'Description Goes Here',
    },
    {
        entry: "src/index-wc.js",
        name: "index-wc",
        output: "dist/wc/",
        description: 'Description Goes Here'
    }
];

const cssJobs = [
    {
        entry: "src/scss/all-styles.scss",
        name: "all-styles-comp",
        output: "dist/comp",
        description: 'Description Goes Here',
    },
    {
        entry: "src/scss/all-styles-wc.scss",
        name: "all-styles-wc",
        output: "dist/wc",
        description: 'Description Goes Here',
    }
];

module.exports = {
    cssJobs,
    compileJobs,
};

/* 
 *  ./webpack.cleanup.js
 */

const path = require('path');
const jobs = require('./.webpack/jobs');
const fs = require('fs')

const utils = {
    dir: (target) => {
        let filesToReturn = [];
        try {
            const arrayOfFiles = fs.readdirSync(target)
            filesToReturn = arrayOfFiles;
        } catch (e) {
            console.log(e)
        }
        return filesToReturn;
    },
    removeDir: function (incomingPath) {
        if (fs.existsSync(incomingPath)) {
            const contnts = fs.readdirSync(incomingPath);
            if (contnts.length > 0) {
                contnts.forEach(function (filename) {
                    if (fs.statSync(incomingPath + '/' + filename).isDirectory()) {
                        utils.removeDir(incomingPath + '/' + filename)
                    } else {
                        fs.unlinkSync(incomingPath + '/' + filename);
                    }
                })
                fs.rmdirSync(incomingPath)
            } else {
                fs.rmdirSync(incomingPath)
            }
        } else {
            console.log('==>', 'Directory path not found.');
        }
    }
}

setTimeout(() => {
    jobs.forEach((job) => {
        const sourceDir = path.resolve(__dirname, 'dist', job.sourceName, 'src', 'src', 'js', 'components');
        const targetDir = path.resolve(__dirname, 'dist', job.sourceName, 'src');
        const components = utils.dir(sourceDir);
        components.forEach((component) => {
            const oldPath = (sourceDir + '/' + component).replace(/\\/g, '/');
            const newPath = (targetDir + '/' + component).replace(/\\/g, '/');
            fs.rename(oldPath, newPath, function (err) {
                if (err) console.log('==>', err);
            });
        });
        setTimeout(() => {
            const pathToRemove = path.resolve(__dirname, 'dist', job.sourceName, 'src', 'src').replace(/\\/g, '/');
            utils.removeDir(pathToRemove);
        }, 500);
})
}, 2000);