Skip to content

Commit

Permalink
[Fix] import/no-cycle: fix perf regression
Browse files Browse the repository at this point in the history
Fixes #1943.
  • Loading branch information
mblaszczyk-atlassian authored and ljharb committed Nov 12, 2020
1 parent 462b016 commit 498b25a
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 7 deletions.
27 changes: 22 additions & 5 deletions src/ExportMap.js
Expand Up @@ -22,6 +22,7 @@ let parseConfigFileTextToJson;
const log = debug('eslint-plugin-import:ExportMap');

const exportCache = new Map();
const tsConfigCache = new Map();

export default class ExportMap {
constructor(path) {
Expand Down Expand Up @@ -438,9 +439,11 @@ ExportMap.parse = function (path, content, context) {

const source = makeSourceCode(content, ast);

function isEsModuleInterop() {
function readTsConfig() {
const tsConfigInfo = tsConfigLoader({
cwd: context.parserOptions && context.parserOptions.tsconfigRootDir || process.cwd(),
cwd:
(context.parserOptions && context.parserOptions.tsconfigRootDir) ||
process.cwd(),
getEnv: (key) => process.env[key],
});
try {
Expand All @@ -450,12 +453,26 @@ ExportMap.parse = function (path, content, context) {
// this is because projects not using TypeScript won't have typescript installed
({ parseConfigFileTextToJson } = require('typescript'));
}
const tsConfig = parseConfigFileTextToJson(tsConfigInfo.tsConfigPath, jsonText).config;
return tsConfig.compilerOptions.esModuleInterop;
return parseConfigFileTextToJson(tsConfigInfo.tsConfigPath, jsonText).config;
}
} catch (e) {
return false;
// Catch any errors
}

return null;
}

function isEsModuleInterop() {
const cacheKey = hashObject({
tsconfigRootDir: context.parserOptions && context.parserOptions.tsconfigRootDir,
}).digest('hex');
let tsConfig = tsConfigCache.get(cacheKey);
if (typeof tsConfig === 'undefined') {
tsConfig = readTsConfig();
tsConfigCache.set(cacheKey, tsConfig);
}

return tsConfig !== null ? tsConfig.compilerOptions.esModuleInterop : false;
}

ast.body.forEach(function (n) {
Expand Down
3 changes: 3 additions & 0 deletions tests/files/typescript-export-assign-property.ts
@@ -0,0 +1,3 @@
const AnalyticsNode = { Analytics: {} };

export = AnalyticsNode.Analytics;
40 changes: 38 additions & 2 deletions tests/src/core/getExports.js
@@ -1,6 +1,8 @@
import { expect } from 'chai';
import semver from 'semver';
import sinon from 'sinon';
import eslintPkg from 'eslint/package.json';
import * as tsConfigLoader from 'tsconfig-paths/lib/tsconfig-loader';
import ExportMap from '../../../src/ExportMap';

import * as fs from 'fs';
Expand Down Expand Up @@ -51,7 +53,8 @@ describe('ExportMap', function () {
const differentSettings = Object.assign(
{},
fakeContext,
{ parserPath: 'espree' });
{ parserPath: 'espree' },
);

expect(ExportMap.get('./named-exports', differentSettings))
.to.exist.and
Expand Down Expand Up @@ -358,8 +361,12 @@ describe('ExportMap', function () {
let imports;
before('load imports', function () {
this.timeout(20000); // takes a long time :shrug:
sinon.spy(tsConfigLoader, 'tsConfigLoader');
imports = ExportMap.get('./typescript.ts', context);
});
after('clear spies', function () {
tsConfigLoader.tsConfigLoader.restore();
});

it('returns something for a TypeScript file', function () {
expect(imports).to.exist;
Expand Down Expand Up @@ -388,9 +395,38 @@ describe('ExportMap', function () {
it('has exported abstract class', function () {
expect(imports.has('Bar')).to.be.true;
});

it('should cache tsconfig until tsconfigRootDir parser option changes', function () {
const customContext = Object.assign(
{},
context,
{
parserOptions: {
tsconfigRootDir: null,
},
},
);
expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(0);
ExportMap.parse('./baz.ts', 'export const baz = 5', customContext);
expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(1);
ExportMap.parse('./baz.ts', 'export const baz = 5', customContext);
expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(1);

const differentContext = Object.assign(
{},
context,
{
parserOptions: {
tsconfigRootDir: process.cwd(),
},
},
);

ExportMap.parse('./baz.ts', 'export const baz = 5', differentContext);
expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(2);
});
});
});

});

// todo: move to utils
Expand Down

0 comments on commit 498b25a

Please sign in to comment.