Skip to content

Issues related to packages in monorepo #2218

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

Closed
lifeiscontent opened this issue Jun 16, 2020 · 14 comments
Closed

Issues related to packages in monorepo #2218

lifeiscontent opened this issue Jun 16, 2020 · 14 comments
Labels
fix: user error issue was fixed by correcting the configuration / correcting the code package: parser Issues related to @typescript-eslint/parser

Comments

@lifeiscontent
Copy link

Repro

It's a private repo I can give one of the maintainers access.

{
  "env": {
    "browser": true,
    "es6": true,
    "jest": true,
    "node": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/eslint-recommended",
    "plugin:@typescript-eslint/recommended-requiring-type-checking",
    "plugin:@typescript-eslint/recommended",
    "plugin:cypress/recommended",
    "plugin:prettier/recommended",
    "plugin:react/recommended",
    "plugin:testing-library/recommended",
    "prettier",
    "prettier/@typescript-eslint"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 2020,
    "project": [
      "tsconfig.json",
      "packages/*/tsconfig.json",
      "apps/*/tsconfig.json"
    ],
    "sourceType": "module"
  },
  "plugins": [
    "cypress",
    "@typescript-eslint",
    "prettier",
    "react-hooks",
    "react",
    "testing-library"
  ],
  "root": true,
  "rules": {
    "@typescript-eslint/no-unused-vars": [
      "error",
      { "argsIgnorePattern": "^_" }
    ],
    "prettier/prettier": "error",
    "react-hooks/exhaustive-deps": "warn",
    "react-hooks/rules-of-hooks": "error",
    "react/jsx-filename-extension": [
      2,
      { "extensions": [".js", ".jsx", ".tsx"] }
    ]
  },
  "settings": {
    "react": {
      "pragma": "React",
      "version": "detect"
    },
    "import/parsers": {
      "@typescript-eslint/parser": [".ts", ".tsx"]
    },
    "import/resolver": {
      "typescript": {}
    }
  }
}
// your repro code case

Expected Result

no errors

Actual Result
20:16 error Unsafe assignment of an any value @typescript-eslint/no-unsafe-assignment

Additional Info
@typescript-eslint/parser doesn't seem to be seeing my source code for some of my packages in the monorepo.

Versions

package version
@typescript-eslint/parser 3.3.0
TypeScript 3.9.5
ESLint 7.2.0
node 12.8.1
npm 6.14.5
@lifeiscontent lifeiscontent added package: parser Issues related to @typescript-eslint/parser triage Waiting for team members to take a look labels Jun 16, 2020
@bradzacher
Copy link
Member

bradzacher commented Jun 16, 2020

doesn't seem to be seeing my source code for some of my packages in the monorepo.

Could you please provide more information? This statement doesn't tell us anything about the problem.

If you've got a lint result, could you also show the code that generated the lint result?

The more information you can provide, the easier it is to diagnose and help you debug. Right now I can give you no help at all.

Help me to help you.

https://github.com/typescript-eslint/typescript-eslint/blob/master/CONTRIBUTING.md#raising-issues

Finally, when raising a new issue, please fill out the issue template - please don't skip sections.

Please provide as much information as possible. This project is maintained by volunteers, so the more the more information you provide, the less likely we will have to waste everyone's time in asking you for more information.

If you have a particularly complex issue - consider creating a small, self-contained reproduction repo. This will help you in figuring out the exact problem, and will help us in reproducing and diagnosing the bug.

@bradzacher bradzacher reopened this Jun 16, 2020
@bradzacher bradzacher added awaiting response Issues waiting for a reply from the OP or another party and removed triage Waiting for team members to take a look labels Jun 16, 2020
@lifeiscontent
Copy link
Author

lifeiscontent commented Jun 16, 2020

@bradzacher I can give you access to the repo if you have time to take a look.

the errors as I said stem from what I believe typescript-eslint not having the right information to see the source code of other packages in the monorepo. So for example:

  20:16  error  Unsafe assignment of an any value                  @typescript-eslint/no-unsafe-assignment
  20:16  error  Unsafe member access [props.name] on an any value  @typescript-eslint/no-unsafe-member-access

and the source code for that lint error:

import React from 'react';
import { circle } from '@lifetime/icons';

interface Props {
  fill: string;
  name: keyof typeof circle;
  size?: number;
}

export function UIIconCircle(props: Props): JSX.Element {
  return (
    <svg
      className="UIIconCircle"
      fill={props.fill}
      shapeRendering="geometricPrecision"
      style={{ fontSize: props.size }}
      viewBox="0 0 24 24"
      xmlns="http://www.w3.org/2000/svg"
    >
      <path d={circle[props.name]} />
      <style jsx>{`
        .UIIconCircle {
          width: 1em;
          height: 1em;
        }
      `}</style>
    </svg>
  );
}

UIIconCircle.defaultProps = {
  fill: 'currentColor',
};

typescript-eslint is saying circle is any from import { circle } from '@lifetime/icons'; because I guess it doesn't know where to read the source code from.

@bradzacher
Copy link
Member

Sure, if that's easiest.

@lifeiscontent
Copy link
Author

@bradzacher I've added you as a collaborator, check out the branch nx-spike if you have any questions just comment on the PR, or if you want a more direct line of communication feel free to ping me on discord lifeiscontent#6354

@lifeiscontent
Copy link
Author

@bradzacher any updates?

@bradzacher
Copy link
Member

Steps taken:

  • clone repo
  • checkout branch nx-spike
  • yarn install
  • yarn workspaces run build
    • note that this errored out and did not complete [1].
  • cd packages/react-ui, yarn build
    • note that this errored out, and did not complete [2].

The second build error is the issue which is causing the lint errors.

Our tooling doesn't show any typescript errors - this is done on purpose, because we don't want to replicate TS at all for various reasons I won't get into.

This means that if, for some reason, your config is wrong and TS can't find imports, it doesn't error your lint run - instead it just treats the type as any [3].

If you fix the build error, it should fix the lint error as well.

[1]
> @lifetime/storybook
yarn run v1.22.4
$ build-storybook -c .storybook -o dist -s public --quiet
info @storybook/react v6.0.0-beta.27
info 
info clean outputDir..
info => Copying static files from: public
info => Copying prebuild dll's..
info => Building manager..
info => Loading manager config..
info => Loading presets
info => Compiling manager..
info => manager built (4.17 s)
info => Building preview..
info => Loading preview config..
info => Loading presets
info => Loading config/preview file in ".storybook".
info => Loading config/preview file in ".storybook".
info => Adding stories defined in ".storybook/main.js".
info => Using default Webpack setup.
info => Compiling preview..
ERR! => Failed to build the preview
ERR! Module not found: Error: Can't resolve '@lifetime/react-ui' in '/Users/bradzacher/temp/lifetime-nx-spike/packages/react-components/src/select-menu'
(node:87437) UnhandledPromiseRejectionWarning: ModuleNotFoundError: Module not found: Error: Can't resolve '@lifetime/react-ui' in '/Users/bradzacher/temp/lifetime-nx-spike/packages/react-components/src/select-menu'
[2]
/Users/bradzacher/temp/lifetime-nx-spike/packages/react-ui/src/UIIcon/UIIcon.tsx (2,25): Cannot find module '@lifetime/icons' or its corresponding type declarations.
/Users/bradzacher/temp/lifetime-nx-spike/packages/react-ui/src/UIIconCircle/UIIconCircle.tsx (2,24): Cannot find module '@lifetime/icons' or its corresponding type declarations.
[3]

It's a special type of any that we can detect, and you can see it is detected and logged in 3.4.0 if you turn on debug logging:

$ DEBUG=typescript-eslint:eslint-plugin:utils:types yarn eslint packages/react-ui/src/UIIconCircle/UIIconCircle.tsx

  typescript-eslint:eslint-plugin:utils:types Found an "error" any type +0ms
  typescript-eslint:eslint-plugin:utils:types Found an "error" any type +1ms

/Users/bradzacher/temp/lifetime-nx-spike/packages/react-ui/src/UIIconCircle/UIIconCircle.tsx
  20:16  error  Unsafe assignment of an any value                  @typescript-eslint/no-unsafe-assignment
  20:16  error  Unsafe member access [props.name] on an any value  @typescript-eslint/no-unsafe-member-access

✖ 2 problems (2 errors, 0 warnings)

@lifeiscontent
Copy link
Author

@bradzacher sorry, I thought I'd updated the build steps, I just pushed a fix. So are you saying I should build my project before running eslint so the typedefs come through?

@lifeiscontent
Copy link
Author

@bradzacher the things typescript-eslint is casting to any are things that VSCode sees as the correct types which is why I'm confused.

import { regular } from '@lifetime/icons';

// typescript-eslint says regular is any here, but VSCode evaluates to the right type.

@lifeiscontent
Copy link
Author

lifeiscontent commented Jun 26, 2020

After you've pulled my latest commit, You should see what I'm seeing if you follow the same steps:

git clean -dfx
yarn
yarn eslint . --ext .ts,.tsx

@bradzacher
Copy link
Member

I don't think you have to do a build based on your config - unsure though.
I just did it because I was already suspecting that there might be a build error, based on the symptoms.

Your repo is setup a little weird, because you use compilerOptions.paths to "link" your packages together, instead of using lerna link to do it for you.
TBH I'm not entirely sure how typescript interacts with projects when you alias them using paths.

If it's anything like using lerna to link your project together, then yes - you will. We do not yet have support for project references (#2094 - TS only recently added support to the API we used), so we cannot automatically resolve files.

VSCode doesn't error because of how it is designed. In a nutshell, VSCode does some unique things to automagically make TS work smoothly in the IDE with zero config - i.e. it automatically figures out the tsconfig for any given file by traversing the file tree.

IIRC it works something along the lines of this:
When you open your TS file (packages/react-ui/src/UIIconCircle/UIIconCircle.tsx), it traverses up the file tree until it finds a tsconfig, packages/react-ui/tsconfig.json. That config matches the file, so it uses it to compile the file. From that config, it knows that @lifetime/icons references packages/icons/src/index.ts, so to resolve the import, it walks the folder tree again to find packages/icons/tsconfig.json, and so on.

We don't have the same logic, and we don't (and can't) use the same APIs as VSCode, so we're more limited in this space, unfortunately.

@bradzacher
Copy link
Member

Note - I pulled the latest nx-spike and it still has the same error. The last commit on the branch was 10 days ago, I'm not sure if you pushed the changes.

@lifeiscontent
Copy link
Author

lifeiscontent commented Jun 26, 2020

@bradzacher shoot, you're right I completely forgot to push.

I'm not familiar with lerna link.

and tbh, I only setup those references because I thought that was how it was supposed to be, I'm kinda fumbling around with this config, so any guidance you can share would be greatly appreciated.

ideally, I'd like eslint to run before a build because it'll give me quicker insight in CI if a build has issues.

I've updated the repo, give it another go and let me know what you think.

@bradzacher
Copy link
Member

bradzacher commented Jun 26, 2020

I just pulled and tried again.

  • git clean -dfx
  • git pull
  • yarn
  • yarn eslint packages/react-ui/src/UIIconCircle/UIIconCircle.tsx
    • see erroneous lint errors
  • yarn workspaces run build
    • completed successfully (with some warnings which I don't think matter)
  • yarn eslint packages/react-ui/src/UIIconCircle/UIIconCircle.tsx
    • saw no lint errors

So it looks like your workspace is working exactly as I mentioned before.


Our repo here is a good example of setting up a multi-package monorepo.
We use lerna to link the workspace together and run scripts across the workspace.

And that's really it.
Each package depends on the current version of another package in this repo.

When you initialise lerna, it will scan the yarn workspace, find all of the package.jsons, and then do a dependency analysis on them.
From there it will link the dependent package folders into their dependency's node_modules folder.
image

This means that node (and typescript) will automatically be able to resolve the path to the files without any special config at all.
Note that we also use project references so typescript can ensure dependences are up to date when we build a specific package (cd packages/parser && yarn build will cause typescript to first build the dependent packages, and then it'll build parser).

@bradzacher
Copy link
Member

I'm going to close this as resolved - you need to do the build first.
There's a good chance that #2094 will make this easier for you.

@bradzacher bradzacher added working as intended Issues that are closed as they are working as intended and removed awaiting response Issues waiting for a reply from the OP or another party labels Jun 26, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 27, 2020
@bradzacher bradzacher added fix: user error issue was fixed by correcting the configuration / correcting the code and removed working as intended Issues that are closed as they are working as intended labels Aug 17, 2020
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