最优实践:如何融入 Lodash
Lodash 是我们很常用的一个库(npm 周下载量是 2.8 亿次,react 是 0.8 亿次,webpack 是 1.1 亿次),但很多人引入 Lodash 并不优雅(打包后的体积过大),本文就带大家来看看 Lodash 常用的几种引入方式。
先写结论,想看细节的话,可以继续。本文所有的代码都在这个仓库中。
结论
- 直接写
import _ from 'lodash';
或import { isEqual } from 'lodash';
引入的是整个 Lodash 包,约 70kb 左右(压缩后),import isEqual from 'lodash/isEqual';
引入的单个使用到的文件,约 15kb 左右(压缩后)。 - 对于已有的项目,很多代码都是前两种写法的,那也不能一个一个的去改吧,是的,可以使用
babel-plugin-lodash
来帮助我们把前两种 变成第三种写法。 - 对于新写的代码,推荐使用
lodash-es
包,因为这可以省去 babel 编译的时间。
直接引入
// one.js
import _ from 'lodash';
console.log(_.isEqual(NaN, NaN));
build 后生成的 js 大小如下:
解构引入
// two.js
import { isEqual } from 'lodash';
console.log(isEqual(NaN, NaN));
build 后如下:
可以看到,都是 72 kb。
具体文件引入
// three.js
import isEqual from 'lodash/isEqual';
console.log(isEqual(NaN, NaN));
build 后如下:
咦,这个时候我们看到了神奇的事情,打包后只有 15 kb,这就说明 webpack 只打包了用到的代码,其他没用到的并没有打包进去。 说明文档也是这样指出的:
那我们就一直这样引入吧,还能做到按需加载,岂不是很 happy,其实不然,当我们引入的方法多了之后,就会变成如下这样:
import isEqual from 'lodash/isEqual';
import chunk from 'lodash/chunk';
import debounce from 'lodash/debounce';
import throttle from 'lodash/throttle';
// ...
这样就写了很多重复的代码,明显没有解构写方便:import { isEqual, chunk, debounce, throttle } from 'lodash';
当然 Lodash 这么牛逼的库不可能想不到这个问题,所以有 babel-plugin-lodash 可以使用,它做的就是一些代码转换,如下:
这个 babel 插件可以让以上 2 种方式都转成 文件引入。棒棒,我们来试一下:
// four.js
import _ from 'lodash';
import { add } from 'lodash/fp';
import isEqual from 'lodash/isEqual';
const addOne = add(1);
_.map([1, 2, 3], addOne);
console.log(isEqual(NaN, NaN));
当我们没有使用 babel-plugin-lodash 时,build 后如下:
167kb,好大。。。用了之后呢?神奇的事情发生了,一样的代码打包之后只有 48kb,nb(antd 也有一个类似的插件,是 babel-plugin-import,大家可以试一下)
只需要在 webpack 中添加如下代码即可:
module: {
rules: [
// other ...
{
loader: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/,
query: {
plugins: ['lodash'],
presets: [['@babel/env', { targets: { node: 6 } }]],
},
},
],
},
如果你的项目代码中,有很多不规范的 import 写法,用这个方法非常友好,但如果你新写的项目,还是推荐你使用如下方式:
使用 es 引入
查看 Lodash 源码的 tag,你会发现有一个 es 分支:
切换到这个 tag 查看代码,如下:
可以看到都是使用 ES Module 的模式引入的,因为 webpack 是一个模块打包器,所以她可以直接解析 ES Module 的代码,所以使用如下引用方式,也可以减小体积:(lodash-es 是一个单独的包;由于这里写都是 var 变量等兼容性很好的代码,所以不需要 babel 编译;推荐看 Lodash 源码的话,使用这个包)
// five.js
import { isEqual, map } from 'lodash-es';
console.log(isEqual(NaN, NaN));
map([1, 2, 3], console.log);
最终,只有 16kb,也很酷!
我是推荐使用 es 引入的,因为这可以减少 babel 编译的时间。(当然这只对于支持 ES Module 语法的才行,如果是 node 使用,还是乖乖地 require 具体文件吧,不过 node 也快要支持 ES Module 了)
推荐阅读
-
35 岁实现财务*,腾讯程序员手握2300万提前退休?-1000万房产、1000万腾讯股票、加上300万的现金,一共2300万的财产。有网友算了一笔账,假设1000万的房产用于自住,剩下1300万资产按照平均税后20-50万不等进行计算,大约花上26-60年左右的时间才能赚到这笔钱。也就是说,普通人可能奋斗一辈子,才能赚到这笔钱。在很多人还在为中年危机而惶惶不可终日的时候,有的人的35岁,就已经安全着陆,试问哪个打工人不羡慕?但问题是有这样财富积累必然有像样的实力做靠山。没有人可以不劳而获。 看到这里,肯定有人说,那么对于普通人来说,卷可能真就成了唯一的出路。但是卷也有轻松的卷,“偷懒”的卷法,对于程序员而言,刨除掉一时无法改掉的开会传统占用的大部分时间,如何把有限的时间和精力放在真正重要的架构设计、需求设计上,而不是重复的造*,编码、改bug、手动测试。因此在科技改变生活的今天,学会使用AI工具成为程序员们的必备技能。 以全栈式全自动的软件开发工具飞算SoFlu软件机器人为例,作为全球首款面向微服务架构设计和最佳实践的软件机器人,SoFlu软件机器人改变了原来手工编码的作业模式,通过可视化拖拽方式以及参数配置就能实现等同于编写复杂代码的业务逻辑,在设计业务逻辑时就完成了微服务应用开发,做到“业务即图,图即代码”,实现“软件开发,十倍提效”。 而作为飞算SoFlu软件机器人的一个重要组成部分,FuncGPT(慧函数)支持所有类型函数创建。通过自然语言描述Java函数需求,实时生成高质量、高可读性的Java函数代码。生成代码可直接复制到IDEA,或一键导入Java全自动开发工具函数库。 FuncGPT(慧函数)具有五大核心能力: ● 自然语言:通过自然语言即可生成函数,降低软件开发门槛。 ● 秒级函数开发:全自动秒级开发函数,秒级完成,效率千倍提升。 ● 一站式函数开发应用:函数生成即可直接应用,效率、安全有保障。 ● 质量可靠:生成的函数代码符合业界规范、具备良好的可读性,符合最优解。 ● 灵活生成:可以根据开发人员的具体需求生成并支持调整和修改。 以“将文件流转换为File对象”这个需求为例,以下是FuncGPT(慧函数)秒级生成的代码: / 类名:FileConverter // 函数名:convertStreamToFile // 函数功能:将文件流转换为File对象 // POM依赖包:无 import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; public class FileConverter { /** * 将文件流转换为File对象 * @param inputStream 文件流 * @param filePath 文件路径 * @param fileName 文件名 * @return 转换后的File对象 * @throws IOException 如果发生I/O异常 */ public static File convertStreamToFile(InputStream inputStream, String filePath, String fileName) throws IOException { File file = new File(filePath + File.separator + fileName); // 创建File对象 try (FileOutputStream outputStream = new FileOutputStream(file)) { // 创建文件输出流 byte buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { // 从文件流读取数据并写入文件 outputStream.write(buffer, 0, bytesRead); } } return file; // 返回转换后的File对象 } } // 函数示例 // 将文件流转换为File对象示例 // 入参:inputStream,文件流 // 入参:filePath,文件路径 // 入参:fileName,文件名 // 出参:file,转换后的File对象 // 调用示例: // InputStream inputStream = new FileInputStream("example.txt"); // String filePath = "C:\\Users\\User\\Documents"; // String fileName = "example.txt"; // File file = FileConverter.convertStreamToFile(inputStream, filePath, fileName); // System.out.println(file.getAbsolutePath); // 输出结果:例如,将文件流转换为File对象后,文件的绝对路径为:C:\Users\User\Documents\example.txt // 则输出结果为:C:\Users\User\Documents\example.txt 通过分析,不难发现以上代码:
-
最优实践:如何融入 Lodash