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;
相关推荐
啃火龙果的兔子19 小时前
Promise.all和Promise.race的区别
前端
马达加斯加D19 小时前
Web身份认证 --- OAuth授权机制
前端
2401_8370885019 小时前
Error:Failed to load resource: the server responded with a status of 401 ()
开发语言·前端·javascript
全栈师19 小时前
LigerUI下frm与grid的交互
java·前端·数据库
叫我詹躲躲19 小时前
被前端存储坑到崩溃?IndexedDB 高效用法帮你少走 90% 弯路
前端·indexeddb
无尽夏_19 小时前
CSS3(前端基础)
前端·css·1024程序员节
温宇飞19 小时前
Next.js 简述 - React 全栈框架
前端
百花~19 小时前
前端三剑客之一 CSS~
前端·css
青天诀19 小时前
React 中 setTimeout 获取不到最新 State 的原因及解决方案
前端·react.js
拉不动的猪19 小时前
闭包实际项目中应用场景有哪些举例
前端·javascript·面试