feat: 优化构建速度和包大小
This commit is contained in:
223
craco.config.js
Normal file
223
craco.config.js
Normal file
@@ -0,0 +1,223 @@
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const { BundleAnalyzerPlugin } = process.env.ANALYZE ? require('webpack-bundle-analyzer') : { BundleAnalyzerPlugin: null };
|
||||
|
||||
module.exports = {
|
||||
webpack: {
|
||||
configure: (webpackConfig, { env, paths }) => {
|
||||
// ============== 持久化缓存配置 ==============
|
||||
// 大幅提升二次构建速度(可提升 50-80%)
|
||||
webpackConfig.cache = {
|
||||
type: 'filesystem',
|
||||
cacheDirectory: path.resolve(__dirname, 'node_modules/.cache/webpack'),
|
||||
buildDependencies: {
|
||||
config: [__filename],
|
||||
},
|
||||
// 增加缓存有效性检查
|
||||
name: env === 'production' ? 'production' : 'development',
|
||||
compression: env === 'production' ? 'gzip' : false,
|
||||
};
|
||||
|
||||
// ============== 生产环境优化 ==============
|
||||
if (env === 'production') {
|
||||
// 高级代码分割策略
|
||||
webpackConfig.optimization = {
|
||||
...webpackConfig.optimization,
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
maxInitialRequests: 30,
|
||||
minSize: 20000,
|
||||
maxSize: 244000, // 限制单个 chunk 最大大小(约 244KB)
|
||||
cacheGroups: {
|
||||
// React 核心库单独分离
|
||||
react: {
|
||||
test: /[\\/]node_modules[\\/](react|react-dom|react-router-dom)[\\/]/,
|
||||
name: 'react-vendor',
|
||||
priority: 30,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
// 大型图表库分离(echarts, d3, apexcharts 等)
|
||||
charts: {
|
||||
test: /[\\/]node_modules[\\/](echarts|echarts-for-react|apexcharts|react-apexcharts|recharts|d3|d3-.*)[\\/]/,
|
||||
name: 'charts-lib',
|
||||
priority: 25,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
// Chakra UI 框架
|
||||
chakraUI: {
|
||||
test: /[\\/]node_modules[\\/](@chakra-ui|@emotion)[\\/]/,
|
||||
name: 'chakra-ui',
|
||||
priority: 22,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
// Ant Design
|
||||
antd: {
|
||||
test: /[\\/]node_modules[\\/](antd|@ant-design)[\\/]/,
|
||||
name: 'antd-lib',
|
||||
priority: 22,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
// 3D 库(three.js)
|
||||
three: {
|
||||
test: /[\\/]node_modules[\\/](three|@react-three)[\\/]/,
|
||||
name: 'three-lib',
|
||||
priority: 20,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
// 日期/日历库
|
||||
calendar: {
|
||||
test: /[\\/]node_modules[\\/](moment|date-fns|@fullcalendar|react-big-calendar)[\\/]/,
|
||||
name: 'calendar-lib',
|
||||
priority: 18,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
// 其他第三方库
|
||||
vendor: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name: 'vendors',
|
||||
priority: 10,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
// 公共代码
|
||||
common: {
|
||||
minChunks: 2,
|
||||
priority: 5,
|
||||
reuseExistingChunk: true,
|
||||
name: 'common',
|
||||
},
|
||||
},
|
||||
},
|
||||
// 优化运行时代码
|
||||
runtimeChunk: 'single',
|
||||
// 使用确定性的模块 ID
|
||||
moduleIds: 'deterministic',
|
||||
// 最小化配置
|
||||
minimize: true,
|
||||
};
|
||||
|
||||
// 生产环境禁用 source map 以加快构建(可节省 40-60% 时间)
|
||||
webpackConfig.devtool = false;
|
||||
} else {
|
||||
// 开发环境使用更快的 source map
|
||||
webpackConfig.devtool = 'eval-cheap-module-source-map';
|
||||
}
|
||||
|
||||
// ============== 模块解析优化 ==============
|
||||
webpackConfig.resolve = {
|
||||
...webpackConfig.resolve,
|
||||
alias: {
|
||||
...webpackConfig.resolve.alias,
|
||||
'@': path.resolve(__dirname, 'src'),
|
||||
'@components': path.resolve(__dirname, 'src/components'),
|
||||
'@views': path.resolve(__dirname, 'src/views'),
|
||||
'@assets': path.resolve(__dirname, 'src/assets'),
|
||||
'@contexts': path.resolve(__dirname, 'src/contexts'),
|
||||
},
|
||||
// 减少文件扩展名搜索
|
||||
extensions: ['.js', '.jsx', '.json'],
|
||||
// 优化模块查找路径
|
||||
modules: [
|
||||
path.resolve(__dirname, 'src'),
|
||||
'node_modules'
|
||||
],
|
||||
// 优化符号链接解析
|
||||
symlinks: false,
|
||||
};
|
||||
|
||||
// ============== 插件优化 ==============
|
||||
// 移除 ESLint 插件以提升构建速度(可提升 20-30%)
|
||||
webpackConfig.plugins = webpackConfig.plugins.filter(
|
||||
plugin => plugin.constructor.name !== 'ESLintWebpackPlugin'
|
||||
);
|
||||
|
||||
// 添加打包分析工具(通过 ANALYZE=true 启用)
|
||||
if (env === 'production' && process.env.ANALYZE && BundleAnalyzerPlugin) {
|
||||
webpackConfig.plugins.push(
|
||||
new BundleAnalyzerPlugin({
|
||||
analyzerMode: 'static',
|
||||
openAnalyzer: true,
|
||||
reportFilename: 'bundle-report.html',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// 忽略 moment 的语言包(如果项目使用了 moment)
|
||||
webpackConfig.plugins.push(
|
||||
new webpack.IgnorePlugin({
|
||||
resourceRegExp: /^\.\/locale$/,
|
||||
contextRegExp: /moment$/,
|
||||
})
|
||||
);
|
||||
|
||||
// ============== Loader 优化 ==============
|
||||
const babelLoaderRule = webpackConfig.module.rules.find(
|
||||
rule => rule.oneOf
|
||||
);
|
||||
|
||||
if (babelLoaderRule && babelLoaderRule.oneOf) {
|
||||
babelLoaderRule.oneOf.forEach(rule => {
|
||||
// 优化 Babel Loader
|
||||
if (rule.loader && rule.loader.includes('babel-loader')) {
|
||||
rule.options = {
|
||||
...rule.options,
|
||||
cacheDirectory: true,
|
||||
cacheCompression: false,
|
||||
compact: env === 'production',
|
||||
};
|
||||
// 限制 Babel 处理范围
|
||||
rule.include = path.resolve(__dirname, 'src');
|
||||
rule.exclude = /node_modules/;
|
||||
}
|
||||
|
||||
// 优化 CSS Loader
|
||||
if (rule.use && Array.isArray(rule.use)) {
|
||||
rule.use.forEach(loader => {
|
||||
if (loader.loader && loader.loader.includes('css-loader') && loader.options) {
|
||||
loader.options.sourceMap = env !== 'production';
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ============== 性能提示配置 ==============
|
||||
webpackConfig.performance = {
|
||||
hints: env === 'production' ? 'warning' : false,
|
||||
maxEntrypointSize: 512000, // 512KB
|
||||
maxAssetSize: 512000,
|
||||
};
|
||||
|
||||
return webpackConfig;
|
||||
},
|
||||
},
|
||||
|
||||
// ============== Babel 配置优化 ==============
|
||||
babel: {
|
||||
plugins: [
|
||||
// 运行时辅助函数复用
|
||||
['@babel/plugin-transform-runtime', {
|
||||
regenerator: true,
|
||||
useESModules: true,
|
||||
}],
|
||||
],
|
||||
loaderOptions: {
|
||||
cacheDirectory: true,
|
||||
cacheCompression: false,
|
||||
},
|
||||
},
|
||||
|
||||
// ============== 开发服务器配置 ==============
|
||||
devServer: {
|
||||
hot: true,
|
||||
port: 3000,
|
||||
compress: true,
|
||||
client: {
|
||||
overlay: false,
|
||||
progress: true,
|
||||
},
|
||||
// 优化开发服务器性能
|
||||
devMiddleware: {
|
||||
writeToDisk: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user