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

相关推荐
谁呛我名字2 小时前
大数据应用开发——数据可视化
javascript·vue.js·echarts
神夜大侠7 小时前
VUE 实现公告无缝循环滚动
前端·javascript·vue.js
明辉光焱7 小时前
【Electron】Electron Forge如何支持Element plus?
前端·javascript·vue.js·electron·node.js
王解8 小时前
【模块化大作战】Webpack如何搞定CommonJS与ES6混战(3)
前端·webpack·es6
杨荧10 小时前
【JAVA毕业设计】基于Vue和SpringBoot的宠物咖啡馆平台
java·开发语言·jvm·vue.js·spring boot·spring cloud·开源
NoloveisGod11 小时前
Vue的基础使用
前端·javascript·vue.js
GISer_Jing11 小时前
前端系统设计面试题(二)Javascript\Vue
前端·javascript·vue.js
理想不理想v12 小时前
使用JS实现文件流转换excel?
java·前端·javascript·css·vue.js·spring·面试
EasyNTS12 小时前
无插件H5播放器EasyPlayer.js网页web无插件播放器vue和react详细介绍
前端·javascript·vue.js
guokanglun13 小时前
Vue.js动态组件使用
前端·javascript·vue.js