如何编写ESLint规则禁止代码中使用特定字符串字面量
ESLint 校验禁用特定字符串字面量实现方案
你已经掌握的禁止特定命名变量、方法的规则写法,核心是匹配对应AST节点做校验,禁用特定字符串的逻辑完全一致,只需要把匹配目标换成字符串字面量对应的AST节点即可,不需要额外引入复杂依赖,两种落地方式按需选择即可。
方案1:用内置no-restricted-syntax规则快速实现
不需要额外写自定义规则、装第三方插件,直接用ESLint原生支持的no-restricted-syntax规则就能实现固定字符串的禁用校验,在ESLint配置文件中添加如下规则即可:
// .eslintrc.js module.exports = { // 其他基础配置省略 rules: { 'no-restricted-syntax': [ 'error', { create(context) { // 在这里配置所有需要禁用的硬编码字符串 const forbiddenStrSet = new Set([ '生产环境数据库连接地址', '硬编码的AK/SK密钥', '必须走环境变量配置的内部服务域名' ]) return { Literal(node) { // 仅校验字符串类型的字面量 if (typeof node.value === 'string' && forbiddenStrSet.has(node.value)) { context.report({ node, message: `禁止直接硬编码字符串"${node.value}",请读取process.env下对应的环境变量替代` }) } } } } } ] } }
这个方案适合只需要拦截固定字符串的场景,配置成本最低,写完直接生效。
方案2:自定义规则实现灵活匹配
如果需要做更复杂的校验(比如正则匹配所有符合密钥格式的字符串、拦截模板字符串中的硬编码内容、给不同的禁用字符串绑定对应的环境变量提示),可以写自定义ESLint规则,核心逻辑如下:
// 自定义ESLint规则核心代码 module.exports = { meta: { type: 'problem', messages: { forbiddenStr: '禁止硬编码违规字符串,请使用环境变量替代,命中规则:{{ruleTip}}' } }, create(context) { // 规则配置支持传精确字符串、正则匹配规则 const rules = context.options[0]?.rules || [] // 配置不需要拦截的白名单字符串 const whiteList = new Set(context.options[0]?.whiteList || []) const checkValue = (value, node) => { if (typeof value !== 'string' || whiteList.has(value)) return for (const rule of rules) { const isMatch = rule instanceof RegExp ? rule.test(value) : rule.value === value if (isMatch) { context.report({ node, messageId: 'forbiddenStr', data: { ruleTip: rule.tip || rule.value || rule.toString() } }) return } } } return { // 校验普通字符串字面量 Literal(node) { checkValue(node.value, node) }, // 需要拦截模板字符串中硬编码内容的话,打开下面的逻辑 // TemplateLiteral(node) { // node.quasis.forEach(quasi => checkValue(quasi.value.cooked, quasi)) // } } } }
自定义规则可以根据你的项目需求扩展能力:
- 支持给每个禁用字符串配置对应的提示,比如命中内部服务域名时直接提示应该使用的环境变量名
- 支持正则模糊匹配,不需要逐个枚举固定值
- 可以扩展自动修复能力,命中规则时自动替换为对应的环境变量引用
- 可以加白名单配置,放过日志文案、类名等不需要拦截的字符串,减少误报
注意事项
- 如果项目中用了
@babel/eslint-parser或者@typescript-eslint/parser作为解析器,要确认解析器对Literal节点的解析逻辑和原生ESTree规范一致,避免出现漏判 - 不要把所有字符串都列入拦截范围,只拦截必须走环境变量的配置项、密钥、内部地址这类敏感/需要统一配置的内容,避免影响正常开发
内容的提问来源于stack exchange,提问作者jordan
相关产品推荐
相关产品推荐

