Expo 49 Web构建含Native冗余代码,如何优化缩减体积?
解决方案
1. 改用Expo平台后缀文件规范
调整文件命名,让webpack自动根据平台匹配对应文件,彻底避免手动Platform判断:
- 将
screens/native/dashboard.tsx重命名为screens/dashboard.native.tsx - 保留
screens/web/dashboard.web.tsx(也可统一调整为screens/dashboard.web.tsx,目录结构更简洁) - 在
index.tsx中直接统一导入组件:import Dashboard from './screens/dashboard'; export default function App() { return <Dashboard />; }
Expo的webpack配置会自动根据当前构建平台(web/native)选择对应后缀的文件,web构建时只会打包.web.tsx文件,完全排除native代码。
2. 确保Tree Shaking生效的基础配置
- 强制使用production模式构建:执行
npx expo export:web --mode production,development模式下webpack不会启用tree shaking优化。 - 组件采用ES模块导出:所有平台专属组件使用
export default或export const方式导出,避免CommonJS格式(module.exports),否则tree shaking无法识别未使用代码。 - 静态化Platform判断逻辑:不要将
Platform.OS赋值给变量后再判断,直接写if (Platform.OS === 'web'),Expo web构建会在编译阶段将Platform.OS替换为静态字符串'web',让webpack能识别并移除死代码。
3. 动态导入优化(适合需保留Platform判断的场景)
如果必须保留手动平台判断逻辑,使用动态导入让webpack按需打包对应平台代码:
import { Suspense } from 'react'; export default function App() { return ( <Suspense fallback={<div>Loading...</div>}> <PlatformSpecificDashboard /> </Suspense> ); } async function PlatformSpecificDashboard() { if (Platform.OS === 'web') { const { default: WebDashboard } = await import('./screens/web/dashboard.web'); return <WebDashboard />; } else { const { default: NativeDashboard } = await import('./screens/native/dashboard'); return <NativeDashboard />; } }
动态导入会让webpack将不同平台的代码拆分为单独chunk,web构建时只会包含web相关的chunk。
4. 自定义Webpack配置增强Tree Shaking
在项目根目录创建webpack.config.js,优化webpack的tree shaking能力:
const createExpoWebpackConfigAsync = require('@expo/webpack-config'); module.exports = async function(env, argv) { const config = await createExpoWebpackConfigAsync(env, argv); // 开启usedExports和sideEffects优化 config.optimization = { ...config.optimization, usedExports: true, sideEffects: true, }; return config; };
同时在package.json中添加"sideEffects": false(若项目中无需要保留副作用的文件),或明确列出有副作用的文件路径,帮助webpack更精准地移除未使用代码。
内容的提问来源于stack exchange,提问作者krishnakirit04
相关产品推荐
相关产品推荐

