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

Using the coverage reporter requires "@hapi/eslint-plugin" to be installed, even if it’s not used. #1017

Closed
rluba opened this issue Jul 13, 2021 · 12 comments · Fixed by #1018
Assignees
Labels
bug Bug or defect
Milestone

Comments

@rluba
Copy link
Contributor

rluba commented Jul 13, 2021

Support plan

  • is this issue currently blocking your project? (yes/no): no
  • is this issue affecting a production system? (yes/no): no

Context

  • node version: 14.17.1
  • module version with issue: 24.3.1
  • last module version without issue: at least 24.1.1, maybe newer
  • environment (e.g. node, browser, native): node
  • used with (e.g. hapi application, another framework, standalone, ...): hapi application, but it shouldn’t matter
  • any other relevant information: -

What are you trying to achieve or the steps to reproduce?

Run lab with the coverage reporter and disabled linting in a project without @hapi/eslint-plugin installed:

./node_modules/.bin/lab -c

What was the result you got?

You get the following error:

UnhandledPromiseRejectionWarning: Error: Failed to load plugin '@hapi' declared in 'BaseConfig': Cannot find module '@hapi/eslint-plugin'

This wasn’t the case at least until 24.1.1.

What result did you expect?

Lab shouldn’t require the eslint plugin if linting isn’t enabled.

@rluba rluba added the support Questions, discussions, and general support label Jul 13, 2021
@Nargonath
Copy link
Member

@hapi/eslint-plugin was added in v24.0.0. See: f7f55c7. How come @hapi/eslint-plugin is not installed on your project? It's a declared dependencies of lab. If you install lab you should have it by default.

@rluba
Copy link
Contributor Author

rluba commented Jul 15, 2021

My bad. That was probably because I yarn link-ed lab into the project to test #1001. So lab’s direct dependencies were in the lab directory and not hoisted to the project’s node_modules root, where eslint was looking for it.

@rluba rluba closed this as completed Jul 15, 2021
@Nargonath
Copy link
Member

Sure, no problem. 👍

@Nargonath Nargonath added non issue Issue is not a problem or requires changes and removed support Questions, discussions, and general support labels Jul 15, 2021
@Nargonath Nargonath self-assigned this Jul 15, 2021
@kanongil
Copy link
Contributor

This should probably be considered a bug. Lab should not require that @hapi/eslint-plugin is hoisted to the root of node_modules as this cannot be depended upon.

Lab needs to either declare a peer dependency on @hapi/eslint-plugin or correctly require the module when it is a nested dependency.

@kanongil kanongil reopened this Jul 15, 2021
@Nargonath
Copy link
Member

I'm not sure we should declare it as a peer dep because it's dependent on it for the linter and coverage analysis feature. IMO it should come with lab itself.

correctly require the module when it is a nested dependency

I wonder if the problem comes from eslint itself that looks for the plugin in the project node_modules root instead of lab itself. I shall dig deeper.

@Nargonath Nargonath added bug Bug or defect and removed non issue Issue is not a problem or requires changes labels Jul 15, 2021
@kanongil
Copy link
Contributor

kanongil commented Jul 15, 2021

It is an eslint / npm thing. When you eslint a project it has no idea that lab initiated it and can only meaningfully search the base node_modules for a plugin that is specified using a simple string.

Any eslint plugin that depends on other plugins need to specify them as peer dependencies for it to always resolve correctly.

@rluba
Copy link
Contributor Author

rluba commented Jul 15, 2021

Thats true. And it might be OK to wrestle with esling if you actually tell lab to lint the project. But it’s weird that it also requires these modules if linting is disabled and you only want a coverage report.

@kanongil
Copy link
Contributor

kanongil commented Jul 15, 2021

Thats true. And it might be OK to wrestle with esling if you actually tell lab to lint the project. But it’s weird that it also requires these modules if linting is disabled and you only want a coverage report.

Hmm, you are not quite right.

Lab uses eslint for parsing the AST when checking for coverage. This needs the correct parser options for the current project. These are defined inside the .eslintrc.js file (or the default one embedded in lab). If there are any extends clauses, these needs to be resolved correctly since they could contain extra parserOptions. As such, the parsing can only commence if the .eslintrc.js config works, even though we don't apply or use any rules.

@kanongil
Copy link
Contributor

If we don't want to add it as a peer dependency (as recommended by eslint), we could probably require in the embedded .eslintrc.js, and hook it directly here instead of using a plugin string reference:

extends: 'plugin:@hapi/module'

However, this is cumbersome and still has a peer dependency issue: If @hapi/eslint-plugin ever adds a dependency on another eslint plugin, it will need to be declared as a peer dependency. Thus the parent project will end up with it as a dependency, but strangely with no direct dependency on @hapi/eslint-plugin.

@Nargonath
Copy link
Member

I didn't look at it this way. With your explanations it makes sense to add it as a peer dependency, thanks @kanongil for raising the issue. I'll open a PR to fix it.

@Nargonath Nargonath added this to the v24.3.3 milestone Jul 16, 2021
Nargonath added a commit that referenced this issue Jul 16, 2021
cjihrig added a commit to cjihrig/belly-button that referenced this issue Sep 12, 2021
cjihrig added a commit to cjihrig/belly-button that referenced this issue Sep 12, 2021
@jmac105
Copy link

jmac105 commented Oct 18, 2021

I've run into this same issue with @hapi/[email protected] & [email protected], node 14.17.0 & npm 7.24.0. The error seems related to both this and #1021, because I don't get the same error if I downgrade eslint to 7.x.x

npm test command: lab --verbose --colors -S -r console -r html -o stdout -o coverage.html -a @hapi/code -p 1

relavent dependency tree:

➜ npm ls eslint @hapi/eslint-plugin @hapi/lab

[email protected] /Users/myuser/Repos/myproject
├─┬ @myprivateorg/[email protected]
│ └── [email protected] deduped
├─┬ @hapi/[email protected]
│ ├─┬ @babel/[email protected]
│ │ └── [email protected] deduped
│ ├── @hapi/[email protected]
│ └── [email protected]
└─┬ [email protected]
  └─┬ [email protected]
    └── [email protected] deduped

And the error we get (which exits with code 0 so isn't getting flagged as a fail by our CI server 😕 )

(node:59134) UnhandledPromiseRejectionWarning: Error: Failed to load plugin '@hapi' declared in 'BaseConfig': Cannot find module '@hapi/eslint-plugin'
Require stack:
- /Users/myuser/Repos/myproject/__placeholder__.js
Referenced from: BaseConfig
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:885:15)
    at Function.resolve (internal/modules/cjs/helpers.js:94:19)
    at Object.resolve (/Users/myuser/Repos/myproject/node_modules/@hapi/lab/node_modules/@eslint/eslintrc/lib/shared/relative-module-resolver.js:28:50)
    at ConfigArrayFactory._loadPlugin (/Users/myuser/Repos/myproject/node_modules/@hapi/lab/node_modules/@eslint/eslintrc/lib/config-array-factory.js:1017:39)
    at ConfigArrayFactory._loadExtendedPluginConfig (/Users/myuser/Repos/myproject/node_modules/@hapi/lab/node_modules/@eslint/eslintrc/lib/config-array-factory.js:837:29)
    at ConfigArrayFactory._loadExtends (/Users/myuser/Repos/myproject/node_modules/@hapi/lab/node_modules/@eslint/eslintrc/lib/config-array-factory.js:779:29)
    at ConfigArrayFactory._normalizeObjectConfigDataBody (/Users/myuser/Repos/myproject/node_modules/@hapi/lab/node_modules/@eslint/eslintrc/lib/config-array-factory.js:720:25)
    at _normalizeObjectConfigDataBody.next (<anonymous>)
    at ConfigArrayFactory._normalizeObjectConfigData (/Users/myuser/Repos/myproject/node_modules/@hapi/lab/node_modules/@eslint/eslintrc/lib/config-array-factory.js:665:20)
    at _normalizeObjectConfigData.next (<anonymous>)
    at ConfigArrayFactory.create (/Users/myuser/Repos/myproject/node_modules/@hapi/lab/node_modules/@eslint/eslintrc/lib/config-array-factory.js:460:16)
    at createBaseConfigArray (/Users/myuser/Repos/myproject/node_modules/@hapi/lab/node_modules/@eslint/eslintrc/lib/cascading-config-array-factory.js:98:48)
    at new CascadingConfigArrayFactory (/Users/myuser/Repos/myproject/node_modules/@hapi/lab/node_modules/@eslint/eslintrc/lib/cascading-config-array-factory.js:234:30)
    at new CLIEngine (/Users/myuser/Repos/myproject/node_modules/@hapi/lab/node_modules/eslint/lib/cli-engine/cli-engine.js:569:36)
    at Object.<anonymous> (/Users/myuser/Repos/myproject/node_modules/@hapi/lab/lib/modules/coverage.js:21:19)
    at Module._compile (internal/modules/cjs/loader.js:1068:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
    at Module.load (internal/modules/cjs/loader.js:933:32)
    at Function.Module._load (internal/modules/cjs/loader.js:774:14)
    at Module.require (internal/modules/cjs/loader.js:957:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.get [as coverage] (/Users/myuser/Repos/myproject/node_modules/@hapi/lab/lib/modules/index.js:15:20)
    at Object.exports.run (/Users/myuser/Repos/myproject/node_modules/@hapi/lab/lib/cli.js:38:17)
    at main (/Users/myuser/Repos/myproject/node_modules/@hapi/lab/bin/lab:56:48)
    at Object.<anonymous> (/Users/myuser/Repos/myproject/node_modules/@hapi/lab/bin/lab:60:1)
    at Module._compile (internal/modules/cjs/loader.js:1068:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
    at Module.load (internal/modules/cjs/loader.js:933:32)
    at Function.Module._load (internal/modules/cjs/loader.js:774:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47
(Use `node --trace-warnings ...` to show where the warning was created)
(node:59134) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:59134) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

@jmac105
Copy link

jmac105 commented Oct 18, 2021

Related to the above: I've also found the issue doesn't occur if I remove eslint from dev dependencies completely. Confused by that because due to the de-duplication npm does I will still have [email protected] at the root of my project's node_modules which is just the same outcome as if I had [email protected] as one of my devDependencies...

@devinivy devinivy modified the milestones: v24.4.0, 24.4.1 Nov 9, 2021
@hueniverse hueniverse removed this from the 24.5.0 milestone Dec 31, 2021
@hueniverse hueniverse added this to the 24.5.1 milestone Jan 19, 2022
Cruikshanks added a commit to DEFRA/hapi-pg-rest-api that referenced this issue Jul 5, 2022
The issue hapijs/lab#1017 includes a comment from someone who solved it by removing eslint as a dependency. As we should be using standardjs anyway we're just trying removing eslint to see if that moves us further.
Cruikshanks added a commit to DEFRA/hapi-pg-rest-api that referenced this issue Sep 1, 2022
DEFRA/water-abstraction-team#4

As a team, we are currently maintaining 11 repos and that's not including documentation, support and deployment-related stuff! What we inherited was not consistent; different CI tools were used for the same purpose and different CI steps were implemented.

An effort was made to get this under control with [water-abstraction-orchestration](https://github.com/DEFRA/water-abstraction-orchestration). But to get a handle on it in such a way as the current team can manage, we're simplifying still further.

This change updates `.github/workflows/ci.yml` to use a template we're applying across all the repos, amended to the requirements of the project. In the future, we hope to return to the lessons **water-abstraction-orchestration** taught us, if only to remove the duplication across the projects. But for now, the template hopefully simplifies and makes consistent our build process.

**Notes**

- Add .nvmrc

We use it locally and in the CI to determine the version of Node to use. This repo didn't have one. So, we've added it and set the version to match what WRLS use for node.js.

- Apply ci.yml template

This is very much based on https://github.com/DEFRA/sroc-charging-module-api/blob/main/.github/workflows/ci.yml

There is now one process, which means you'll just see the one item listed in the checks on GitHub. The steps are ordered in an effort to fail fast and/or where needed, for example, DB migrations before running tests and SonarCloud analysis after code coverage data has been generated.

Specifically for this project, it also moves us away from using travis-ci.org, which was the first CI provider we integrated many, _many_ years ago. Defra has since migrated all their repos to travis-ci.com, then finally GitHub actions. Clearly, this one has been overlooked.

- Update .labrc

This is based on https://github.com/DEFRA/sroc-charging-module-api/blob/main/.labrc.js. We use the config file to ensure we generate the coverage output in a format needed by SonarCloud.

- Add SonarCloud properties file

Previously, the CI specified the values SonarCloud needs in its steps plus there were some in the web UI. But there are a bunch of other things we can tell SonarCloud about which makes managing SonarCloud much easier.

So, we use `sonar-project.properties` files to set what the SonarCloud analysis step needs and what's useful in its UI.

- Update README with new badges

Also displays the badges we want in a layout that is consistent with most open source repos.

- Switch to standardjs

We had a problem trying to get the project to build again. We found [this issue](hapijs/lab#1017) which includes a comment from someone who solved it by removing eslint as a dependency. As we should be using standardjs anyway we removed eslint and switched to standardjs as part of this change. Normally, we would have done it as part of separate PR.

- Remove setting table owners in migration code

This breaks doing stuff locally and in our CI pipeline. The create migrations appear to be generated directly from pgAdmin so we also removed other statements which are not needed.

- Update to hapi lab and code dependencies

Hapi lab was listed x2 as a dev dependency. Once, as the new @hapi/hapi but the second time under the old `hapi` namespace. Also, old `lab` and `Code` were listed as the test dependencies.

The old Hapi looks like it was bringing in a version of catbox-memory that depended on `big-time` but that wasn't actually getting installed. We removed it but to be on the safe side we have also updated the versions of Lab and Code to use those under the `@hapi` namespace.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug or defect
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants