Skip to content

Commit

Permalink
fix: Plugins should always use the same reference (eslint#91)
Browse files Browse the repository at this point in the history
When loading a plugin the first time, we should create a normalized
plugin object and then cache it to use later so every reference to the
same plugin is represented by the same normalized plugin reference.

Refs eslint/eslint#16277
Closes eslint#89
Closes eslint#90
  • Loading branch information
nzakas committed Sep 12, 2022
1 parent 99adbac commit 2a2bef1
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
18 changes: 17 additions & 1 deletion lib/config-array-factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ const configFilenames = [
/** @type {WeakMap<ConfigArrayFactory, ConfigArrayFactoryInternalSlots>} */
const internalSlotsMap = new WeakMap();

/** @type {WeakMap<object, Plugin>} */
const normalizedPlugins = new WeakMap();

/**
* Check if a given string is a file path.
* @param {string} nameOrPath A module name or file path.
Expand Down Expand Up @@ -405,12 +408,25 @@ function createContext(
* @returns {Plugin} The normalized plugin.
*/
function normalizePlugin(plugin) {
return {

// first check the cache
let normalizedPlugin = normalizedPlugins.get(plugin);

if (normalizedPlugin) {
return normalizedPlugin;
}

normalizedPlugin = {
configs: plugin.configs || {},
environments: plugin.environments || {},
processors: plugin.processors || {},
rules: plugin.rules || {}
};

// save the reference for later
normalizedPlugins.set(plugin, normalizedPlugin);

return normalizedPlugin;
}

//------------------------------------------------------------------------------
Expand Down
43 changes: 43 additions & 0 deletions tests/lib/config-array-factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -2967,6 +2967,49 @@ env:
});
});

it("should represent the same plugin with the same object reference", async () => {
const teardown = createCustomTeardown({
cwd: tempDir,
files: {
"node_modules/eslint-plugin-test/index.js": `
module.exports = {
environments: {
bar: { globals: { bar: true } }
}
}
`,
"plugins/.eslintrc.yml": `
plugins:
- test
rules:
test/foo: 2
env:
test/bar: true
`
}
});

cleanup = teardown.cleanup;

await teardown.prepare();
const factory = new ConfigArrayFactory({ cwd: teardown.getPath() });

const filePath = "plugins/.eslintrc.yml";
const config1 = factory
.loadFile(filePath)
.extractConfig(filePath);

const config2 = factory
.loadFile(filePath)
.extractConfig(filePath);

const first = config1.plugins.test.definition;
const second = config2.plugins.test.definition;

assert.strictEqual(first, second);
});


it("should load two separate configs from a plugin", async () => {
const teardown = createCustomTeardown({
cwd: tempDir,
Expand Down

0 comments on commit 2a2bef1

Please sign in to comment.