Skip to content

[eslint-plugin-packlets] Initial implementation#2256

Merged
octogonz merged 23 commits intomasterfrom
octogonz/packlets
Oct 5, 2020
Merged

[eslint-plugin-packlets] Initial implementation#2256
octogonz merged 23 commits intomasterfrom
octogonz/packlets

Conversation

@octogonz
Copy link
Copy Markdown
Collaborator

@octogonz octogonz commented Oct 4, 2020

Fixes #2254

Copy link
Copy Markdown
Contributor

@sachinjoseph sachinjoseph left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Left a few clarification comments.

return undefined;
}

public static detectCircularImport(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume we want to return only the first cycle if there are multiple cycles?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should add some docs to clarify this. The way it works:

  • Cycles are only detected by looking at index.ts files. This works because we require consumers to import those files.
  • Each import statement is analyzed separately, and the analysis stops when the first cycle is found.
  • We then sort the list of affected packlets alphabetically, and only report the error for the index.ts file of the first packlet in the list. This avoids redundantly reporting it for each packlet along the cycle.

return;
}

if (!(modulePath.startsWith('.') || modulePath.startsWith('..'))) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we import from a file in the same folder like import from 'filename.ts' without having to do ./filename.ts?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't. The module resolver would interpret filename.ts to be an NPM package with that name.

// Okay
import { MainReport } from '../packlets/reports';

// Error: The import statement does not use the packlet's entry point (@rushstack/packlets/mechanics)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please allow this. This is strictly superior to the directory import in terms of resolution accuracy and performance in TypeScript, Webpack, etc.

Copy link
Copy Markdown
Collaborator Author

@octogonz octogonz Oct 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you provide some details? If this is a real concern (?), then it seems better to optimize our tooling than to ask developers to write their code in an awkward way.

Copy link
Copy Markdown
Collaborator Author

@octogonz octogonz Oct 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dmichon-msft I'm interested in this question, but I'm trying to unblock a couple teams who are waiting for these lint rules. So if you feel strongly about it, let's sort it out in a separate GitHub issue.

CC @iclanton

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expecting people to always say import { ... } from 'package-name/lib/index'; is awkward and will break SPFx development scenarios.

This isn't an optimization that we should expect developers to have to make because it produces objectively worse code for the sake of making the compiler slightly faster. If these filesystem accesses are a real concern, we should try to improve our caching and maybe explore filling a filesystem cache in a background thread.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with not making it the default. I'm not so happy about forbidding it. If we were actually writing code directly for browsers, we'd be expected to include the final step of doing import { MainReport } from '../packlets/reports/index.js', but unfortunately TypeScript doesn't allow us to be that specific.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can continue this topic here: #2262

@octogonz octogonz merged commit 997f510 into master Oct 5, 2020
@octogonz octogonz deleted the octogonz/packlets branch October 5, 2020 22:23
const referencingFilePath: string = refFile.file;

if (Path.isUnder(referencingFilePath, packletsFolderPath)) {
const referencingRelativePath: string = path.relative(packletsFolderPath, referencingFilePath);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All file paths within TypeScript are normalized to use / as the directory separator. Recommend using path.posix.relative and, if necessary, starting at the first / if there are problems with the drive letter on Windows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[eslint-plugin] Proposal: "Packlets" model for lightweight package-like folders within a project

4 participants