资讯专栏INFORMATION COLUMN

借助webpack对项目进行分析优化

Me_Kun / 3473人阅读

摘要:由于项目的不断扩大,只会影响我们定位功能和问题的速度,因此对冗余文件进行清理,是很重要的。我们在项目中使用的,自动将各个图标进行。

进入公司之后,接手的便是前人留下来的一个大项目。庆幸的是整个项目拥有完善的产品功能文档,但是由于项目过于庞大,老旧。包含了打包过慢,冗余文件过多等诸多问题。想要快速的解决这些问题,想要完全把功能重构一遍的话,成本太高了。一个一个文件来过,时间成本也比较大。因此在此篇文章中,我们介绍一下我是如何配合webpack一步步进行分析,将项目进行优化的。
同时我针对思路封装了一个webpack-unused-files,用于查找项目中的冗余文件,欢迎试用并star
原文链接
问题

首先,我们先大致看下我们都有什么问题,然后一步步进行解决

项目频繁进行修改,冗余文件过多

部分第三方依赖滥用,想去除但是不知道在哪个文件中。或没用,但是遗留在package.json里,

项目庞大,打包的结果过大,时间过长

删除冗余文件

由于项目的频繁改动,有很多文件已经不被使用并且没有被删除。由于项目的不断扩大,只会影响我们定位功能和问题的速度,因此对冗余文件进行清理,是很重要的。但是我们单凭肉眼很难识别哪个文件是否被依赖的,因此还要通过webpack来解决。

1.获取项目依赖的所有文件

我们来看一下webpack的输出文件格式:

{
  ...
  chunks: [{
    name: "chunk-name",
    modules: [
      // 每个chunk中所有的依赖文件
    ]
  }]
  ...
}

所以说,根据这个stats.json,我们可以拿到在整个项目中拿到的所有项目文件:

/**
 * 查询依赖的模块
 */
function findSrcModules () {
  return new Promise((resolve, reject) => {
    fs.readFile(statPath, (err, data) => {
      if (err) return
      const json = JSON.parse(data)
      const assetsList = json.chunks
      let ret = []
      // 拿到所有chunk的所有依赖文件
      assetsList.forEach(chunk => {
        const modules = chunk.modules.map(item => item.name)
        ret = ret.concat(modules)
      })
      // 去除node_modules中的文件
      ret = ret.filter(item => item.indexOf("node_modules") < 0)
      resolve(ret)
    })
  })
}

通过这一步,我们可以拿到项目中,所有打包依赖的文件。

2.获取项目中所有的文件

通过glob,我们可以获取所有的文件:

function getAllFilesInSrc () {
  const pattern = "./src/**"

  return new Promise((resolve, reject) => {
    glob(pattern, {
      nodir: true
    }, (err, files) => {
      const ret = files.map(item => {
        return item.replace("./src", ".")
      })
      resolve(ret)
    })
  })
}
3.将两个文件数组进行对比,然后进行删除等操作:

将两个数组进行对比,没有出现在依赖中的文件,就是冗余文件。我们可以一键删除

findSrcModules().then(ret => {
  getAllFilesInSrc().then(allFiles => {
    const unUsed = allFiles.filter(item => {
      return ret.indexOf(item) < 0
    })
    const join = p => path.join("./src", p)

    unUsed.forEach(file => {
      shelljs.rm(join(file))
    })
  })
})
分析第三方依赖

根据上述冗余文件的思路,我们同样可以对第三方依赖进行处理,大致思路如下

获取所有包含node_modules的依赖

将文件名进行截取、去重。获取到所有的依赖

与package.json进行对比,拿到没有使用的依赖

将对比结果进行分析,将不想使用的依赖保存下来

再次查找stat.json,查找该依赖的reson字段,获取再哪里引用了该依赖,进行输出

将依赖进行手动替换、删除等操作

可以说,拿到了所有依赖及依赖关系,我们可以很灵活的对其进行处理,拿到我们想要的结果。

该功能后续也会更新到webpack-unused-files中去。

优化打包大小

让人震惊的是,整个项目由于种种原因,打包后的大小有近20M的大小!虽然并不是TO C项目,并且针对页面进行了代码拆分和懒加载,但是作为一个“合格的前端”,这种现象是一定要修改的(没错!)。该如何下手呢?一个个的翻代码,看看我们都引用了什么大依赖,看哪些项目过大未免太复杂了。我们看看webpack给我吗提供了什么方案:

1.展示打包结果

我们知道,在webpack打包结束后,会自动在控制台显示打包结果。同时,他也提供了输出依赖及大小的功能,我们执行以下参数, 便可将所有的依赖进行展示,并且看到他们的大小了。

webpack --display-modules --sort-modules-by size

结果类似这样:

我们可以很快的定位到排名前几的js文件或者第三方依赖,决定该如何对其进行处置。

2.可视化分析依赖

webpack提供了一个功能,将打包的所有依赖文件以及关系,以json格式进行输出:

webpack --profile --json > stats.json

这是我们整篇文章的一个基础,很多人基于此封装了不少可视化分析的工具,可以直观的看到各个
文件、chunk之间的依赖关系以及大小等,快速定位到大文件、大模块

webpack analyse

webpack chart

3.优化方案

通过以上两种方法,我们可以很好的对内容文件和依赖进行定位和分析,针对打包大小的优化方案网上已经有很多了,在此不再进行赘述,提供几个思路及参考:

CommonsChunkPlugin提取公共代码

dll-plugin进行大文件多带带打包,缓存

删除无用的依赖(后面会提到

选择性的弃用一些依赖

代码压缩

babel-polyfill

Scope Hoisting

优化打包时间

针对打包时间的优化的文章其实也很多了,我们在此仅提供一些思路。我们主要提一点,通过构建会发现,项目中引用了大量的svg图标以及国旗图标,每次在静态资源处理中,打包时间就会变的特别慢。

我们在项目中使用的svg-sprite-loader,自动将各个svg图标进行svg-spirte。但是我们知道,这些图标一旦引用,我们很少进行修改。尤其是像国旗图标这种,但是每次构建我们都需要进行重复打包。因此,我们可以提前把这些图标进行svg-sprite。推荐一个网站,将各种svg图标提前进行sprite并自动进行引用:

iconmoon

日常打包时间优化点

externals 避免打包大的第三方依赖

dll-plugin 预打包第三方依赖

happypack 多进程处理,缓存

缓存与增量构建

babel-loader?cacheDirectory

webpack cache:true

减少构建搜索或编译路径 alias resolve

具象打包的范围 include exclude

总结

通过对webpack输出依赖关系的json的分析,我们可以直观的拿到以下数据:

所有依赖文件及其大小

每个依赖文件是被哪些文件引用的

项目依赖的第三方依赖

通过这些数据,我们可以很方便的对现有项目进行优化。

生命不息,倒腾不止。让我们对所有的恶心代码说再见!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94203.html

相关文章

  • 用十分之一的构建时间做一场页面静态资源依赖分析

    摘要:不直接使用的原因很简单首先构建一次实在太慢了,特别是有几十个页面存在的情况下,另一个原因是我只是想拿到资源依赖,我根本不想对整个前端进行一次构建,也不想生成任何。这就达到了本文题目中目的,用十分之一的构建时间做一场页面静态资源依赖分析。原文链接 作者:梯田 前言: 所谓【静态资源依赖分析】,指的是可以通过分析页面资源后,可以以 json 数据或者图表的方式拿到页面资源间的依赖关系。 比如 c...

    B0B0 评论0 收藏0
  • 基于webpack4的VUE多页脚手架

    摘要:另外备注一部分参数的说明折叠有助于文档树中文本节点的空白区域对进行压缩默认默认按照不同文件的依赖关系来排序。敲黑板讲重点的当然目前这部分的文档在官网还不是很全,所以这里我们参考了印记中文的说明文档,指优化模块。 链接 写在前面 为什么要自己手写一个脚手架? 如何去思考遇到的问题? 正文 链接 原文链接 github whale-vue ——写在前面 1、为什么要自己手写...

    张金宝 评论0 收藏0
  • 从零到一,新建webpack工程

    摘要:指定启用例如上述代码,就使用和处理了除了以外的。设置当前的为,同样这个配置也可以写在中。设置目录删除注释去除空格去除属性引号复制静态目录将所以可能被请求的静态文件,分别放在目录下。结语本次从零到一,新建了一个脚手架。 react-sample-javascript 为了实现一个可定制化高的react工程,我们往往会自己搭建一个react工程。所以本文会从零开始搭建一个react脚手架工...

    Code4App 评论0 收藏0
  • webpack优化

    摘要:使用要给项目构建接入动态链接库的思想,需要完成以下事情把网页依赖的基础模块抽离出来,打包到一个个单独的动态链接库中去。接入已经内置了对动态链接库的支持,需要通过个内置的插件接入,它们分别是插件用于打包出一个个单独的动态链接库文件。 webpack优化 查看所有文档页面:全栈开发,获取更多信息。原文链接:webpack优化,原文广告模态框遮挡,阅读体验不好,所以整理成本文,方便查找。 ...

    ChanceWong 评论0 收藏0
  • 基于 react, redux 最佳实践构建的 2048

    摘要:最佳实践一个文件一个组件。,这是包含的是无副作用的纯函数式计算状态操作的函数。,的启动脚本,启动开发模式,项目打包,运行单元测试等等。每次代码推送到之前也会执行所有单元测试用例,全部通过才可以继续推送。,首次安装依赖包之后生成的文件。 前段时间 React license 的问题闹的沸沸扬扬,搞得 React 社区人心惶惶,好在最终 React 团队听取了社区意见把 license 换...

    Eidesen 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<