序言
Hello,大家好,我是kamesan。
说到减少打包体积,最常听到的说法就是按需引入,也就是下面这种写法
// 以element-plus为例
import { ElButton } from 'element-plus'
通过按需引入,我们可以只打包ElButton相关的js文件,可以极大程度的减少打包文件的体积。
打包分析工具
在这里给大家介绍一个分析打包文件的工具rollup-plugin-visualizer,通过配置该工具可以在根目录生成一个stats.html文件,打开后就能看到项目打包后各个依赖的使用情况,我在这里给出一个最简的配置。
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { visualizer } from 'rollup-plugin-visualizer';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
visualizer({
gzipSize: true,
}),
],
})
全量引入和按需引入
回归正题,我们看一下全量引入element-plus和按需引入ElButton在打包后差距会有多大。
全量引入
按需引入
从直观的视觉对比中,全量引用与按需引入的差异一目了然,这种差异不仅体现在模块覆盖的范围上,更显著地反映在文件体积的占用上。具体而言,全量引用的文件大小膨胀至1.45MB,而按需引入的文件仅占用16.95KB。
按需引入的隐式隐患
这里就引申出了一个问题,只要使用import { xxx } from 'xxx'的写法就一定是按需引入吗?我们来看一个例子。
import { isArray } from 'lodash';
console.log(isArray(['1']))
我们跑一遍build看一下打包的情况
可以看出整个
lodash都被打包进去了,那为什么使用了按需引入的写法却没有达到按需引入的效果呢?我们可以通过查看node_modules里lodash的文件得到答案
lodash库在使用CommonJS模块系统时,并非通过单独导入和导出
isArray方法来构建。相反,它导出的是一个完整的lodash对象。
与之相反的是element-plus,使用了非常规范的import和export,所以我们才可以通过使用按需引入的方式只打包我们所需的部分。
如何真正的按需引入
以lodash为例,如果想要真正做到按需引入的效果,可以通过下面几种方式实现
1. 只import自己需要的方法
import isArray from 'lodash/isArray';
console.log(isArray(['1']))
打包效果
2. 使用对应的插件
这边网上的资料比较常见的都是webpack的插件,vite相关的应该也有但是比较少,不太推荐
3.使用依赖的es版本
以lodash为例,官方提供了lodash-es,可以方便的让我们使用按需引入
import { isArray } from 'lodash-es'
console.log(isArray(['1']))
打包效果
总结
不要觉得使用了ES标准的导入语法就能实现按需引入的效果,通过打包分析才能看出效果,多看官方的文档说明,一般里面都会有提及如何按需引入。
Extra quiz
不知道大家有没有用过highlight.js,大家可以模拟自己使用到这个的场景并进行优化,欢迎在评论区进行分享。