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

parser.createProgram is not being exported #3514

Closed
3 tasks done
rdsedmundo opened this issue Jun 11, 2021 · 6 comments
Closed
3 tasks done

parser.createProgram is not being exported #3514

rdsedmundo opened this issue Jun 11, 2021 · 6 comments
Labels
fix: user error issue was fixed by correcting the configuration / correcting the code package: parser Issues related to @typescript-eslint/parser

Comments

@rdsedmundo
Copy link
Contributor

rdsedmundo commented Jun 11, 2021

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.
  • I have read the FAQ and my problem is not listed.

Repro

  1. mkdir typescript-eslint-bug-no-createprogram
  2. yarn init -y
  3. yarn add eslint @typescript-eslint/parser
  4. Check node_modules/@typescript-eslint/parser exports contents.

Attached screenshots at the bottom.

Expected Result

Should be exported.

Actual Result

I tried to use inside eslintrc.js and it threw saying that parser.createProgram is not defined.

Additional Info

I tried to import from @typescript-eslint/typescript-estree as well and got the same result.

Versions

package version
@typescript-eslint/parser 4.26.1
TypeScript 4.3.2
ESLint 7.28.0
node 14.17.0

Screen Shot 2021-06-11 at 16 12 22

Notice on this file above how it's missing a third import but still has a trailing comma, for some reason createProgram is getting stripped from there.

export { parse, parseForESLint, ParserOptions } from './parser';
export { ParserServices, clearCaches, } from '@typescript-eslint/typescript-estree';
export declare const version: string;
//# sourceMappingURL=index.d.ts.map

Screen Shot 2021-06-11 at 16 12 40

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.version = exports.clearCaches = exports.parseForESLint = exports.parse = void 0;
var parser_1 = require("./parser");
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return parser_1.parse; } });
Object.defineProperty(exports, "parseForESLint", { enumerable: true, get: function () { return parser_1.parseForESLint; } });
var typescript_estree_1 = require("@typescript-eslint/typescript-estree");
Object.defineProperty(exports, "clearCaches", { enumerable: true, get: function () { return typescript_estree_1.clearCaches; } });
// note - cannot migrate this to an import statement because it will make TSC copy the package.json to the dist folder
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
exports.version = require('../package.json').version;
//# sourceMappingURL=index.js.map
@rdsedmundo rdsedmundo added package: parser Issues related to @typescript-eslint/parser triage Waiting for team members to take a look labels Jun 11, 2021
@bradzacher
Copy link
Member

It's not getting stripped. It hasn't been released yet.
We release to the npm latest tag on mondays.

If you want to play with this new api - use our canary tag on npm

@bradzacher bradzacher added fix: user error issue was fixed by correcting the configuration / correcting the code and removed triage Waiting for team members to take a look labels Jun 11, 2021
@bradzacher
Copy link
Member

@rdsedmundo please comment back once you've tested and let us know how it goes!
We'd love to hear what sort of performance improvements you get.

Worth noting that @JamesHenry is working to make this the default for CLI runs in #3512.
Also as an FYI @uniqueiniquity - look a real-world user already getting onto it!

@rdsedmundo
Copy link
Contributor Author

I wasn't focused on performance improvements (although that will be good in the future!), my use case was writing a custom module resolution (#2771) that enables absolute paths within cross-package imports in a monorepo.

Actually, I ended up using parserOptions.programs just, created my own ts.Program using the Compiler API and it worked wonders. Thank y'all so much for enabling this feature.

I also had to duplicate the logic into a custom tsc CLI for running the type checking with the awareness of the absolute paths + a language service for VSCode. It's unfortunate that TypeScript doesn't support a global hook for this in the tsconfig.json and we have to duplicate this everywhere. microsoft/TypeScript#16607 which asks for this is about to complete 4 years next week.

@bradzacher
Copy link
Member

my use case was writing a custom module resolution (#2771) that enables absolute paths within cross-package imports in a monorepo.

oh shit - I didn't even think about that.
this a really awesome possibility that's enabled with this new API.

I know the original usecase Ben was thinking of was for a large project to reuse a project for both linting and typechecking.
So you could probably share your code around and write your own script wrappers for typechecking and linting (and doing both at the same time).

@rdsedmundo
Copy link
Contributor Author

rdsedmundo commented Jun 12, 2021

One difficulty that I'm facing is that the eslint server grows fast in memory usage because it creates a new program almost every time I edit the file in the IDE (because it reads the eslintrc.js again).

I proceeded to cache the program using the tsconfig path, similarly to what you already do with the 'watch programs', it worked, but the problem now is that my program source files are outdated as I don't have access to the dirty file from the IDE before it's saved on the disk, so I can only see the lint problems upon saving the file.

I'd need to do something similar as this, but the useProvidedPrograms don't get access to the code variable, and even if it did I'm not sure how @typescript-eslint could pass that downstream 🤔 , perhaps it could have an overload like this:

module.exports = {
  parserOptions: {
    programs: [
       (code, filePathIn) => {
         const program = getCachedProgram();
         // here I mimic the same logic from the createWatchProgram.ts#L278
       },
    ]
  }
}

A similar problem arises for a new file being created in the disk which won't be inside the ts.createProgram, so if I receive those two parameters I can check if it's not inside and put it in.

Ultimately, I'll end up having to implement a lot of things that you've already done (and better, with tests and edge cases) in the createWatchProgram file, so maybe after all the suggestion you had made here of having a parserOptions.resolveModuleNames is the best way to go with this.

Do you have any thoughts? Thanks.

@rdsedmundo
Copy link
Contributor Author

I gave up reinventing the wheel and added support for a parserOptions.moduleResolver option.

#3516

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 13, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
fix: user error issue was fixed by correcting the configuration / correcting the code package: parser Issues related to @typescript-eslint/parser
Projects
None yet
Development

No branches or pull requests

2 participants