@lewishowles/lint-config 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +36 -15
  2. package/base.json +6 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -8,7 +8,7 @@ Shared oxlint configuration for Lewis Howles projects. One package that every re
8
8
  bun add -d @lewishowles/lint-config @stylistic/eslint-plugin vite-plus
9
9
  ```
10
10
 
11
- `@stylistic/eslint-plugin` and `vite-plus` are peer dependencies — they must be installed in the consuming project so oxlint can resolve the JS plugins from `node_modules`.
11
+ `@stylistic/eslint-plugin` and `vite-plus` are peer dependencies: they must be installed in the consuming project so oxlint can resolve the JS plugins from `node_modules`.
12
12
 
13
13
  ## Usage
14
14
 
@@ -32,7 +32,7 @@ Create a `.oxlintrc.json` in your project root that extends the appropriate laye
32
32
  }
33
33
  ```
34
34
 
35
- The Vue layer extends `base.json` internally — you only need to extend `vue.json`.
35
+ The Vue layer extends `base.json` internally, so you only need to extend `vue.json`.
36
36
 
37
37
  ## Customising
38
38
 
@@ -40,7 +40,7 @@ Your `.oxlintrc.json` stub can override rules, add ignore patterns, add override
40
40
 
41
41
  ### Overriding a rule
42
42
 
43
- To change the severity or options of a rule defined in the shared layer, redeclare it in your stub — your value wins:
43
+ To change the severity or options of a rule defined in the shared layer, redeclare it in your stub: your value wins.
44
44
 
45
45
  ```json
46
46
  {
@@ -64,7 +64,7 @@ Ignore patterns are repo-specific, so they always live in your stub:
64
64
 
65
65
  ### Adding overrides
66
66
 
67
- Overrides are additive — shared overrides (if any) still apply, and your local ones are appended:
67
+ Overrides are additive: shared overrides (if any) still apply, and your local ones are appended.
68
68
 
69
69
  ```json
70
70
  {
@@ -84,38 +84,44 @@ Overrides are additive — shared overrides (if any) still apply, and your local
84
84
 
85
85
  ### Adding plugins
86
86
 
87
- Plugins are additive and deduplicated — your local plugins are added to the shared ones. Note that oxlint only supports its built-in plugin names (`oxc`, `typescript`, `unicorn`, `vue`, etc.) — there is no `playwright` or `vitest` plugin. Test-file-specific behaviour is handled via `overrides`, not plugins.
87
+ Plugins are additive and deduplicated: your local plugins are added to the shared ones. Note that oxlint only supports its built-in plugin names (`oxc`, `typescript`, `unicorn`, `vue`, etc.); there is no `playwright` or `vitest` plugin. Test-file-specific behaviour is handled via `overrides`, not plugins.
88
88
 
89
89
  ## Layers
90
90
 
91
91
  | Layer | File | Contents |
92
92
  | ------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
93
- | `base` | `base.json` | Correctness rules, `@stylistic` formatting rules, `vite-plus/prefer-vite-plus-imports`, `oxc` + `typescript` + `unicorn` plugins, browser env, node env for config files (`vite.config.*`, `vitest.config.*`, `playwright*.config.*`) |
93
+ | `base` | `base.json` | Correctness rules, named-import member sorting, `@stylistic` formatting rules, `vite-plus/prefer-vite-plus-imports`, `oxc` + `typescript` + `unicorn` plugins, browser env, node env for config files (`vite.config.*`, `vitest.config.*`, `playwright*.config.*`) |
94
94
  | `vue` | `vue.json` | Extends `base`. Adds `vue` plugin, Vue compiler macros as globals, Vue-specific rules |
95
95
 
96
+ ### Import sorting ownership
97
+
98
+ The base layer sorts named members within each import declaration. It sets `ignoreDeclarationSort: true` because Oxlint reports declaration-row ordering but does not auto-fix it.
99
+
100
+ Consumers that want import declaration rows sorted should enable Oxfmt's `sortImports` option in their local `.oxfmtrc.json`. This keeps member sorting in the shared Oxlint layer and declaration ordering in the formatter that can fix it.
101
+
96
102
  ## What stays repo-local
97
103
 
98
- - `ignorePatterns` — every repo has different build output and tool directories
99
- - `overrides` for repo-specific directories (e.g. `bin/**/*.js`, `src/cli/**/*.js`, `src/playwright/**/*.js`) — the file paths differ per repo, so they can't be generalised
104
+ - `ignorePatterns`, since every repo has different build output and tool directories
105
+ - `overrides` for repo-specific directories (e.g. `bin/**/*.js`, `src/cli/**/*.js`, `src/playwright/**/*.js`), since the file paths differ per repo and can't be generalised
100
106
  - Test-file rule relaxations (e.g. turning off `vite-plus/prefer-vite-plus-imports` in `*.d.ts`)
101
- - Additional plugins — only repos that need them
107
+ - Additional plugins, only for repos that need them
102
108
 
103
109
  ## Merge semantics
104
110
 
105
111
  When a consumer stub extends a shared layer:
106
112
 
107
- - **Rules** shallow-merge by key — the consumer's value wins for any rule defined in both
108
- - **Overrides** are additive — both shared and local `overrides` entries apply, including any `env` declared inside an override block
109
- - **Plugins** are additive — both shared and local `plugins`/`jsPlugins` are loaded (deduplicated)
113
+ - **Rules** shallow-merge by key: the consumer's value wins for any rule defined in both
114
+ - **Overrides** are additive: both shared and local `overrides` entries apply, including any `env` declared inside an override block
115
+ - **Plugins** are additive: both shared and local `plugins`/`jsPlugins` are loaded (deduplicated)
110
116
 
111
117
  ### Known oxlint limitation: top-level `env`, `globals`, and `ignorePatterns` don't merge through `extends`
112
118
 
113
- oxlint currently drops top-level `env`, `globals`, and `ignorePatterns` from an extended config file entirely — they only take effect if declared directly in the file oxlint is invoked with. This is an open upstream bug: [oxc-project/oxc#20087](https://github.com/oxc-project/oxc/issues/20087) (open as of oxlint 1.72.0).
119
+ oxlint currently drops top-level `env`, `globals`, and `ignorePatterns` from an extended config file entirely: they only take effect if declared directly in the file oxlint is invoked with. This is an open upstream bug: [oxc-project/oxc#20087](https://github.com/oxc-project/oxc/issues/20087) (open as of oxlint 1.72.0).
114
120
 
115
121
  In practice this means:
116
122
 
117
- - `base.json`'s `env` (`builtin`, `browser`) and `vue.json`'s Vue macro `globals` (`defineProps`, `defineEmits`, etc.) will **not** reach a consumer that only does `{ "extends": ["./node_modules/@lewishowles/lint-config/vue.json"] }` — every global from the shared layer will be flagged by `no-undef`.
118
- - Any `ignorePatterns` this package might declare would be silently dropped the same way, so it deliberately ships none — see "What stays repo-local" below.
123
+ - `base.json`'s `env` (`builtin`, `browser`) and `vue.json`'s Vue macro `globals` (`defineProps`, `defineEmits`, etc.) will **not** reach a consumer that only does `{ "extends": ["./node_modules/@lewishowles/lint-config/vue.json"] }`: every global from the shared layer will be flagged by `no-undef`.
124
+ - Any `ignorePatterns` this package might declare would be silently dropped the same way, so it deliberately ships none. See "What stays repo-local" below.
119
125
 
120
126
  Until this is fixed upstream, redeclare the `env`/`globals` you need directly in your project's `.oxlintrc.json`, even though `base.json`/`vue.json` already declare them:
121
127
 
@@ -135,3 +141,18 @@ Until this is fixed upstream, redeclare the `env`/`globals` you need directly in
135
141
  "ignorePatterns": ["**/dist/*", ".codebase-memory/**"]
136
142
  }
137
143
  ```
144
+
145
+ ### Known limitation: `vite-plus`'s `lint` config field requires resolved objects, not string paths
146
+
147
+ Raw oxlint (CLI, editor integrations) accepts `"extends": ["./node_modules/@lewishowles/lint-config/vue.json"]` as string paths and resolves them at load time. `vite-plus`, when a project routes its oxlint config through `vite.config.js`'s `lint` field (importing `.oxlintrc.json` as JSON and handing it to `vp check`/`vp lint`), does not resolve string paths in `extends`: every entry, at every nesting level, must already be a plain object. This means `vue.json`'s own internal `extends: ["./base.json"]` also breaks one level deeper.
148
+
149
+ If your project uses `vite-plus`'s `lint` field rather than raw oxlint, resolve the chain yourself in `vite.config.js`:
150
+
151
+ ```js
152
+ import base from "@lewishowles/lint-config/base.json" with { type: "json" };
153
+ import vue from "@lewishowles/lint-config/vue.json" with { type: "json" };
154
+
155
+ const lint = { ...vue, extends: [base, ...(vue.extends ?? [])] };
156
+ ```
157
+
158
+ `.oxlintrc.json` itself should stay untouched (string `extends`) for raw oxlint/editor consumption; this only applies to the `vite-plus` config path.
package/base.json CHANGED
@@ -25,6 +25,12 @@
25
25
  "no-unexpected-multiline": "error",
26
26
  "no-useless-assignment": "error",
27
27
  "preserve-caught-error": "error",
28
+ "sort-imports": [
29
+ "error",
30
+ {
31
+ "ignoreDeclarationSort": true
32
+ }
33
+ ],
28
34
 
29
35
  "@stylistic/no-confusing-arrow": "error",
30
36
  "@stylistic/padding-line-between-statements": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lewishowles/lint-config",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Shared oxlint configuration for Lewis Howles projects",
5
5
  "keywords": [
6
6
  "config",