Files
vf_react/craco.config.js
2025-10-16 10:09:15 +08:00

233 lines
7.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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,
},
// 代理配置:将 /api 请求代理到后端服务器
proxy: {
'/api': {
target: 'http://49.232.185.254:5001',
changeOrigin: true,
secure: false,
logLevel: 'debug',
},
},
},
};