Skip to content

create-react-app 相关配置

cra是react官方在v18前的默认脚手架,18以后react官方主推 next.js 为代表的SSR框架, 桌面应用这种富客户端软件不适合服务端渲染,所以还是采用cra cra配置路径在 "根目录/craco.config.js"

cra相关配置说明

cra的配置完全兼容webpack

js
const path = require("path")
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer")
const TerserPlugin = require("terser-webpack-plugin")

const { whenProd } = require("@craco/craco")

module.exports = {
	devServer: {
		port: 1718,   // 开发服务器端口号
		open: false   // 不自动打开浏览器
	},
	webpack: {
		alias: {
			'@': path.resolve('src'),  // 设置别名 '@' 指向 'src' 目录
			'@statics': path.resolve(__dirname, 'src/renderer/statics'),  // '@statics' 指向静态资源目录
			'@views': path.resolve(__dirname, 'src/renderer/views'),  // '@views' 指向视图目录
			'@comp': path.resolve(__dirname, 'src/renderer/components'),  // '@comp' 指向组件目录
			'@services': path.resolve(__dirname, 'src/renderer/services'),  // '@services' 指向服务目录
			'@api': path.resolve(__dirname, 'src/renderer/api'),  // '@api' 指向API目录
			'@utils': path.resolve(__dirname, 'src/renderer/utils'),  // '@utils' 指向工具函数目录
			'@redux': path.resolve(__dirname, 'src/renderer/redux'),  // '@redux' 指向Redux相关目录
			'@styles': path.resolve(__dirname, 'src/renderer/styles'),  // '@styles' 指向样式目录
			'@configs': path.resolve(__dirname, 'src/renderer/configs'),  // '@configs' 指向配置文件目录
		},
		publicPath: "/",  // 静态资源的公共路径
		plugins: [
			...whenProd(() => [
				// 打包时生成压缩包(可以通过解开注释启用)
				// new BundleAnalyzerPlugin()
			], [])
		],
		configure: (webpackConfig, { env: webpackEnv, paths }) => {
			webpackConfig.devtool = process.env.NODE_ENV === "development" ? "source-map" : false;  // 开发环境启用source map,生产环境关闭
			webpackConfig.entry = path.resolve(__dirname, 'src', 'renderer/entry/index.js')  // 设置入口文件路径
			webpackConfig.resolve.fallback = {
				"path": false  // 兼容Node.js的path模块API
			};
			webpackConfig.ignoreWarnings = [/Failed to parse source map/]  // 忽略source map解析失败的警告
			webpackConfig.module.rules.push({
				test: /\.(js|mjs|jsx|svg)$/,  // 匹配JavaScript和SVG文件
				enforce: "pre",  // 预处理这些文件
				loader: require.resolve("source-map-loader"),  // 使用source-map-loader加载器
				resolve: {
					fullySpecified: false  // 禁用完全指定模块路径
				}
			})
			whenProd(() => {
				webpackConfig.optimization.minimize = true  // 启用代码压缩
				webpackConfig.optimization.minimizer.map(plugin => {
					if (plugin instanceof TerserPlugin) {
						// 自定义TerserPlugin配置,删除调试信息和console.log
						Object.assign(plugin.options.minimizer.options.compress, {
							drop_debugger: true,  // 删除debugger语句
							drop_console: true,  // 删除所有console语句
							pure_funcs: ["console.log"]  // 删除console.log
						})
					}
					return plugin
				})
				webpackConfig.optimization.runtimeChunk = "single"  // 将运行时代码提取为单个chunk
				webpackConfig.optimization.splitChunks = {
					...webpackConfig.optimization.splitChunks,
					chunks: "all",  // 分割所有的chunk
					minSize: 30000,  // 最小尺寸,超过该尺寸的chunk会被分割
					maxAsyncRequests: 30,  // 最大异步请求数
					maxInitialRequests: 30,  // 最大初始请求数
					cacheGroups: {
						defaultVendors: {
							test: /[\\/]node_modules[\\/]/,  // 分割node_modules中的代码
							name: "vendors"  // 输出文件名为vendors
						},
						antd: {
							test: /antd/,  // 单独分割antd库
							name: "antd",
							priority: 90  // 优先级设为90
						},
						echarts: {
							test: /echarts/,  // 单独分割echarts库
							name: "echarts",
							priority: 90  // 优先级设为90
						},
						zrender: {
							test: /zrender/,  // 单独分割zrender库
							name: "zrender",
							priority: 90  // 优先级设为90
						},
						wangeditor: {
							test: /@wangeditor/,  // 单独分割wangeditor库
							name: "@wangeditor",
							priority: 90  // 优先级设为90
						},
						lodash: {
							test: /lodash/,  // 单独分割lodash库
							name: "lodash",
							priority: 90  // 优先级设为90
						},
						moment: {
							test: /moment/,  // 单独分割moment库
							name: "moment",
							priority: 90  // 优先级设为90
						},
						base: {
							chunks: "all",  // 分割基础框架
							test: /(react|react-dom|react-dom-router)/,  // 匹配react相关库
							name: "base",  // 输出文件名为base
							priority: 100  // 优先级设为100
						},
						commons: {
							chunks: "all",  // 分割公共模块
							minChunks: 2,  // 至少两个chunk共享的模块才会被分割到commons组
							name: "commons",  // 输出文件名为commons
							priority: 110  // 优先级设为110
						}
					}
				}
			})
			return webpackConfig
		}
	},
	babel: {
		plugins: [
			...whenProd(
				() => [
					["@babel/plugin-proposal-decorators", { legacy: true }]  // 支持装饰器语法
				],
				[]
			)
		]
	},
	plugins: [],
	eslint: {
		enable: false  // 禁用ESLint
	}
}