treeshaking,webpack,vite

Tree Shaking 在 Vite 项目中是默认启用的,但为了确保最佳效果,你可以采取以下措施来优化未使用代码的移除:

1. 确保使用 ES 模块语法

Vite 默认支持 ES 模块的 Tree Shaking,所以你的代码应该:

// 正确 - 使用 ES 模块导入导出
import { functionA } from './moduleA'
export const functionB = () => {}

// 避免 - CommonJS 语法无法被 Tree Shaking
const _ = require('lodash')
module.exports = {}

2. 配置 Vite 优化选项

在 vite.config.js 中:

import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    // 生产构建的特定配置
    minify: 'terser', // 或 'esbuild'
    terserOptions: {
      compress: {
        // 删除未使用的代码
        unused: true,
        // 删除调试代码
        drop_console: true,
        drop_debugger: true,
      },
    },
    // 启用更激进的 Tree Shaking
    rollupOptions: {
      output: {
        manualChunks: undefined, // 让 Rollup 自动处理代码分割
      },
    },
  },
})

3. 处理第三方库

对于第三方库:

  1. 优先选择 ES 模块版本

    // 使用 lodash-es 而不是 lodash
    import { debounce } from 'lodash-es'

  2. 在 package.json 中标记副作用

    {
      "sideEffects": false,
      // 或者明确列出有副作用的文件
      "sideEffects": [
        "*.css",
        "*.scss",
        "**/*.vue"
      ]
    }

4. 按需导入组件

对于组件库(如 Element Plus、Ant Design Vue):

// 正确 - 按需导入
import { Button } from 'element-plus'

// 避免 - 全量导入
import ElementPlus from 'element-plus'

5. 验证 Tree Shaking 效果

  1. 构建分析

    import { defineConfig } from 'vite'
    import visualizer from 'rollup-plugin-visualizer'
    
    export default defineConfig({
      plugins: [
        visualizer({
          open: true,
          gzipSize: true,
          brotliSize: true,
        }),
      ],
    })

  2. 检查构建输出

    • 运行 vite build 后检查 dist 目录

    • 使用 vite preview 预览生产构建

6. 特殊情况的处理

如果某些代码意外被保留:

  1. 使用 /*#__PURE__*/ 注释

    const result = /*#__PURE__*/ expensiveCalculation()
  2. 动态导入

    // 需要时才加载模块
    const module = await import('./moduleA')

Vite 基于 Rollup 的 Tree Shaking 机制非常高效,遵循以上实践可以确保你的生产构建只包含实际使用的代码,从而显著减少包体积。

Webpack 从版本 2 开始支持 Tree Shaking,但需要正确配置才能有效工作。以下是详细实现方法:

1. 基础配置

必须条件

  • 使用 ES6 模块语法 (import/export)

  • 在生产模式 (mode: 'production') 下自动启用

  • 避免使用 CommonJS 模块语法 (require/module.exports)

webpack.config.js 基础配置

module.exports = {
  mode: 'production', // 生产模式自动启用 Tree Shaking
  optimization: {
    usedExports: true,  // 标记未使用的导出
    minimize: true,     // 启用代码压缩
    concatenateModules: true, // 启用作用域提升(scope hoisting)
  }
};

2. 关键配置详解

Babel 配置

确保 Babel 不转换 ES6 模块语法:

{
  "presets": [
    ["@babel/preset-env", {
      "modules": false // 保留 ES6 模块语法
    }]
  ]
}

package.json 配置

{
  "sideEffects": false,
  // 或明确列出有副作用的文件
  "sideEffects": [
    "*.css",
    "*.scss",
    "*.vue",
    "*.png"
  ]
}

3. 第三方库优化

按需导入

// 正确 - 按需导入
import { debounce } from 'lodash';

// 避免 - 全量导入
import _ from 'lodash';

使用 ES 模块版本

// 使用 lodash-es 而不是 lodash
import { debounce } from 'lodash-es';

4. 高级优化配置

代码分割 + Tree Shaking

optimization: {
  splitChunks: {
    chunks: 'all',
    cacheGroups: {
      vendors: {
        test: /[\\/]node_modules[\\/]/,
        priority: -10,
        reuseExistingChunk: true
      },
      default: {
        minChunks: 2,
        priority: -20,
        reuseExistingChunk: true
      }
    }
  }
}

排除不需要 Tree Shaking 的文件

module: {
  rules: [
    {
      test: /\.css$/,
      sideEffects: true // 标记 CSS 文件有副作用
    }
  ]
}

5. 验证 Tree Shaking 效果

使用分析工具

  1. webpack-bundle-analyzer:

    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
    
    module.exports = {
      plugins: [
        new BundleAnalyzerPlugin()
      ]
    }

  2. 查看未使用导出:

    webpack --display-used-exports

手动检查

  1. 在输出文件中搜索 unused harmony export

  2. 检查最终打包文件中是否包含预期外的代码

6. 常见问题解决

Tree Shaking 不生效的可能原因

  1. 使用了 CommonJS 语法:确保全部使用 ES6 模块

  2. Babel 转换了模块语法:检查 Babel 配置 "modules": false

  3. 第三方库不支持:尝试找 ES 模块版本 (如 lodash-es)

  4. 副作用标记不正确:检查 sideEffects 配置

强制保留某些导出

import { keep } from 'library';
/*@__PURE__*/ keep(); // 使用纯注释标记

通过以上配置,Webpack 可以有效地移除未使用的代码,显著减少最终打包体积。生产环境下 Webpack 的 Tree Shaking 效果通常比开发环境更好,因此务必在生产构建时验证效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每天吃饭的羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值