尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

CRACO 配置入门:从创建 craco.config.js 到理解配置加载机制

发布时间:2026/9/28 2:55:32

资讯中心
01
ARTICLE

CRACO 配置入门:从创建 craco.config.js 到理解配置加载机制

CRACO 配置入门:从创建 craco.config.js 到理解配置加载机制
开发工具前端构建【免费下载链接】cracoCreate React App Configuration Override, an easy and comprehensible configuration layer for Create React App.项目地址https://gitcode.com/gh_mirrors/cr/craco点击查看免费下载导读本文以 Create React App Configuration OverrideCRACO即craco/craco的配置文件为主题系统讲解配置文件如何被创建、查找与加载以及对象字面量、函数、Promise 三种配置导出方式与when系列辅助函数的使用方法。读完本文你将能正确搭建自己的 CRACO 配置文件理解配置文件的优先级解析顺序并掌握用cracoConfig、--config指定自定义配置文件位置以及切换自定义react-scripts的完整实战方案。创建配置文件CRACO 之所以被称为 Configuration Override配置覆盖层是因为它允许你在不执行eject的前提下通过一个独立的配置文件对 Create React App 的默认行为进行定制。根目录 README.md 给出的安装与启用流程非常简单npm i -D craco/craco然后在项目根目录创建一个配置文件并把package.json中的react-scripts start/build/test替换为craco start/build/test。CRACO 支持的配置文件名称有如下六种craco.config.tscraco.config.jscraco.config.cjs.cracorc.ts.cracorc.js.cracorc这六个名称并非随意罗列而是与源码中的实际搜索逻辑一一对应。在 packages/craco/src/lib/config.ts 中CRACO 使用cosmiconfigSync并显式配置了searchPlacesconst moduleName craco; const explorer cosmiconfigSync(moduleName, { searchPlaces: [ package.json, ${moduleName}.config.ts, ${moduleName}.config.js, ${moduleName}.config.cjs, .${moduleName}rc.ts, .${moduleName}rc.js, .${moduleName}rc, ], loaders: { .ts: tsLoader(), }, });注意两点列表第一位是package.json这意味着 cosmiconfig 会尝试把package.json本身当作配置载体通过其中的craco字段但如前所述CRACO 真正推荐的方式是在package.json中指定cracoConfig路径字段.ts后缀的配置文件通过cosmiconfig-typescript-loadertsLoader加载因此 TypeScript 编写的配置文件同样受支持。优先级规则如果同时存在多个配置文件CRACO 将使用列表中排位最靠前的那一个。也就是说craco.config.ts的优先级高于craco.config.js而.cracorc的优先级最低。此外你还可以在package.json中显式指定配置文件路径该方式优先于上述所有自动搜索的文件。指定自定义配置文件位置方式一package.json 中的cracoConfig推荐在package.json中为cracoConfig字段赋值即可指定配置文件的存放位置{ cracoConfig: config/craco-config-with-custom-name.js }该字段的值会被视为相对于项目根目录的路径。在源码 packages/craco/src/lib/config.ts 的getConfigPath中加载顺序为CLI 的--config参数 →package.json中的cracoConfig字段 → cosmiconfig 自动搜索。其中projectRoot取自process.cwd()的真实路径见 packages/craco/src/lib/paths.tsfunction getConfigPath() { const args getArgs(); if (args.config isString(args.config)) { return path.resolve(projectRoot, args.config); } else { const packageJsonPath path.join(projectRoot, package.json); const packageJson require(packageJsonPath); if (packageJson.cracoConfig isString(packageJson.cracoConfig)) { return path.resolve(projectRoot, packageJson.cracoConfig); } else { const result explorer.search(projectRoot); // 找不到任何配置文件时抛出明确错误 if (result null) { throw new Error( craco: Config file not found. check if file exists at root (craco.config.ts, craco.config.js, .cracorc.js, .cracorc.json, .cracorc.yaml, .cracorc) ); } return result.filepath; } } }方式二CLI 的--config参数向后兼容你也可以通过 CLI 选项--config指定配置文件路径{ scripts: { start: craco start --config config/craco-config-with-custom-name.js } }--config与--verbose是 CRACO CLI 内置的两个参数其解析逻辑定义在 packages/craco/src/lib/args.ts 中--config需要紧跟一个值value: true而--verbose是布尔开关。注意cautionCLI 的--config选项不支持 Babel with Jest。如果你的 Jest 配置依赖 Babel 转译请改用package.json中的cracoConfig方式。配置技巧两种覆盖写法CRACO 配置中大量属性如webpack.configure、eslint.configure都支持两种赋值方式对象字面量或函数。文档中很多小节会同时展示这两种写法例如两个同名configure属性一个是对象字面量、一个是函数。对象字面量与原有配置合并module.exports { webpack: { configure: { entry: ./path/to/my/entry/file.js, }, }, };对象字面量写法会被**合并merge**进原始配置。合并由 packages/craco/src/lib/utils.ts 中的deepMergeWithArray完成——它基于 lodash 的mergeWith遇到数组时执行concat拼接而非覆盖export function deepMergeWithArray(dest: any, ...src: any) { return mergeWith(dest, ...src, (x: any, y: any) { if (isArray(x)) { return x.concat(y); } }); }这一合并策略意味着你提供配置中的数组项例如 webpack 插件数组会追加到原有数组之后而不是整体替换掉 CRA 默认的插件列表。函数接收原始配置并返回新配置module.exports { webpack: { configure: (webpackConfig, { env, paths }) { webpackConfig.entry ./path/to/my/entry/file.js; return webpackConfig; }, }, };函数写法将原始配置作为第一个参数传入你可以直接修改它最后必须返回新的配置。第二个可选参数是 context 对象。这一 对象或函数二选一 的模式在类型层面由Configure联合类型定义见 packages/craco-types/src/config.tsexport type ConfigureConfig, Context | Config | ((config: Config, context: Context) Config);Context 对象{ env, paths }函数形式的覆盖属性接收一个可选的第二参数它是一个包含以下属性的单一对象env—— 当前的NODE_ENVdevelopment、production等paths—— 一个包含 CRA 使用的所有路径的对象。paths的具体结构可以从 packages/craco-types/src/context.ts 的CraPaths接口窥见包括appPath、appBuild、appPublic、appHtml、appIndexJs、appSrc、appTsConfig、appPackageJson、testsSetup、proxySetup、appNodeModules等。基础 context 类型BaseContext定义如下export interface BaseContext { env?: string; paths?: CraPaths; }某些配置区块会在 context 中追加额外属性例如jest.configure—— 额外包含resolve与rootDir对应JestContext见 packages/craco-types/src/context.tsdevServer—— 额外包含proxy与allowedHost对应DevServerContext。context 对象的构建过程可见于 packages/craco/src/scripts/start.tsenv在脚本入口处被设置为process.env.NODE_ENV未设置时默认developmentpaths则在读取配置后通过getCraPaths与overridePaths填充。覆盖模式Override modes部分配置区块如eslint、style.postcss拥有mode属性可取以下两个值extends—— 提供的配置将扩展CRA 的默认设置默认值file—— CRA 的设置将被重置你需要为该插件提供一份官方的独立配置文件来全面接管设置。mode的类型约束同样体现在类型定义中例如CracoEsLintConfig.mode?: extends | file与CracoStyleConfig.postcss.mode?: extends | file见 packages/craco-types/src/config.ts。CRACO 的默认配置见 packages/craco/src/lib/config.ts将style.postcss.mode与eslint.mode均预设为extends并默认启用 Jest 的 Babel 预设与插件补充jest.babel.addPresets: true、addPlugins: trueconst DEFAULT_CONFIG: CracoConfig { reactScriptsVersion: react-scripts, style: { postcss: { mode: extends, }, }, eslint: { mode: extends, }, jest: { babel: { addPresets: true, addPlugins: true, }, }, };这份默认配置会在processCracoConfig中通过deepMergeWithArray与你的配置合并packages/craco/src/lib/config.ts因此你无需为这些字段重复填写默认值。配置辅助函数CRACO 提供一组小工具函数用于根据环境按条件生成配置项。它们的实现位于 packages/craco/src/lib/user-config-utils.tsmodule.exports { eslint: { mode: file, configure: { formatter: when( process.env.NODE_ENV CI, require(eslint-formatter-vso) ), }, }, webpack: { plugins: [ new ConfigWebpackPlugin(), ...whenDev(() [new CircularDependencyPlugin()], []), ], }, };when(condition, fn, [unmetValue])类型签名whenT(condition: boolean, fn: () T, unmetValue?: T): T | undefined当condition求值为true时调用fn并返回其结果否则返回unmetValue未提供时返回undefined。源码实现如下export function whenT( condition: boolean, fn: () T, unmetValue?: T ): T | undefined { if (condition) { return fn(); } return unmetValue; }whenDev(fn, [unmetValue])等价于when(process.env.NODE_ENV development, fn, unmetValue)export function whenDevT(fn: () T, unmetValue?: T): T | undefined { return whenT(process.env.NODE_ENV development, fn, unmetValue); }whenProd(fn, [unmetValue])等价于when(process.env.NODE_ENV production, fn, unmetValue)export function whenProdT(fn: () T, unmetValue?: T): T | undefined { return whenT(process.env.NODE_ENV production, fn, unmetValue); }whenTest(fn, [unmetValue])等价于when(process.env.NODE_ENV test, fn, unmetValue)export function whenTestT(fn: () T, unmetValue?: T): T | undefined { return whenT(process.env.NODE_ENV test, fn, unmetValue); }由于这些辅助函数基于NODE_ENV判断它们非常适合在同一份配置中为不同环境注入不同插件或配置项。测试用例可参考仓库 test/unit/merging-tests 下各场景的craco.config.js其中大量使用了条件注入与两种configure写法。导出你的配置CRACO 配置文件支持三种导出方式。需要注意的是函数形式的导出会被传入一个包含当前环境变量的对象例如NODE_ENV这一点与上文介绍的 context 对象不同——顶层导出函数接收的正是{ env, paths }这类 context。对象字面量导出module.exports { ... };函数导出module.exports function ({ env }) { return { ... }; };Promise / Async 函数导出module.exports async function ({ env }) { await ...; return { ... }; };三种导出方式在源码中都有对应处理在 packages/craco/src/lib/config.ts 的getConfigAsObject中配置若是函数则调用result.config(context)取回对象若返回的是 Promise同步版本的loadCracoConfig会直接抛出 Config function returned a promise 错误而start、build、test脚本使用的loadCracoConfigAsync会await该 Promise 后再处理——这也正是 async 导出得以工作的原因export async function loadCracoConfigAsync(context: BaseContext) { const configAsObject await getConfigAsObject(context); if (!configAsObject) { throw new Error(craco: Async config didnt return a config object.); } return processCracoConfig(configAsObject, context); }使用自定义的react-scripts包如果你使用的是 Create React Appreact-scripts的 fork 版本可以在配置中通过reactScriptsVersion指定其包名让 CRACO 从正确的包中加载脚本。省略该属性时默认值为react-scriptsmodule.exports { // ... reactScriptsVersion: custom-react-scripts-package, };该字段在底层的作用非常直接CRACO 所有对 CRA 内部文件的解析都基于react-scripts的config/、scripts/目录通过require.resolve(path.join(cracoConfig.reactScriptsVersion ?? react-scripts, ...))完成见 packages/craco/src/lib/cra.ts例如config/paths.js—— 读取 CRA 路径config/webpack.config.js或 legacy 的webpack.config.dev.js/webpack.config.prod.js—— 加载 webpack 配置config/webpackDevServer.config.js—— 加载 dev server 配置scripts/utils/createJestConfig.js—— 加载 Jest 配置scripts/start.js/build.js/test.js—— 最终启动 CRA 对应脚本。因此reactScriptsVersion不仅决定配置覆盖从哪份配置出发也决定最终调用哪个包的脚本入口。此外packages/craco/src/lib/cra.ts 中的getReactScriptVersion会使用semver校验react-scripts版本是否满足 CRACO 支持的最低大版本当前源码中为5.0.0validate-cra-version.ts 会在启动流程中执行版本校验。小结配置文件可命名为craco.config.ts/js/cjs或.cracorc.ts/js/.cracorc排位越靠前优先级越高package.json的cracoConfig字段与 CLI--config参数可显式指定路径并拥有更高优先级。覆盖属性支持对象字面量深度合并、数组拼接与函数接收原始配置与 context返回新配置两种写法部分区块支持extends/file两种覆盖模式。使用when/whenDev/whenProd/whenTest可按NODE_ENV条件注入配置配置可导出为对象、函数或 async 函数。通过reactScriptsVersion可切换到自定义的react-scriptsfork 包CRACO 会从该包中加载全部 CRA 内部配置与脚本。在此基础上你可以继续阅读 webpack 配置、babel 配置、eslint 配置、jest 配置 等专题文档构建完整的 CRACO 定制方案。赞分享开发工具前端构建【免费下载链接】cracoCreate React App Configuration Override, an easy and comprehensible configuration layer for Create React App.项目地址https://gitcode.com/gh_mirrors/cr/craco点击查看免费下载相关推荐CRACO项目配置入门指南从零开始掌握高级React配置CRACO项目配置入门指南从零开始掌握高级React配置 什么是CRACO CRACOCreate React App Configuration Over开发工具前端构建零基础用 Refly 搭出第一条 AI 工作流从 clone 到出结果零基础用 Refly 搭出第一条 AI 工作流从 clone 到出结果 你手里有一堆竞品链接想让 AI 每天自动搜一遍公开信息、写好对比分析但又不想自己搭人工智能AI 应用大模型AI AgentAgent 工作流AI 技能RAG深入解析XiaoMi/Gaea配置热加载机制深入解析XiaoMi/Gaea配置热加载机制 引言 在现代分布式数据库中间件设计中配置热加载是一个至关重要的功能特性。XiaoMi/Gaea作为一款优秀的数据上一篇Devise插件生态常用扩展插件推荐与使用教程下一篇Xwayland Satellite实战教程10个步骤让Java应用在Wayland下完美运行创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。