Lodash按需引入引发的问题

3,418 阅读2分钟

前提

在做项目首屏加载优化时,会通过 BundleAnalyzer 对打包文件进行图形化分析,通过分析对体积较大的第三方库进行拆分打包或者对常用的一些工具库进行按需引入处理,像常见的UI组件库等。
像Lodash是我们在日常开发工作中使用频率较高的一个JS工具库,但是项目中对于Lodash的引入并不优雅(打包后的体积过大)。

接下来我们先简单了解下Lodash的引入:

一、Lodash引入方式

1. 直接引入

// vue页面或者js文件
import _ from 'lodash';
const data = [];
if(_.isEmpty(data)) {
    ...
}

【注】打包后的体积大概是在72kb左右

2. 解构引入

// vue页面或者js文件
import {isEmpty} from 'lodash';
const data = [];
if(isEmpty(data)) {
    ...
}

【注】打包后的体积大概是在72kb左右

3. 具体模块引入

// vue页面或者js文件
import isEmpty from 'lodash/isEmpty';
const data = [];
if(isEmpty(data)) {
    ...
}

【注】打包后只会对用到的具体模块进行打包

综合以上引入方式,虽然具体模块引入方式从最终打包结果来看相对比较友好,但是这里存在一个问题,当一个页面或者js文件中用到较多模块时,就会出现如下:

// vue页面或者js文件
import isEmpty from 'lodash/isEmpty';
import indexOf from 'lodash/indexOf';
import filter from 'lodash/filter';
import debounce from 'lodash/debounce';
...

这样一看,某些情况下反而增加了开发工作量,还不如解构引入方便

二、Lodash按需引入实践

官方提供了插件可以对lodash进行按需引入处理:

  • lodash-webpack-plugin:去除未引用的模块
  • babel-plugin-lodash:类似于webpack的tree-shaking,根据import的引入自动转换为按需加载的形式【tree-shaking:移除上下文中未引用的代码】 具体配置如下:
//vue.config.js
const LodashModuleReplacementPlugin = require("lodash-webpack-plugin"); 
module.exports = {  
  chainWebpack: config => {     
    //按需加载lodash     
    if (process.env.NODE_ENV === "production") {       
      config.plugin("loadshReplace").use(new LodashModuleReplacementPlugin());     
    };   
  } 
} 
// babel.config.js
module.exports = {  
  "plugins":["lodash"] 
}

三、lodash-webpack-plugin按需引入踩坑

通过lodash-webpack-plugin按需引入后会可能产生的问题(目前只测试了以下):

  • map方法只剩下最基本的类似Array map的用法:

    lodash-webpack-plugin在去除未引用模块时,会把某些lodash模块的资源路径替换掉,牺牲一些不常用的接口用法,从而达到打包体积的减小,像map模块最后会被替换为_arrayMap

  • 如果其他第三方库依赖了lodash,一旦项目里配置了按需引入,那么将会影响到第三方模块的使用

总结

在使用Lodash时慎用按需引入,当然其他插件也一样,不要为了使用而使用,一定要多看多分析。