Error encountered: When setting up the pre-commit hook for the monorepo, a parsing error occurred stating that the `parserOptions.project` has been configured for the @typescript-eslint

We recently transitioned to a monorepo structure and are currently in the process of setting everything up. Our setup involves TypeScript, ESLint, and Prettier. Here's an overview of our project structure:

root
  - common
    - folder_a
      - file_a.ts
  - build_scripts
    - script_a.js
  - project_a
    - components
      - component_a
        - Component.tsx
    - tsconfig.json
    - .eslintrc.json
    - node_modules
    - package.json
  - .prettierignore
  - .prettierrc.yml
  - .eslintignore
  - .eslintrc.base.json
  - tsconfig.base.json
  - node_modules
  - package.json
  - Makefile
  - webpack.config.js
  - .pre-commit-config.yaml

The common directory contains shared code used across multiple projects and is not considered a standalone project (hence no tsconfig.json). Each sub-project with its own tsconfig.json and .eslintrc.json files extends the base configurations. For example:

tsconfig.base.json

{
    "compilerOptions": {
        "lib": ["ES2017", "DOM"],
        ...
    },
    ...
}

.eslintrc.base.json (abbreviated rules)

{
    "env": {
        "es2020": true,
        ...
    },
    ...
}

And so on for the other configuration files like .eslintignore, .pre-commit-config.yaml, package.json, etc.

In general, our linting and bundling processes work well without errors. However, we encountered an issue when trying to stage and commit changes within project_a where a specific parsing error related to TypeScript-eslint was thrown. This error seems to be triggered only during pre-commit hook linting despite having all necessary configurations set up correctly.

This unexpected behavior could potentially be linked to additional include directives in certain configuration files that might cause conflicts or issues during linting, especially when working with different projects simultaneously. We're actively investigating this issue to identify a resolution.

Answer №1

element, I discovered that the @typescript-eslint/parser resolves the provided tsconfig.json relative to the current working directory. Unfortunately, I overlooked this detail while going through the documentation. Consequently, the pre-commit hook always executes from the root directory, causing it to utilize tsconfig.base.json instead of the one located in project_a. To rectify this issue, the following steps should be followed (as outlined in https://github.com/typescript-eslint/typescript-eslint/issues/251#issuecomment-567365174):
  • Rename project_a/.eslintrc.json to project_a/.eslintrc.js
  • Add parserOptions.tsconfigRootDir as shown below:
  • module.exports = {
      parserOptions: {
        project: './tsconfig.json'
        tsconfigRootDir: __dirname // important option
      }
    }
    

Answer №2

your setup:

- repo: local
  hooks:
    - id: lint_fix
      name: lint_fix_project_a
      entry: node_modules/.bin/eslint --report-unused-disable-directives --fix -c project_a/.eslintrc.json --ext .ts,.tsx
      files: ^project_a/
      types: [file]
      language: node

utilizes language: node, creating a managed environment (pre-commit establishes its own isolated node environment and does not have access to your dependencies)

consider changing to language: system if you want to handle the environment independently from pre-commit


Note: I am the creator of pre-commit

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What could be causing the disappearance of my Angular 6 Service object variable upon refreshing the component it's injected into?

Recently, I encountered an issue with a SERVICE named test.service, which contains an object: public locationObject = { ...... ...... currency: string } In my project, this SERVICE is injected into the HeaderComponent and the object locationObj ...

Combining two interconnected projects: A guide to compiling mutual project dependencies

I am encountering difficulties while constructing a project (@red5/middleware) that relies on another project (@red5/router), which in turn depends on the initial project (@red5/middleware). When I execute the following command: rm -rf types && t ...

Exploring the capabilities of the VSCode Volar extension in a project utilizing Vue 2, Nuxt, Typescript, and the @nuxtjs composition-api

Trying to set up the Volar VSCode extension for a NuxtJS / Typescript project and facing two issues in .vue file templates. Followed the installation guide for Vue 2 and Typescript, and enabled Take Over mode. Solved some codebase issues with the extensio ...

Updating Previous and Next links in an Angular Table following row deletions: A step-by-step guide

I need to implement a feature where row elements can be deleted by enabling checkboxes on the rows and clicking the Delete button. Although I am able to successfully delete items from the table upon clicking the Delete button, I am facing challenges in upd ...

The angular-CLI does not support the use of content delivery networks (CDNs) within the .angular-cli.json

Is there a way to make angular-cli recognize when we add any deployed URLs for styles or scripts using CDN? Currently, adding them to index.html works but adding to .angular-cli.json has no effect. Any workaround available? ...

Assign a variable within a Vue composition file

I'm diving into the world of composition API in Vue and I'm uncertain if my approach is breaking any established patterns. I have a desire to initialize a variable directly within the composition file: GameLogic.ts export default function () { ...

Adjusting the background color of the custom input range thumb when the input is disabled

I've customized the input thumb on my range slider, and I'm looking to change its color when it's disabled. I attempted adding a class to the thumb like this: input[type=range]::-webkit-slider-thumb.disabled and also tried adding the disa ...

Utilize localStorage.getItem() in conjunction with TypeScript to retrieve stored data

Within my codebase, I have the following line: const allGarments = teeMeasuresAverages || JSON.parse(localStorage.getItem("teeMeasuresAverages")) || teeMeasuresAveragesLocal; Unexpectedly, Typescript triggers an alert with this message: Argument ...

Error encountered: Could not find the specified file or directory, 'resultsCapturer.js:.will-be-removed-after-cucumber-runs.tmp'

I'm currently working on automating an Angular 4 application. Whenever I execute "protractor config.js" SCENARIO 1: If the format option in my config.ts file looks like this: format: ['json:../reporting/results.json'] An error message is ...

It is necessary for ReactJS eslint rules to employ destructuring when assigning state

class MyDrawer extends Component { const modalOpen = this.state; // Initialize state in the constructor render() { return ( <div> <Drawer modal open={this.state.modalOpen} // <-- this line show error ...

Strange compilation issue "Syntax error: Unable to access 'map' property of null" occurs when map function is not utilized

I recently developed a custom useToggle hook that does not rely on the .map() method: import { useState } from "react"; export const useToggle = ( initialValue: boolean = false ): [boolean, () => void] => { const [value, setValue] = us ...

Select a single radio button containing values that can change dynamically

<input type="radio" on-click="checkDefaultLanguage" id="checkbox" > [[names(name)]] This custom radio input field contains dynamic values and I am attempting to create a functionality where only one radio button can be selected at a time while dese ...

Can you explain the meaning behind this TypeScript variable declaration syntax?

Can anyone explain the meaning of this code snippet: myCollection: Collection|any = null; I'm having trouble understanding it... Does it indicate that myCollection is set to type Collection, (which is an interface), with a default value of null? But ...

RXJS Implementing a custom error-handling operator

Typically, I have the capability to define a personalized operator and structure a pipe in this manner: public customOperator = () => { return (source: Observable<any>) => { return source.pipe( map(val => { ...

What is the best method for releasing an NX library along with all its bundled dependencies?

This problem is quite common in GitHub's NX repository, but I have not been able to find a solution there. Within my workspace, I have two buildable libraries: ui/avatar and ui/icon, as well as a publishable library named bar The goal is to utilize ...

Guidelines on creating a recursive function in Typescript that calculates the common elements between multiple arrays of strings

I have a code snippet that calculates the intersection of multiple arrays of strings. Play with Typescript here export const findIntersection = (list1: string[], list2: string[], ...otherLists): string[] => { const result = []; for (let i = 0; i & ...

Struggling to implement two-way binding in Mat-Datepicker

I have included my code snippet below. I am utilizing mat-datepicker and customizing it to function as a year picker. The problem arises when I add name="control" #control="ngModel" [(ngModel)]="" to my control, as it throws an error in the console. Howeve ...

Retrieve a particular item using the NGXS selector and incorporate it into the template

I am retrieving stored configuration settings from an API. Each setting includes an 'ID' and several properties like 'numberOfUsers', etc. I am utilizing NGXS for managing the state. My goal is to specifically fetch the 'numberOf ...

Using Angular 2 along with RxJS to transform an array using Rx Observables

I am working with an array of numbers, specifically [1, 2, 3], and utilizing an HTTP service that includes a function to load data objects based on a given number: function get(id: number): Observable<object> Can anyone help me figure out how to map ...

Disabling the scrollbar within angular elements

Trying to remove the two scrollbars from this code, but so far unsuccessful. Attempted using overflow:hidden without success filet.component.html <mat-drawer-container class="example-container" autosize> <button type="button&qu ...