
开发工具前端构建【免费下载链接】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的eslint配置段展开讲解如何在不 eject 的前提下覆盖 CRA 内置的 ESLint 设置包括启用开关、两种 override 模式、配置合并函数与 ESLint Webpack Plugin 参数定制并结合仓库源码解释每个选项的底层行为。读完本文你将能写出可复现、可维护的craco.config.jsESLint 配置并理解 CRACO 是如何在构建链中完成这些覆盖的。一、为什么需要 CRACO 来定制 ESLintCreate React AppCRA把 ESLint 的配置固化在react-scripts内部它通过ESLintWebpackPlugin在开发与构建时进行代码检查预设了react-app规则集。直接修改package.json里的eslintConfig只能叠加规则无法改变插件本身的运行方式例如切换成读取独立.eslintrc文件。CRACO 提供了一层的eslint配置段让你在保持 CRA 工作流的同时对 ESLint 的配置与插件选项做精细化覆盖这正是本仓库中 eslint.ts 模块的核心职责。二、eslint 配置段总览在craco.config.js中eslint段支持四个属性官方文档给出了完整骨架见 eslint.mdmodule.exports { // ... eslint: { enable: true /* (default value) */, mode: extends /* (default value) */ || file, configure: { /* ... */ }, configure: (eslintConfig, { env, paths }) { /* ... */ return eslintConfig; }, pluginOptions: { /* ... */ }, pluginOptions: (eslintPluginOptions, { env, paths }) { /* ... */ return eslintPluginOptions; }, }, };注意骨架中configure与pluginOptions各出现了两次这并非笔误而是表示它们既可以赋值为对象字面量也可以赋值为函数。关于这种对象或函数二选一的通用约定详见 getting-started.md 中的 Object literals and functions 一节。从类型定义config.ts可以看到每个字段的精确类型export interface CracoEsLintConfig { enable?: boolean; mode?: extends | file; configure?: ConfigureLinter.Config, BaseContext; pluginOptions?: ConfigurePluginOptions, BaseContext; }ConfigureConfig, Context表示Config | ((config, context) Config)即对象字面量或函数二选一Linter.Config来自 ESLint 自身的类型即官方 ESLint 配置对象PluginOptions来自eslint-webpack-plugin即该 webpack 插件支持的选项集。三、eslint.enable总开关类型boolean true作用控制 ESLint 是否启用。默认值为true即保持 CRA 原生的 ESLint 行为。在源码 eslint.ts 中overrideEsLint首先判断enable false若为假则直接调用disableEslintif (enable false) { disableEslint(webpackConfig); return webpackConfig; }disableEslint通过removePlugins按名称移除构建配置中的ESLintWebpackPluginfunction disableEslint(webpackConfig: WebpackConfig) { const { hasRemovedAny } removePlugins( webpackConfig, pluginByName(ESLintWebpackPlugin) ); if (hasRemovedAny) { log(Disabled ESLint.); } else { logError(Couldnt disabled ESLint.); } }从源码结构可以推断当插件成功被移除时CRACO 会打印 Disabled ESLint. 日志若找不到该插件例如自定义配置里已把它改名为其他构造器则会打印错误提示但不会中断构建。如果你出于性能考虑想关闭代码检查可这样配置module.exports { eslint: { enable: false, }, };四、eslint.mode两种覆盖模式类型extends | file extends作用决定configure中的配置如何与 CRA 默认 ESLint 设置结合。这是 CRACO 通用的override modes机制在该配置段的应用完整语义见 getting-started.md 的 Override modes 一节extends默认你提供的配置将扩展CRA 的设置即与内置配置合并fileCRA 的内置设置将被重置你需要提供一份官方的 ESLint 配置文件如.eslintrc由它完全取代插件内部配置。在 eslint.ts 中模式分支非常清晰if (mode file) { useEslintConfigFile(match); } else { extendsEslintConfig(match, cracoConfig.eslint, context); }两种模式在插件选项层面的差异如下mode插件选项变化适用场景extends保留baseConfig将configure合并进baseConfig只想在 CRA 默认规则上追加/调整规则file设置useEslintrc: true并删除baseConfig想使用独立.eslintrc/eslint.config文件统一管理规则4.1 file 模式的底层行为useEslintConfigFile的实现eslint.ts展示了重置的具体含义function useEslintConfigFile(plugin: any) { if (plugin.options) { plugin.options.useEslintrc true; delete plugin.options.baseConfig; } else { plugin.options { useEslintrc: true, }; } log(Overrided ESLint config to use a config file.); }它把useEslintrc置为true并删除 CRA 注入的baseConfig从而让ESLintWebpackPlugin回落到从项目根目录查找.eslintrc等配置文件。此时你在configure里写的规则对象实际上不再被使用——configure的内容只对extends模式有效。4.2 一个附带行为忽略文件总被启用无论哪种模式只要eslint段存在且未禁用enableEslintIgnoreFile都会被调用eslint.ts它把插件选项中的ignore设为truefunction enableEslintIgnoreFile(plugin: any) { if (plugin.options) { plugin.options.ignore true; } else { plugin.options { ignore: true, }; } log(Overrided ESLint config to enable an ignore file.); }这意味着只要你在配置中使用eslint段且enable ! falseESLint 就会尊重项目中的.eslintignore文件——这是 CRACO 默认替你打开的行为值得在排查某些文件怎么没被检查时留意。五、eslint.configure对象字面量与函数两种写法类型ESLintConfig或(config: ESLintConfig, { env, paths }) ESLintConfig作用提供任意 ESLint 官方配置项extends、rules、parserOptions、env、settings等写入插件内部的baseConfig。5.1 对象字面量深合并直接给对象时CRACO 会把它与 CRA 内置的baseConfig做带数组的深度合并deepMergeWithArray因此不会覆盖掉 CRA 原有的extends与规则只会叠加eslint.tsif (plugin.options) { plugin.options.baseConfig deepMergeWithArray( {}, plugin.options.baseConfig || {}, configure ); } else { plugin.options { baseConfig: configure, }; }这一点在仓库的单元测试中得到了直接印证test/unit/merging-tests/custom-eslint-config/eslint.test.js断言合并结果同时包含 CRA 的react-app与自定义的plugin:prettier/recommendedit(correctly applies custom ESLint configuration, () { const eslintConfig cracoConfig.eslint.configure; expect(eslintConfig.extends).toContain(react-app); expect(eslintConfig.extends).toContain(plugin:prettier/recommended); expect(eslintConfig.rules[no-console]).toEqual(error); expect(eslintConfig.rules[no-debugger]).toEqual(error); });对应的配置样例craco.config.js与模拟的 CRA 内置配置eslint.config.mock.js如下module.exports { eslint: { configure: { extends: [react-app, plugin:prettier/recommended], rules: { no-console: error, no-debugger: error, }, }, }, };const eslintConfigMock { extends: [react-app], rules: { no-console: warn, }, }; module.exports eslintConfigMock;从源码与测试可以确认deepMergeWithArray的合并行为数组会按元素合并所以extends两个来源都保留对象键会合并所以rules[no-console]从warn被提升为error。另一条测试does not remove existing ESLint rules进一步保证自定义规则数量不少于内置配置。5.2 函数完全掌控传函数时CRACO 会把当前插件已有的baseConfig或其空对象作为第一个参数传入由你自由修改后返回eslint.tsif (isFunction(configure)) { if (plugin.options) { plugin.options.baseConfig configure( plugin.options.baseConfig || {}, context ); } else { plugin.options { baseConfig: configure({}, context), }; } if (!plugin.options.baseConfig) { throw new Error( craco: eslint.configure function didnt return a config object. ); } }函数签名中的第二个参数是上下文对象包含env— 当前NODE_ENVdevelopment / production / test 等paths— CRA 使用的全部路径集合。如果函数没有返回配置对象CRACO 会抛出craco: eslint.configure function didnt return a config object.异常并中断构建。因此函数写法必须显式returnmodule.exports { eslint: { configure: (eslintConfig, { env, paths }) { // eslintConfig 即 CRA 内置的 baseConfig或空对象 if (env production) { eslintConfig.rules[no-console] error; } return eslintConfig; }, }, };5.3 函数与上下文配合的实用技巧结合 getting-started.md 中的when系列辅助函数可以让配置按环境差异化。官方示例展示了在file模式下按NODE_ENV切换格式化器const { when } require(craco/craco); module.exports { eslint: { mode: file, configure: { formatter: when( process.env.NODE_ENV CI, require(eslint-formatter-vso) ), }, }, };when(condition, fn, [unmetValue])条件为真时调用fn并返回其结果否则返回unmetValue未提供则为undefined。同系列的whenDev/whenProd/whenTest分别是针对三种NODE_ENV的简写。六、eslint.pluginOptions定制 ESLint Webpack Plugin 本身类型ESLintPluginOptions或(options: ESLintPluginOptions, { env, paths }) ESLintPluginOptions作用直接覆盖eslint-webpack-plugin的插件级选项。与configure只影响 lint 规则不同pluginOptions影响插件如何运行常见选项包括cache— 是否启用 lint 缓存布尔值可显著加速重复构建cacheLocation— 缓存文件位置fix— 是否让插件自动修复可修复的问题formatter— 输出格式化器threads— 是否使用多线程并行检查exclude/extensions— 检查范围与文件扩展名控制。上述选项均为eslint-webpack-plugin公开支持项具体取值范围以插件文档为准。源码中applyPluginOptions同样支持对象与函数两种形态eslint.tsfunction applyPluginOptions( plugin: any, pluginOptions: ConfigurePluginOptions, BaseContext, context: BaseContext ) { if (isFunction(pluginOptions)) { plugin.options pluginOptions(plugin.options || {}, context); if (!plugin.options) { throw new Error( craco: eslint.pluginOptions function didnt return a config object. ); } } else { plugin.options deepMergeWithArray(plugin.options || {}, pluginOptions); } log(Applied ESLint plugin options.); }与configure的差异在于configure只会写入baseConfig而pluginOptions是整个插件 options 对象的合并/替换——你甚至可以在这里覆盖configure已写入的baseConfig之外的任何字段。函数形态若未返回对象同样会抛出 craco: eslint.pluginOptions function didnt return a config object. 错误。module.exports { eslint: { pluginOptions: { cache: true, fix: false, formatter: stylish, }, // 也可以写成函数基于上下文做环境判断 // pluginOptions: (eslintPluginOptions, { env, paths }) { // if (env production) { // eslintPluginOptions.fix true; // } // return eslintPluginOptions; // }, }, };七、源码视角eslint 覆盖在构建链中的位置理解何时生效有助于排查问题。overrideEsLint定义于 eslint.ts并在 merge-webpack-config.ts 中被串联调用resultingWebpackConfig overrideBabel( cracoConfig, resultingWebpackConfig, context ); resultingWebpackConfig overrideEsLint( cracoConfig, resultingWebpackConfig, context ); resultingWebpackConfig overrideStyle( cracoConfig, resultingWebpackConfig, context ); resultingWebpackConfig overrideTypeScript( cracoConfig, resultingWebpackConfig );ESLint 覆盖发生在 Babel 覆盖之后、Style 与 TypeScript 覆盖之前。overrideEsLint的完整流程是若cracoConfig.eslint存在先在 webpack 配置中按名称查找ESLintWebpackPlugin找不到则打印Cannot find ESLint plugin (ESLintWebpackPlugin).并原样返回不报错、不崩溃找到后若enable false则移除插件并结束否则启用 ignore 文件支持ignore: true按mode走file读取配置文件或extends合并configure分支若提供了pluginOptions最后合并到插件选项。这一调用顺序保证只要你在配置中写了eslint段无论是禁用、换模式还是加规则最终都会被应用到由mergeWebpackConfig产出的 webpack 配置上进而影响craco start/craco build的执行。若想从外部观测合并效果可以在configure函数中打印eslintConfig或在pluginOptions函数中打印插件选项。八、ESLint 配置落地速查需求写法完全关闭 ESLinteslint: { enable: false }在 CRA 默认规则上追加规则eslint: { configure: { rules: { ... } } }默认extends模式用独立.eslintrc取代内置规则eslint: { mode: file }并在项目根目录放置.eslintrc按环境差异化规则eslint: { configure: (cfg, { env }) { /* ... */ return cfg; } }开启 lint 缓存加速eslint: { pluginOptions: { cache: true } }关闭对某些文件的检查项目根目录放.eslintignoreignore: true默认已开启配套的单元测试位于 test/unit/merging-tests/custom-eslint-config/包含配置样例、模拟的 CRA 内置配置与三条行为断言extends 保留、自定义规则生效、内置规则不被删除可作为你验证自己配置行为的参考模型。赞分享开发工具前端构建【免费下载链接】cracoCreate React App Configuration Override, an easy and comprehensible configuration layer for Create React App.项目地址https://gitcode.com/gh_mirrors/cr/craco点击查看免费下载相关推荐使用独立 ESLint 配置文件CRACO 的 mode: file 模式完整指南使用独立 ESLint 配置文件CRACO 的 mode: file 模式完整指南 本篇指南讲解如何在使用 CRACOCreate React App开发工具前端构建zlib配置脚本终极指南configure参数与Makefile变量深度解析zlib配置脚本终极指南configure参数与Makefile变量深度解析 还在为zlib的编译配置头疼吗每次面对configure脚本和Makefile数据工程CRACO DevServer 配置完全指南通过 craco.config.js 深度定制 CRA 开发服务器CRACO DevServer 配置完全指南通过 craco.config.js 深度定制 CRA 开发服务器 导读 本文聚焦 Create React Ap开发工具前端构建上一篇Buzz音频转录终极指南5步掌握离线转录与翻译技巧下一篇Agent-Native成本分析自建智能体应用的经济效益终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考