likes
comments
collection
share

10分钟删除无用500+无用文件,我是如何做的?

作者站长头像
站长
· 阅读数 46

先做个自我介绍吧,大家好,我是一个21年专科毕业的小厂前端,这个账号会记录一些自己工作学习中的一些案例,分享给大家。

需求背景

最近接手了一个起初代码是买来的项目,现在业务进入了快速发展的阶段,原有的业务逻辑一大半都是用不到的,但是在项目中,无论在开发体验,还是构建速度上都造成了不小的影响

了解了需求,我就开始调研,经过一通百度,总结了两种方案

本文涉及的代码仓库github.com/wangjieCode…

方案1-ast

大概的流程就是从入口文件开始解析为ast,递归收集import,require内容,拿出一个依赖的文件,话不多说直接开干

先下好使用的到的依赖,babel全家桶(@babel/parser, @babel/traverse), 开干,parse入口文件,找到所有的import路径, 在去递归import的source

const fastGlob = require('fast-glob');
const path = require('path');
const fs = require('fs');
const { parse } = require('@babel/parser');
const traverse = require('@babel/traverse').default;
// const vue = require('babel-preset-vue')
const allSourcesPath = fastGlob.sync('./src/**/*.{js,vue}');

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/946af49d129d483483ba9616e4de13a5~tplv-k3u1fbpfcp-watermark.image?)
const entry = path.resolve(process.cwd(), './src/main.js');

const getDepPath = (sourcePath) => {
    const sourceContent = fs.readFileSync(sourcePath);
    const depPathArr = [];
    const ast = parse(sourceContent.toString(), {
        sourceType: 'module',
    })
    traverse(ast, {
        ImportDeclaration(path) {
            const filepath = path.node.source.value;
            filepath.startsWith('.') && depPathArr.push(filepath)
        }
    })
    return depPathArr;
}
// 找到入口的依赖
console.log(getDepPath(entry)) // ['./App.vue']

写到这里我突然语塞了,emmm vue文件babel咋解析,搞到这里整个人都不开心, 我就删个无用文件咋这么麻烦,本着一行代码能解决绝不用两行的原则,马上开始了第二个方案的尝试

方案2-webpack的统计信息(推荐)

以@vue/cli为例子配置信息

在package.json 给build添加 --report-json 参数

10分钟删除无用500+无用文件,我是如何做的?

运行build命令, 打开dist/report.json, 我们要使用的mudules字段,这个模块记录到了构建过程中使用到的文件,记录的内容很丰富,我们找到自己需要的字段nameForCondition

10分钟删除无用500+无用文件,我是如何做的?

先处理一下自己这个巨长的json文件

const { modules } = require('./dist/report.json');
const fastGlob = require('fast-glob');
const { resolve } = require('path');
const fs = require('fs')

// 所有文件路径
const allFilesPathArr = fastGlob.sync('./src/**/*.{js,vue,png}')
.map( ele => resolve(process.cwd(), ele));

// 过滤出使用到的文件路径
const useModulePathArr = new Set(modules.map( ele => ele.nameForCondition )
.filter( path =>  path && !path.includes('node_modules') ));

// 删除没有使用到的文件
allFilesPathArr.forEach( path => {
    if(useModulePathArr.has(path))return;
    fs.rmSync(path);
})

这个方案还是比较方便的,很快就完成了我要的需求 🎉🎉🎉

总结

本次只实现了文件级别的过滤,还是比较简单的

转载自:https://juejin.cn/post/7131634046374772744
评论
请登录