Description
Checklist
- I have tried restarting my IDE and the issue persists.
- I have read the FAQ and my problem is not listed.
Tell us about your environment
- ESLint version: 7.32.0
- eslint-plugin-vue version: 7.20.0
- Node version: 14.16.0
- Operating System: macOS Catalina 10.15.7
Some additional details:
- My project is relatively big – around 3000
*.vue
files and around 2000 of*.js
files with// @vue/component
comment
Please show your full configuration:
{
"root": true,
"env": { "es2021": true },
"plugins": ["vue"],
"extends": ["plugin:vue/recommended"],
"rules": {
"vue/no-unsupported-features": ["error", { "version": "^2.6.14" }]
}
}
Note this is not full .eslintrc
file, but just relevant part with the configured rule in question
What did you do?
No code here because this issue can be reproduced with both valid and invalid code.
What did you expect to happen?
Memory consumption does not significantly change when no-unsupported-features
rule is enabled.
What actually happened?
ESLint output is not relevant here, as we need to look into "Activity Monitor" instead.
With the rule enabled, during the lint process (which we run as eslint --ext .js,.vue .
) RAM consumption keeps raising and peaks at to 3.5G-4Gb level. When I disable the rule – it doesn't go more than 800-900Mb. I tried to disable other rules, but it seems this is the one which causes the issue.
I tried to debug it myself and I narrowed it down to this line:
/** @type {Map<VElement, StyleVariablesContext>} */
const cache = new Map()
This file is used in the style-css-vars-injection
syntax spec, which is part of the no-unsupported-features
rule.
From my understanding, this cache
is created globally per entire lint process, while it would be populated with values from each of the scanned files. This cache uses VElement
objects as a key, which makes them "trapped" in this cache for the duration of the entire lint process. As a result Node.js cannot garbage collect those references when scan for individual file is done.
Simple change to WeakMap
seems to be solving the problem:
/** @type {WeakMap<VElement, StyleVariablesContext>} */
const cache = new WeakMap()
Btw during my experiments, I noticed that part of that code that reads from the cache
is never executed. I'm not sure what is the use case for this cache implementation, but for now it seems redundant for me and it could be removed altogether.
Repository to reproduce this issue
I'm not sure if you still need it, but I can add it if you confirm.