Skip to content

Commit

Permalink
Merge pull request #1656 from belgattitude/centralize-linter-config
Browse files Browse the repository at this point in the history
Centralize linter configs
  • Loading branch information
belgattitude authored Apr 11, 2022
2 parents fae32f6 + 019d5b1 commit bafb627
Show file tree
Hide file tree
Showing 48 changed files with 1,508 additions and 708 deletions.
11 changes: 11 additions & 0 deletions .changeset/long-pumas-smash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"nextjs-app": minor
"remix-app": minor
"vite-app": minor
"@your-org/core-lib": minor
"@your-org/db-main-prisma": minor
"@your-org/ui-lib": minor
"@your-org/eslint-config-bases": minor
---

Improved linter configs
1 change: 1 addition & 0 deletions .ncurc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ reject: [
'is-port-reachable',
# Till cache-interop supports it
'ioredis',
# Not ready yet
'@types/react',
'@types/react-dom',
]
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
lts/fermium
lts/gallium
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.yarn
**/.next/**
**/dist/**
**/build/**
**/tmp/**
29 changes: 15 additions & 14 deletions .prettierrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@
/**
* @type {import('prettier').Config}
*/

const { getPrettierConfig } = require('@your-org/eslint-config-bases/helpers');

const { overrides = [], ...prettierConfig } = getPrettierConfig();

module.exports = {
singleQuote: true,
semi: true,
tabWidth: 2,
bracketSpacing: true,
trailingComma: 'es5',
bracketSameLine: false,
useTabs: false,
endOfLine: 'lf',
...prettierConfig,
overrides: [
{
files: '*.md',
options: {
singleQuote: false,
quoteProps: 'preserve',
...overrides,
...[
{
files: '*.md',
options: {
singleQuote: false,
quoteProps: 'preserve',
},
},
},
],
],
};
91 changes: 14 additions & 77 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ Useful to
└── packages
├── core-lib
├── db-main-prisma
└── ui-lib (emotion, storybook)
├── eslint-config-bases (to shared eslint configs)
└── ui-lib (emotion, storybook)
```

#### Example apps
Expand All @@ -68,6 +69,7 @@ Useful to

- [packages/core-lib](./packages/core-lib): publishable. [README](./packages/core-lib/README.md) | [CHANGELOG](./packages/core-lib/CHANGELOG.md)
- [packages/db-main-prisma](./packages/db-main-prisma): used by web-app. [README](./packages/db-main-prisma/README.md) | [CHANGELOG](./packages/db-main-prisma/CHANGELOG.md)
- [packages/eslint-config-bases](./packages/eslint-config-bases): [README](./packages/eslint-config-bases/README.md) | [CHANGELOG](./packages/eslint-config-bases/CHANGELOG.md)
- [packages/ui-lib](./packages/ui-lib): publishable. [README](./packages/ui-lib/README.md) | [CHANGELOG](./packages/ui-lib/CHANGELOG.md)

> Apps can depend on packages, packages can depend on each others...
Expand Down Expand Up @@ -124,6 +126,12 @@ If needed static resources like **locales**, **images**,... can be shared by usi
│ │ ├── package.json
│ │ └── tsconfig.json
│ │
│ ├── eslint-config-bases
│ │ ├── src/
│ │ ├── CHANGELOG.md
│ │ ├── package.json
│ │ └── tsconfig.json
│ │
│ └── ui-lib (basic design-system in react)
│ ├── src/
│ ├── CHANGELOG.md
Expand Down Expand Up @@ -204,46 +212,11 @@ Initialize a package.json with the name of your package.
"fix:all-files": "eslint . --ext .ts,.tsx,.js,.jsx --fix",
},
"devDependencies": {
"@testing-library/jest-dom": "5.14.1",
"@testing-library/react": "12.0.0",
"@testing-library/react-hooks": "7.0.1",
"@types/node": "16.4.10",
"@types/react": "17.0.15",
"@types/react-dom": "17.0.9",
"@typescript-eslint/eslint-plugin": "4.29.0",
"@typescript-eslint/parser": "4.29.0",
"camelcase": "6.2.0",
"eslint": "7.32.0",
"eslint-config-prettier": "8.3.0",
"eslint-plugin-import": "2.23.4",
"eslint-plugin-jest": "24.4.0",
"eslint-plugin-jest-formatting": "3.0.0",
"eslint-plugin-jsx-a11y": "6.4.1",
"eslint-plugin-prettier": "3.4.0",
"eslint-plugin-react": "7.24.0",
"eslint-plugin-react-hooks": "4.2.0",
"eslint-plugin-testing-library": "4.10.1",
"jest": "27.0.6",
"npm-run-all": "4.1.5",
"prettier": "2.3.2",
"react": "17.0.2",
"react-dom": "17.0.2",
"rimraf": "3.0.2",
"shell-quote": "1.7.2",
"ts-jest": "27.0.4",
"typescript": "4.3.5",
},
"peerDependencies": {
"react": "^16.14.0 || ^17.0.2",
"react-dom": "^16.14.0 || ^17.0.2",
"@your-org/eslint-config-bases": "workspace:^",
},
}
```

> _Note that as we want to be strict with dependencies, the best is to
> define all you need (eslint, ...) per package. And not in the monorepo root.
> That might seem weird, but on the long run it's much safer._
</details>

### 3. Using the package in app
Expand All @@ -256,7 +229,7 @@ yarn and pnpm.

```bash
cd apps/my-app
yarn add @your-org/magnificent-poney@'workspace:*'
yarn add @your-org/magnificent-poney@'workspace:^'
```

Inspiration can be found in [apps/nextjs-app/package.json](./apps/nextjs-app/package.json).
Expand All @@ -268,7 +241,7 @@ Inspiration can be found in [apps/nextjs-app/package.json](./apps/nextjs-app/pac
{
"name": "my-app",
"dependencies": {
"@your-org/magnificient-poney": "workspace:*",
"@your-org/magnificient-poney": "workspace:^",
},
}
```
Expand Down Expand Up @@ -429,11 +402,8 @@ They are based on the excellent [npm-check-updates](https://github.com/raineorsh

### 5.1 Linters

An example of base eslint configuration can be found in [./.eslint.base.js](./.eslintrc.base.js), apps
and packages extends it in their own root folder, as an example see [./apps/nextjs-app/.eslintrc.js](./apps/nextjs-app/.eslintrc.js).
Prettier is included in eslint configuration as well as [eslint-config-next](https://nextjs.org/docs/basic-features/eslint) for nextjs apps.

For code complexity and deeper code analysis [sonarjs plugin](https://github.com/SonarSource/eslint-plugin-sonarjs) is activated.
See an example in [./apps/nextjs-app/.eslintrc.js](./apps/nextjs-app/.eslintrc.js) and our
[eslint-config-bases](./packages/eslint-config-bases/README.md).

### 5.2 Hooks / Lint-staged

Expand Down Expand Up @@ -557,39 +527,6 @@ To help keeping deps up-to-date, see the `yarn deps:check && yarn deps:update` s
> by setting `defaultSemverRangePrefix: ""` in [yarnrc.yml](./.yarnrc.yml). But this would make the default for packages/\* as well.
> Better to handle `yarn add something --exact` on per-case basis.
#### About next-transpile-modules
And why this repo example doesn't use it to support package sharing.
[next-transpile-modules](https://github.com/martpie/next-transpile-modules) is one of the most installed
packages for nextjs. It basically allows you to transpile some 3rd party packages present in your node_modules folder.
This can be helpful for transpiling packages for legacy browser support (ie11), esm packages (till it lands in nextjs) and
handle shared packages.
In this repo, we use next-transpile-modules only for ie11 and esm. The monorepo management is done through [tsconfig path](https://github.com/vercel/next.js/pull/13542).
It will work best when external tooling is involved (ts-jest...), but comes with some limitations if your shared package use an
scss compiler for example. Note that future version of NextJs might improve monorepo support through [experimental.externalDir option](https://github.com/vercel/next.js/pull/22867).
See here a quick comparison:
| Support matrix | tsconfig paths | next-transpile-module |
| ------------------- | ------------------ | ------------------------- |
| Typescript | ✅ | ✅ |
| Javascript | ✅ | ✅ |
| NextJs Fast refresh | ✅ | ✅ |
| CSS | custom webpack cfg | ✅ |
| SCSS | custom webpack cfg | ✅ |
| CSS-in-JS | ✅ | ✅ |
| ts-jest | ✅ | custom aliases |
| Vercel monorepo | ✅ | ✅ |
| Yarn 2 PNP | ✅ | ✅ |
| Webpack5 | ✅ | ✅ |
| Publishable (npm) | ✅ | ❌ (ntm relies on "main") |
## See also
- https://stackoverflow.com/a/69554480/5490184
## License
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fbelgattitude%2Fnextjs-monorepo-example.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fbelgattitude%2Fnextjs-monorepo-example?ref=badge_large)
55 changes: 18 additions & 37 deletions apps/nextjs-app/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,37 @@
* @see https://github.com/belgattitude/nextjs-monorepo-example/blob/main/docs/about-linters.md
*/

const {
getDefaultIgnorePatterns,
} = require('@your-org/eslint-config-bases/helpers');

module.exports = {
root: true,
ignorePatterns: ['.next', '**/.out'],
ignorePatterns: [...getDefaultIgnorePatterns(), '.next', '.out'],
extends: [
// Extend the monorepo default configuration
'../../.eslintrc.base.js',
// Add specific rules for react
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:jsx-a11y/recommended',
'@your-org/eslint-config-bases/typescript',
'@your-org/eslint-config-bases/sonar',
'@your-org/eslint-config-bases/regexp',
'@your-org/eslint-config-bases/jest',
'@your-org/eslint-config-bases/react',
'@your-org/eslint-config-bases/rtl',
'@your-org/eslint-config-bases/graphql-schema',
// Add specific rules for nextjs
'plugin:@next/next/core-web-vitals',
// Apply prettier and disable incompatible rules
'@your-org/eslint-config-bases/prettier',
],
env: {
browser: true,
es6: true,
node: true,
},
rules: {
'react/prop-types': 'off',
'react/react-in-jsx-scope': 'off',
'jsx-a11y/anchor-is-valid': 'off',
'react/no-unescaped-entities': 'off',
// next/image might not be yet a good move as of NextJs v11.
// https://github.com/vercel/next.js/discussions/16832
'@next/next/no-img-element': 'off',
// For the sake of example
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/HEAD/docs/rules/anchor-is-valid.md
'jsx-a11y/anchor-is-valid': 'off',
},
overrides: [
{
// For performance run jest/recommended on test files, not regular code
files: ['**/*.test.{ts,tsx}'],
extends: ['plugin:testing-library/react'],
},
{
files: ['src/pages/**/*.{ts,tsx}'],
files: ['src/pages/\\_*.{ts,tsx}'],
rules: {
'@typescript-eslint/explicit-module-boundary-types': 'off',
'react/display-name': 'off',
},
},
Expand All @@ -56,18 +50,5 @@ module.exports = {
],
},
},
{
files: ['src/backend/api/**/*.ts'],
rules: {
'@typescript-eslint/explicit-module-boundary-types': 'off',
},
},
{
files: ['config/jest/test-utils.tsx'],
rules: {
'@typescript-eslint/explicit-module-boundary-types': 'off',
'import/export': 'off',
},
},
],
};
8 changes: 4 additions & 4 deletions apps/nextjs-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@
"test-unit": "jest --config jest.config.js",
"test-e2e": "cross-env E2E_WEBSERVER_MODE=BUILD_AND_START playwright test",
"typecheck": "tsc --project ./tsconfig.json --noEmit",
"lint": "eslint . --ext .ts,.tsx,.js,.jsx --cache",
"fix-all-files": "eslint . --ext .ts,.tsx,.js,.jsx --fix",
"lint": "eslint . --ext .ts,.tsx,.js,.jsx,.mdx,.graphql --cache",
"fix-all-files": "eslint . --ext .ts,.tsx,.js,.jsx,.mdx,.graphql --fix",
"?postinstall": "@todo: the prisma generate seems to be required, but is installed at the root",
"postinstall": "test -n \"$SKIP_POSTINSTALL\" || yarn workspace @your-org/db-main-prisma run prisma generate"
},
"devDependencies": {
"@emotion/babel-plugin": "11.7.2",
"@emotion/babel-plugin": "11.9.2",
"@next/bundle-analyzer": "12.1.4",
"@next/env": "12.1.4",
"@playwright/test": "1.20.2",
Expand Down Expand Up @@ -143,7 +143,7 @@
"picocolors": "1.0.0",
"react": "18.0.0",
"react-dom": "18.0.0",
"react-i18next": "11.16.4",
"react-i18next": "11.16.5",
"react-query": "3.34.19",
"rooks": "5.11.0",
"sharp": "0.30.3",
Expand Down
2 changes: 1 addition & 1 deletion apps/nextjs-app/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@your-org/db-main-prisma": ["../../../packages/db-main-prisma/src/index"]
}
},
"exclude": ["**/node_modules", "**/.*/", ".next"],
"exclude": ["**/node_modules", "**/.*/", ".next", ".out"],
"include": [
"next-env.d.ts",
"**/*.ts",
Expand Down
48 changes: 21 additions & 27 deletions apps/remix-app/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,36 @@
* @see https://github.com/belgattitude/nextjs-monorepo-example/blob/main/docs/about-linters.md
*/

const {
getDefaultIgnorePatterns,
} = require('@your-org/eslint-config-bases/helpers');

module.exports = {
root: true,
ignorePatterns: ['public/build', 'api/build', '.cache'],
ignorePatterns: [
...getDefaultIgnorePatterns(),
'public/build',
'api/build',
'.cache',
],
extends: [
// Extend the monorepo default configuration
'../../.eslintrc.base.js',
// Add specific rules for react
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:jsx-a11y/recommended',
'@your-org/eslint-config-bases/typescript',
'@your-org/eslint-config-bases/sonar',
'@your-org/eslint-config-bases/regexp',
'@your-org/eslint-config-bases/jest',
'@your-org/eslint-config-bases/react',
'@your-org/eslint-config-bases/rtl',
'@your-org/eslint-config-bases/graphql-schema',
// Specific rules for remix
'@remix-run/eslint-config',
// Apply prettier and disable incompatible rules
'@your-org/eslint-config-bases/prettier',
],
env: {
browser: true,
es6: true,
node: true,
},
rules: {
'react/prop-types': 'off',
'react/react-in-jsx-scope': 'off',
'jsx-a11y/anchor-is-valid': 'off',
'react/no-unescaped-entities': 'off',
'react/jsx-no-target-blank': 'off',
},
overrides: [
{
// For performance run jest/recommended on test files, not regular code
files: ['**/*.test.{ts,tsx}'],
extends: ['plugin:testing-library/react'],
},
{
files: ['config/jest/test-utils.tsx'],
rules: {
'import/export': 'off',
},
},
],
rules: {},
overrides: [],
};
Loading

3 comments on commit bafb627

@vercel
Copy link

@vercel vercel bot commented on bafb627 Apr 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on bafb627 Apr 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

monorepo-remix-app – ./apps/remix-app

monorepo-remix-app.vercel.app
monorepo-remix-app-belgattitude.vercel.app
monorepo-remix-app-git-main-belgattitude.vercel.app

@vercel
Copy link

@vercel vercel bot commented on bafb627 Apr 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

monorepo-nextjs-app – ./apps/nextjs-app

monorepo-nextjs-app-belgattitude.vercel.app
monorepo-nextjs-app.vercel.app
monorepo-nextjs-app-git-main-belgattitude.vercel.app

Please sign in to comment.