当前位置: 首页 > 知识库问答 >
问题:

通过vite中rollup打包,如何对lodash做按需打包?

龙焱
2024-08-06

通过vite中rollup打包,如何对lodash做按需打包?

import {throttle} from 'lodash'
import throttle from 'lodash/throttle'

这两种写法在build时 第一种dist体积比第二种要大。都说是第一种写法是将整个lodash打包进了dist。我这里有一个疑问,rollup在build时不是会对代码做按需打包吗? rollup的树摇不会起作用吗? 假设整个项目只使用了一个throttle函数,也会将整个lodash打包到dist吗?

虽然lodash是 cjs规范的,我理解在编译是应该会被转换成esm。
node_modules/lodash包里每个函数都是单独文件,在node_modules/lodash/index.js里仅仅对这些文件做了集合 按理说这种分散的方式会被按需打包啊。
我在网上查了说rollup的树摇操作只能识别esm模块?

共有3个答案

尉迟栋
2024-08-06

你找的资料都是对的,可以考虑换 lodash-es

单于飞鸣
2024-08-06

能否做 tree-shaking 要看lodash 的导出方式,

// index.js

export { default as throttle } from "./throttle.js"
// 如果是这样的导出,那么会启动tree-shaking , 只打包 throttle 
// index.js
export function throttle (){

}
// 如果是这样的导出,那么整个index.js 都会被打包

loadash 有 esm 版本的 lodash-es

lodash 的cjs版本使用的是 module.exports = { throttle }
这种方式不会触发 tree-shaking , 因为 esm 才是官方支持 cjs 是社区规范

杨雪松
2024-08-06

在Vite中使用Rollup进行打包时,确实可以优化打包体积,但这依赖于几个关键因素,包括模块的类型(ESM vs CJS)、导入语句的写法以及Rollup插件的配置。对于lodash这样的库,尽管它内部是模块化的(每个函数作为单独的文件存在),但如果你直接从lodash包的主入口文件导入(即使用import {throttle} from 'lodash'),Rollup可能无法有效地进行树摇(Tree Shaking),因为这通常依赖于ES模块(ESM)的静态导入分析。

解释

  1. ESM vs CJS:

    • ESM(ECMAScript Modules)支持静态分析,这意味着Rollup可以在打包前确定哪些代码是实际需要的,哪些可以被排除。
    • CJS(CommonJS)模块则不支持这种静态分析,因为CommonJS的require调用是动态的,Rollup难以在编译时确定具体需要哪些部分。
  2. lodash的导入方式:

    • 当你使用import {throttle} from 'lodash'时,你实际上是从lodash的CJS主入口文件导入,这个文件可能包含了lodash的所有功能或至少是一个包含大量功能的集合。Rollup在这种情况下可能无法精确地进行树摇,因为它依赖于lodash内部模块化的结构来识别哪些部分被实际使用。
    • 使用import throttle from 'lodash/throttle'时,你直接从lodash的ESM构建中导入单独的throttle模块,这样Rollup可以更容易地识别并只包含这个特定的模块。
  3. Rollup的配置:

    • 确保你的Rollup配置或Vite配置启用了对ESM的支持,并且配置了适当的插件来处理node_modules中的依赖。

解决方案

  • 使用直接导入: 尽可能使用import throttle from 'lodash/throttle'这样的直接导入方式,以确保只包含所需的lodash函数。
  • 配置Rollup插件: 如果你需要处理一些特殊情况或想要进一步优化打包体积,可以考虑使用Rollup插件,如@rollup/plugin-commonjs来转换CommonJS模块为ESM,但这通常不是必要的,因为lodash已经提供了ESM版本。
  • 检查Vite配置: 确保Vite配置正确,以支持ESM和树摇。

结论

虽然lodash的CJS主入口文件试图通过内部模块化的方式支持树摇,但直接从该入口文件导入时,Rollup可能无法有效地识别并排除未使用的代码。最佳实践是直接从lodash的ESM入口导入所需的函数,以确保只包含必要的代码。

 类似资料:
  • 本文向大家介绍Webpack实现按需打包Lodash的几种方法详解,包括了Webpack实现按需打包Lodash的几种方法详解的使用技巧和注意事项,需要的朋友参考一下 前言 在数据操作时,Lodash 就是我的弹药库,不管遇到多复杂的数据结构都能用一些函数轻松拆解。 ES6 中也新增了诸多新的对象函数,一些简单的项目中 ES6 就足够使用了,但还是会有例外的情况引用了少数的 Lodash 函数。一

  • vite打包如何不生成vite.svg,index应用的favicon已经改为别的图标,打包还是带vite.svg,如何配置可不生成vite.svg?

  • 现在遇到个这么个需求,就是项目用的vite的打包工具 我现在想实现把项目用vite打包, 然后把项目中的其中一两个组件也单独打包成一个js,类似于把其中一两个组件打包成组件库的js 也就是执行npm run build的时候既打包了项目,又打包了其中部分组件为组件库的js,供外部html直接引入这个打包好的js进行使用,这个有办法实现吗

  • 通过rollup打包test.js,打包后文件中出现Symbol关键字 源文件:test.js 打包后文件:test.min.js rollup配置文件:rollup.config.js 期望能够不生成Symbol.toPrimitive或者生成Symbol的polyfill。能在不支持ES6环境正常运行

  • 问题内容: 我在这方面是一个初学者,因此我正在努力使它起作用。 当按下按钮时,我只是希望拨号器以自动输入的指定号码打开。 到目前为止,我已经尝试了以下方法: 我也尝试过: 我已将权限ACTION_CALL添加到清单中。 每当我单击“呼叫”按钮时,应用程序强制关闭。 任何帮助将不胜感激。 谢谢! 问题答案: 您需要将此权限添加到清单中。

  • 问题内容: 你们可以帮我将以下代码翻译成Swift吗? (或者我是否必须使用此链接: _itms://itunes.apple.com/app/id839686104_ ?) 提前致谢! 问题答案: 这里。但我强烈建议您学习Swift的基础知识!