vue2,webpack 老项目清除无用的文件

清理无用文件肝的眼睛冒金星,不妨来试试webpack插件。

原理就是获取指定目录的全部文件,排除代码依赖的文件,就是不依赖的文件,也就是无用的文件,使用shelljs删除文件

插件仅限在webpack3、webpack4下使用

插件使用

javascript 复制代码
const UnusedFilesWebpackPlugin = require('./unused-files-webpack-plugin')

plugins: [
//...其他插件
    new UnusedFilesWebpackPlugin({
        root: './src', // 项目目录
        output: './unused-files.json', // 输出文件列表
        clean: true, // 是否删除文件,true,删除;false,不删除
        exclude: ['src/assets/font', 'src/assets/icon-font'], // 排除文件列表

    })
]

插件源码

ini 复制代码
const fs = require("fs");
const glob = require("glob");
const path = require("path");
const shelljs = require("shelljs");

class CleanUnusedFilesPlugin {
    constructor(options) {
        this.opts = options;
    }
    apply(compiler) {
        let _this = this;
        compiler.plugin("after-emit", function(compilation, done) {
            _this.findUnusedFiles(compilation, _this.opts);
            done();
        });
    }

    /**
     * 获取依赖的文件
     */
    getDependFiles(compilation) {
        return new Promise((resolve, reject) => {
            const dependedFiles = [...compilation.fileDependencies].reduce(
                (acc, usedFilepath) => {
                    if (!~usedFilepath.indexOf("node_modules")) {
                        acc.push(usedFilepath);
                    }
                    return acc;
                },
                []
            );
            resolve(dependedFiles);
        });
    }

    /**
     * 获取项目目录所有的文件
     */
    getAllFiles(pattern) {
        return new Promise((resolve, reject) => {
            glob(
                pattern,
                {
                    nodir: true
                },
                (err, files) => {
                    if (err) {
                        throw err;
                    }
                    const out = files.map(item => path.resolve(item));
                    resolve(out);
                }
            );
        });
    }

    dealExclude(path, unusedList) {
        let exclude = [];
        if (Array.isArray(path)) {
            // 兼容传入的是数组路径
            exclude = path;
        } else if (typeof path == "string") {
            try {
                // 读取文件里的数组字符串
                const file = fs.readFileSync(path, "utf-8");
                exclude = JSON.parse(file) || [];
            } catch (error) {
                console.log(error);
            }
        }
        console.log(exclude, "exclude");
        if (process.platform == "win32") {
            // windows 需要兼容路径 D:\\workspace\\src\\App.vue
            unusedList = unusedList.map(item => item.replace(/\\/g, "/"));
        }
        let result = unusedList.filter(unused => {
            return !exclude.some(item => ~unused.indexOf(item));
        });
        return result;
    }

    async findUnusedFiles(compilation, config = {}) {
        const {
            root = "./src",
            output = "./unused-files.json",
            clean = false,
            exclude = false
        } = config;
        const pattern = root + "/**/*";
        try {
            const allChunks = await this.getDependFiles(compilation);
            const allFiles = await this.getAllFiles(pattern);
            let unUsed = allFiles.filter(item => !~allChunks.indexOf(item));
            if (exclude) {
                unUsed = this.dealExclude(exclude, unUsed);
            }
            if (typeof output === "string") {
                fs.writeFileSync(output, JSON.stringify(unUsed, null, 4));
            } else if (typeof output === "function") {
                output(unUsed);
            }
            if (clean) {
                unUsed.forEach(file => {
                    shelljs.rm(file);
                    console.log(`remove file: ${file}`);
                });
            }
            return unUsed;
        } catch (err) {
            throw err;
        }
    }
}

module.exports = CleanUnusedFilesPlugin;
相关推荐
hunterandroid20 分钟前
[Android 从零到一] Compose LazyColumn 性能优化:key、稳定性与重组治理
android·前端
lichenyang45329 分钟前
从一次团队邀请开始:用 React、NestJS 与 Socket.IO 做可靠的实时通知
前端
vtian30 分钟前
一篇文章吃透 Monorepo:pnpm + Turborepo + Changesets 全流程实战(含 8 个踩坑)
前端
默_笙35 分钟前
❗ 点击计数按钮,为什么"峨眉队"也跟着重新渲染?React.memo 说:我记住了
前端·javascript
31535669131 小时前
DeepSeek Harness 发布后,我没急着跑 Demo,先把 `.agents/` 翻了一遍
前端·后端·github
名字还没想好☜1 小时前
Next.js 用 Server Components 直连数据库:去掉 API 层的边界,和三条别踩的安全红线
前端·javascript·数据库·安全·react·next.js
学习zhao极致it1 小时前
2020全新React教程全家桶实战redux+antd+React Hooks前端js视频
前端
用户921080262861 小时前
Bubble 消息操作区改造:复制、重新生成和反馈
前端
LEE1 小时前
AI Agent 都在疯狂加功能,它说:我全砍了
前端·后端
张清悠1 小时前
用 TRAE Work 把 PRD + 设计稿注释,整理成 20 分钟可排期前端任务清单
前端