Giter Club home page Giter Club logo

lint-staged-multi-pkg's Introduction

lint-staged-multi-pkg

Example repo to demostrate use of lint-staged in multi package project with lerna and husky.

pre-commit hook

husky is installed in the root package.json as recommended in husky docs.

The pre-commit hook is configured with the script lerna run --concurrency 1 --stream precommit --since HEAD --exclude-dependents. This executes the precommit script for each package (if it exists). Execution is limited to only those packages with modified files, however the --since HEAD --exclude-dependents option does not consider whether the file is staged. To further limit precommit to only staged files please look at the discussion in sudo-suhas/lint-staged-multi-pkg#4. Furthermore, concurrent execution is disabled because it can cause problems during git add (see okonet/lint-staged#225).

lint-staged configuration

Starting with v5.0, lint-staged automatically resolves the git root without any additional configuration. You configure lint-staged as you normally would, if your project root and git root were the same directory.

Project structure:

.
|-- .git
|-- .gitattributes
|-- .gitignore
|-- lerna.json
|-- license
|-- package.json
|-- packages
|   |-- say-bye
|   |   |-- .eslintrc.yml
|   |   |-- .lintstagedrc.yml
|   |   |-- lib
|   |   |   `-- index.js
|   |   |-- package.json
|   |   `-- yarn.lock
|   `-- say-hi
|       |-- .eslintrc.yml
|       |-- .lintstagedrc.yml
|       |-- package.json
|       |-- src
|       |   `-- index.js
|       `-- yarn.lock
|-- readme.md
`-- yarn.lock

lint-staged config for package say-hi, .lintstagedrc.yml:

linters:
  src/*.js:
    - eslint --fix
    - git add

Note: lint-staged has not been upgraded to v8 as it requires Node >= 8.6.

Output

Example output from the git hook execution:

$ git commit
husky > pre-commit (node v11.9.0)
lerna notice cli v3.13.1
lerna info Executing command in 2 packages: "yarn run precommit"
say-bye: yarn run v1.13.0
say-bye: $ lint-staged
say-bye: Running tasks for lib/*.js [started]
say-bye: eslint --fix [started]
say-bye: eslint --fix [completed]
say-bye: git add [started]
say-bye: git add [completed]
say-bye: Running tasks for lib/*.js [completed]
say-bye: Done in 1.05s.
say-hi: yarn run v1.13.0
say-hi: $ lint-staged
say-hi: Running tasks for src/*.js [started]
say-hi: eslint --fix [started]
say-hi: eslint --fix [completed]
say-hi: git add [started]
say-hi: git add [completed]
say-hi: Running tasks for src/*.js [completed]
say-hi: Done in 1.03s.
lerna success run Ran npm script 'precommit' in 2 packages in 2.5s:
lerna success - say-bye
lerna success - say-hi

What if I don't want to or can't use lerna?

You might not want to use lerna either because you think it is overkill or if you have a different monorepo setup than the one required by lerna. You can still use lint-staged, though not as easily:

Install lint-staged at the package root

Install lint-staged and husky at the project root and configure all linters at the root:

Project structure:

.
|-- .git
|-- .gitignore
|-- .lintstagedrc.yml πŸ’€ Our `lint-staged` config at the monorepo root.
|-- package.json
|-- prj-1
|   |-- .eslintrc.yml
|   |-- .gitignore
|   |-- package.json
|   |-- src
|   |   `-- index.js
|   `-- yarn.lock
`-- prj-2
    |-- .eslintrc.yml
    |-- .gitignore
    |-- package.json
    |-- src
    |   `-- index.js
    `-- yarn.lock

.lintstagedrc.yml:

linters:
  prj-1/*.js:
    - eslint --fix
    - some-other-cmd
    - git add
  prj-2/**/*.js:
    - eslint --fix
    - git add

Note: All linters would have to be installed in the root package.

Manually call precommit in each package

Install husky at the project root and setup the pre-commit hook to execute the precommit script in each package. npm-run-all could also be used to make things a bit easier:

// package.json
{
  "...": "...",
  "scripts": {
    "precommit:prj-1": "cd prj-1 && npm run precommit",
    "precommit:prj-2": "cd prj-2 && npm run precommit",
    "precommit": "npm-run-all precommit:*"
  },
}

Project structure:

.
|-- .gitignore
|-- package.json
|-- prj-1
|   |-- .eslintrc.yml
|   |-- .gitignore
|   |-- .lintstagedrc.yml πŸ’€ Each project has it's own config.
|   |-- package.json
|   |-- src
|   |   `-- index.js
|   `-- yarn.lock
`-- prj-2
    |-- .eslintrc.yml
    |-- .gitignore
    |-- .lintstagedrc.yml
    |-- package.json
    |-- src
    |   `-- index.js
    `-- yarn.lock

License

MIT Β© Suhas Karanth

lint-staged-multi-pkg's People

Contributors

bertho-zero avatar dependabot[bot] avatar sudo-suhas avatar thomaslamb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

lint-staged-multi-pkg's Issues

Not working without learna

I'm trying to follow the instructions and I'm not using lerna and to "Manually call precommit in each package".

I'm following the instructions in section "Manually call precommit in each package", where I have a .lintstagedrc.yml in each project's own folder. lint-staged and husky has been installed at the project root. I've got husky setup with npm-run-all and husky is working with the precommit hook.

However, my hook doesn't seem to get called when I stage my files.

I think I'm missing some more configuration. Can you please provide more details on your instructions for the section "Manually call precommit in each package"?

Thank you very much!

Latest husky version

Can this example be updated having in mind the latest version of husky? t would be very helpful.

Add basic eslint + prettier to this precommit flow as well

Great example repo! I think it would also be useful to document how adding eslint and prettier would be added to this as well.

For example, you likely have one .prettierrc file because you want your JS code to read the same throughout, but you could have multiple .eslintrc files for each project based on different settings.

"Install lint-staged at the package root" solution requires extra works?

I checked out the description and installed husky, lint-staged, prettier, stylelint in project root, and configured hooks in .lintstagedrc.yml, however they didn't work.

My dir structure:

|-- .git
|-- .gitignore
|-- .lintstagedrc.yml
|-- .prettierrc
|-- node_modules
|-- package.json
|-- yarn.lock
|
|-- my-project-1
|
`-- my-project- 2
    |-- package.json
    |-- src
    |   |-- a
    |   |     |-- index.ts
    |   |     `-- index.less
    |   `-- b
    |          `-- index.ts
    `-- yarn.lock

.lintstagedrc.yml

linters:
  my-project-2/**/*.{ts,tsx,json}:
    - prettier --config ./.prettierrc --write
  my-project-2/**/*.{css,less}:
    - stylelint --fix

I tried to add husky configs in package.json and it still didn't solve the problem:

{
   "husky": {
      "hooks": {
        "pre-commit": "lint-staged"
      }
   },
   ...
}

I wonder if I missed something, or we should only install these dependencies and configure .lintstagedrc in project root without some extra works?

It didn't work!

I just clone the repo, change the eslintrc: no-console: off -> no-console: error.

then

$ npx lerna bootstrap
$ git add .
$ git commit -m "test"

the result is:

husky > pre-commit (node v8.17.0)
lerna notice cli v3.13.1
lerna info Executing command in 2 packages: "yarn run precommit"
say-bye: yarn run v1.22.1
say-bye: $ lint-staged
say-bye: Running tasks for lib/.js [started]
say-bye: Running tasks for lib/
.js [skipped]
say-bye: β†’ No staged files match lib/.js
say-bye: Done in 0.46s.
say-hi: yarn run v1.22.1
say-hi: $ lint-staged
say-hi: Running tasks for src/
.js [started]
say-hi: Running tasks for src/.js [skipped]
say-hi: β†’ No staged files match src/
.js
say-hi: Done in 0.43s.
lerna success run Ran npm script 'precommit' in 2 packages in 1.3s:
lerna success - say-bye
lerna success - say-hi
[test 7ade78b] test
2 files changed, 2 insertions(+), 2 deletions(-)

I tried under win10/osx/ubuntu-18.04, they ware same.

Eslint-plugin-react was not loaded as a node module from the directory

Hi @sudo-suhas ,

Thank you for creating such a great example. I am new to eslint and trying to lint my code using lint-staged package with pre-commit hook. Frontend project is react+ typescript, common is nodejs project and backend is NestJS project. My project structure is as below:

|-- .gitignore
|-- package.json
|-- frontend
|   |- .eslintrc.yml
|   |- .package.json
|   |   |-- src
|   |   |   --app.tsx
|   |   |   --index.ts
|-- backend
|   |- .eslintrc.yml
|   |- .package.json
|   |   |-- src
|   |   |   --app.tsx
|   |   |   --index.ts
|-- common
|   |- .eslintrc.yml
|   |- .package.json
|   |   |-- src
|   |   |   --app.tsx
|   |   |   --index.ts

My root package.json is as below:

"devDependencies": {
    "eslint": "~6.6.0",
    "husky": "~3.0.7",
    "lint-staged": "~9.4.0"
 },
"husky": {
    "hooks": {
      "pre-commit": "lint-staged",
    }
  },
  "lint-staged": {
    "common/**/*.{ts,tsx}": [
      "eslint --fix",
      "git add"
    ],
    "backend/**/*.{ts,tsx}": [
      "eslint --fix",
      "git add"
    ],
    "frontend/**/*.{ts,tsx}": [
      "eslint --fix",
      "git add"
    ]
  }

But, when I try to commit my staged files having linter errors, I am getting an error as below:

husky > pre-commit (node v12.18.0)
  ↓ Stashing changes... [skipped]
    β†’ No partially staged files found...
  ❯ Running tasks...
    ↓ Running tasks for common/**/*.{ts,tsx} [skipped]
      β†’ No staged files match common/**/*.{ts,tsx}
    ↓ Running tasks for backend/**/*.{ts,tsx} [skipped]
      β†’ No staged files match server/**/*.{ts,tsx}
    ❯ Running tasks for frontend/**/*.{ts,tsx}
      βœ– eslint --fix
        git add

βœ– eslint --fix found some errors. Please fix them and try committing again.

Oops! Something went wrong! :(

ESLint: 6.6.0.

ESLint couldn't find the plugin "eslint-plugin-react".

(The package "eslint-plugin-react" was not found when loaded as a Node module from the directory "/Projects/demoproject.)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react@latest --save-dev

The plugin "eslint-plugin-react" was referenced from the config file in "frontend/.eslintrc.js".

If you still can't figure out the problem, please stop by https://gitter.im/eslint/eslint to chat with the team.
husky > pre-commit hook failed (add --no-verify to bypass)

What am I doing wrong here?

lint staged config with react-express monorepo failing

Hi,
I have project with react and express but it is not wrapped using lerna.
project structure:

project
β”œβ”€β”€ client/
β”‚   β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ package.json
β”‚   β”œβ”€β”€ index.js
β”‚   └── utils.js
β”œβ”€β”€ cli.js
β”œβ”€β”€ src/
β”œβ”€β”€ index.js
β”œβ”€β”€ config.js
└── package.json

So outside folder contains all express related files and client folder has create-react-react(typescript) project. I have separate eslint config for both. express eslint is in root and react's eslint is in client folder.

my scripts in base package.json:

"lint": "eslint .",
"lint:fix": "eslint . --fix",
"client:lint": "cd client && npm run lint",
"client:lint:fix": "cd client && npm run lint:fix",

my husky and lint-staged config:

"lint-staged": {
    "./**/*": [
      "npm run lint:fix"
    ],
    "./client/**/*.{js,jsx,ts,tsx}": [
      "npm run client:lint:fix"
    ]
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },

what I need is,

  1. if file is from base express directory then it should run first task on it for linting and then add
  2. and if file is from client folder then it should use client lint command to fix

so in my configuration, it is working fine for express files but sometimes it is failing in client related files.
it says,

Prevented an empty git commit!

Because even if my react files have changes and linting errors it is not committing those files after running the lint fixes.

Can anyone please help me with the correct lint-staged config

while committing to this branch it is giving errors in .eslintignore etc file which are ignored like following, so I pushed it with --no-verify flag
Screenshot 2020-07-20 at 10 16 56 PM

Thank you

Not works, no output.

root folder

"lerna": "3.11.0",
"husky": "^1.3.1"

lerna.json

"packages": [
    "pack1",
    "pack2"
  ],

pack 1 and pack2 have this in package.json in scripts

"precommit": "lint-staged"

With .lintstagedrc.yml

linters:
  "src/main/js/**/*.js":
    - "eslint src/main/js --fix"       
    - "prettier --print-width 120 --tab-width 4 --trailing-comma none --write src/main/js/**/*.js"                    
    - "git add"

After commit nothing. I mean no any messages/output

It works only from terminal.
I mean i need run
git add -A
npm run -s precommit

But if i do normat flow for commit - nothing

Docs: Why use lerna run --concurrency 1?

Thank you for creating this repo! It helped me a lot!

You documented everything very well, I only have one question: why is lerna not run in parallel? Is it because this might mess up the logs?

Perhaps it would be nice to add the reasoning to the README.md?

Further documentation for "Install lint-staged at the package root"

What should the new package.json look like for root and each package?

Is this still the same for root package.json or should it be changed? Should everything be removed from the package package.json files since it's now handled by root instead?

  "husky": {
    "hooks": {
      "pre-commit": [
        "lerna run --concurrency 1 --stream precommit"
      ]
    }
  },

Basically, I want the following to occur for all packages:

  "lint-staged": {
    "*.{js,jsx,ts,tsx}": [
      "npm run lint:fix",
      "git add"
    ],
    "{*.{json,md}}": [
      "prettier --write",
      "git add"
    ]
  },
  "husky": {
    "hooks": {
      "pre-commit": [
        "npm run type-check && lint-staged"
      ]
    }
  },

Example without Lerna and global linter/formatter

Here's another option to use lint-staged at the project root, but still calling linters at package-level. This respects the linter and formatter configs/ignore files of each package.

const package = require('./package.json');
const { workspaces } = package; // or manually define workspaces as ['package-a', 'package-b']
const pattern = '**/*.{js,jsx,ts,tsx}';
const linter = 'node_modules/.bin/eslint --fix';

const rules = Object.fromEntries(workspaces.map(workspace => [`${workspace}/${pattern}`, `./${workspace}/${linter}`]))

module.exports = {
  // results into...
  // 'package-a/**/*.{js,jsx,ts,tsx}': 'package-a/node_modules/.bin/eslint --fix',
  // 'package-b/**/*.{js,jsx,ts,tsx}': 'package-b/node_modules/.bin/eslint --fix'
  ...rules
}

What do you think?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.