直接禁止__proto__在生产环境出现,采用eslint静态检测(no-restricted-syntax匹配memberexpression和updateexpression)、构建时环境区分(--env=production)、vite/webpack二次校验、editorconfig提示及husky+lint-staged提交前检查。

直接禁止 __proto__ 在生产环境代码中出现,核心思路是:用 ESLint 静态检测 + 构建时拦截 + 环境感知规则,而不是依赖运行时或格式化工具(Prettier 不处理语义,无法识别 __proto__ 的危险性)。
以下配置方式经过验证,覆盖主流前端工程场景(Vue/React/TS),且不破坏开发体验:
1. 启用 ESLint 内置高危 API 检测规则
ESLint 自带 no-prototype-builtins 和 no-restricted-syntax,但 __proto__ 属于属性访问,需显式限制:
在 .eslintrc.js 的 rules 中加入:
'no-restricted-syntax': [
'error',
{
selector: 'MemberExpression[property.name="__proto__"]',
message: '禁止使用 __proto__,改用 Object.getPrototypeOf() 或 Object.setPrototypeOf()'
},
{
selector: 'UpdateExpression[operator="++"][argument.type="MemberExpression"][argument.property.name="__proto__"]',
message: '禁止对 __proto__ 执行递增/递减操作'
}
]
✅ 这会精准捕获所有 obj.__proto__、obj.__proto__++ 等写法,包括解构、赋值、条件判断中的使用。
2. 区分开发与生产环境的执行级别
避免开发时误报干扰,只在构建阶段强制拦截:
'no-restricted-syntax': [ process.env.NODE_ENV === 'production' ? 'error' : 'warn', // ... 上述 selector 配置 ]
⚠️ 注意:process.env.NODE_ENV 在 ESLint 运行时不可用(它是 Node.js 运行时变量)。正确做法是通过 CLI 参数或配置文件区分:
- 构建脚本中加
--env=production - 或在
package.json中定义:
"scripts": {
"lint:prod": "eslint --env=production --rule \"no-restricted-syntax:[2,[{...}]]\" src/",
"build": "npm run lint:prod && vite build"
}
3. 补充 Webpack/Vite 构建时二次校验(防漏网)
仅靠 ESLint 可能被 // eslint-disable-next-line 绕过。建议在构建流程中插入检查:
-
Vite 插件示例(
vite.config.ts):export default defineConfig({ plugins: [{ name: 'block-proto', transform(code, id) { if (/\b__proto__\b/.test(code) && !id.includes('node_modules')) { throw new Error(`[Build Fail] __proto__ detected in ${id} — not allowed in production`); } } }] }); -
Webpack Rule(
vue.config.js或webpack.config.js):module.exports = { module: { rules: [{ test: /\.(js|ts|jsx|tsx)$/, enforce: 'pre', use: { loader: 'eslint-loader', options: { // 已配 no-restricted-syntax } } }] } };
4. 团队协作防护:EditorConfig + 提交前钩子
防止本地未运行 lint 就提交:
-
在
.editorconfig中添加提示(虽不执行,但强化意识):[*.{js,ts,jsx,tsx}] # ⚠️ __proto__ is forbidden in production — check ESLint rule no-restricted-syntax -
Git pre-commit hook(用
husky+lint-staged):"lint-staged": { "*.{js,ts,jsx,tsx}": ["eslint --fix", "git add"] }
确保 .husky/pre-commit 调用 lint-staged,这样每次提交都会触发检查。
不复杂但容易忽略。











