Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[eslint-plugin-packlets] Initial implementation #2256

Merged
merged 23 commits into from
Oct 5, 2020
Merged

Conversation

octogonz
Copy link
Collaborator

@octogonz octogonz commented Oct 4, 2020

Fixes #2254

Copy link
Member

@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.

stack/eslint-plugin-packlets/src/DependencyAnalyzer.ts Outdated Show resolved Hide resolved
return undefined;
}

public static detectCircularImport(
Copy link
Member

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
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
Member

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
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
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
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
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
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
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
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
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