Vue-cli项目实现lodash-es按需加载

lodash优化前大小

webpack配置lodash单独生成一个bundle,优化前体积为3.2M。项目中用到lodash方法并不多,所以这个3.2M应该没有按需加载。

js 复制代码
splitChunk: {
    chunks: 'all',
    cacheGroup: {
        lodash: {
            name: 'lodash',
            test: /[\\/]node_modules[\\/]lodash/,
            chunks: 'all',
            priority: 18
        }
    }
}

写一个webpack插件,协助排查哪些地方用到了lodash。

js 复制代码
class WebpackCustomPlugin {
    apply(compiler) {
        compiler.hooks.comilation.tap('WebpackCustomPlugin', compilation => {
            compilation.hooks.succeedModule.tap('WebpackCustomPlugin', module => {
                const source = module._source?.value
                if (!source) return
                const ast = require('@babel/parser').parse(source, {
                    sourceType: 'module'
                })
                const _this = this
                const traverse = require('@babel/traverse').default
                traverse(ast, {
                    ImportDeclaration(path) {
                        if (path.node.source.value.includes('lodash')) {
                            console.log(module.resource)
                            console.log('path')
                        }
                    }
                })
        
           })
        })
    }
}

输出结果发现:node_modules中有使用lodash,项目中使用的lodash-es, 将lodash和lodash-es分开生成bundle,lodash-es的大小为2.6M,lodash的大小为567KB,由此可知lodash-es按需加载应该存在问题。

webpack将lodash-es导入语句转换成什么样

在项目中是按照下面的方式进行导入的:

js 复制代码
import { omitBy  } from 'lodash-es'

webpack转换后的语句:

js 复制代码
var lodash_es_WEBPCK_IMPORTED_MODULE_10 = __webpack_require__("./node_modules/lodash-es/lodash.js")
lodash_es_WEBPCK_IMPORTED_MODULE_10['omitBy']()

由此可见,lodash-es被全量导入了。

使用babel-plugin-loadsh

babel.config.js 中增加babel-plugin-babel的配置:

js 复制代码
plugins: [
    //...
    [
        'lodash', {
            libraryName: 'loadsh-es',
            libraryDirectory: '',
            camel2DashComponentName: false
        },
        'lodash-es'
    ]
]

增加babel-plugin-loadsh配置后,再次执行发现loadsh-es的大小还是2.6M;检查项目中导入语句import { omitBy } from 'lodash-es'已经正确转换为import omitBy from 'lodash-es/omitBy',那么问题出在哪里呢, 再次通过自定义webpack插件输出所有lodash-es导入语句,发现node_modules下的@antv中loadsh-es导入语句import { isEqual } from 'lodash-es'没有正确转换。

babel-loader默认忽略node_mdouels下的文件

Vue-cli官方说明:

调试Vue-cli发现,babel-loader默认对node_modules下的js文件不处理。Vue-cli中module.rule('js').exclude的默认配置如下:

js 复制代码
// module.rule('js').exclude
(filePath) => {
  // alway transpile js in vue files
  if (/\\.vue\\.jsx?$/.test(filePath)) return false
  // exlude dynamic entries from cli-service
  if (filePath.startWith(cliServicePath)) return true
  // only include @babel/runtime when the @vue/babel-preset-app preset is used
  if (
    process.env.VUE_CLI_TRANSPILE_BABEL_RUNTIME &&
    filePath.includes(path.join("@babel", "runtime"))
  )
    return false
  // check if this is something the user explicity wants to transpile
  if (transpileDepRegex && transpileDepRegex.test(filePath)) return false
  // Don't transpile node_modules
  return /node_modules/.test(filePath)
}

lodash完成按需加载

至此,lodash完成按需加载,优化后的大小为427KB

相关推荐
li357421 小时前
将已有 Vue 项目通过 Electron 打包为桌面客户端的完整步骤
前端·vue.js·electron
Icoolkj21 小时前
VuePress 与 VitePress 深度对比:特性、差异与选型指南
前端·javascript·vue.js
萌萌哒草头将军1 天前
10个 ES2025 新特性速览!🚀🚀🚀
前端·javascript·vue.js
Zz_waiting.1 天前
Javaweb 14.4 Vue3 视图渲染技术
前端·javascript·vue.js
前端开发爱好者1 天前
一键 i18n 国际化神库!适配 Vue、React!
前端·javascript·vue.js
前端开发爱好者1 天前
Vite 移动端调试利器!开发效率飙升 300%!
前端·javascript·vue.js
weixin_456904271 天前
Vscode中开发VUE项目的调试方案
ide·vue.js·vscode
BillKu1 天前
容器元素的滚动条回到顶部
前端·javascript·vue.js
鱼钓猫1 天前
H5 电子签名组件
vue.js·canvas
就是帅我不改1 天前
敏感词过滤黑科技!SpringBoot+Vue3+TS强强联手,打造无懈可击的内容安全防线
前端·vue.js·后端