Repository navigation
feat: oxlint-tailwindcss/config, the plugin for extends (#218) - #225
Merged
Merged
Conversation
A preset published as a package couldn't rely on listing "oxlint-tailwindcss"
in jsPlugins: oxlint resolves a plugin's bare name from where it runs, not from
the config that lists it — a pnpm bin shim's NODE_PATH happens to reach a
hoisted copy, a plain `node …/bin/oxlint` (an editor, hoist=false) doesn't —
and it rejects a relative specifier in an extended config.
`import tailwindcss from 'oxlint-tailwindcss/config'`; `tailwindcss()` returns
`{ jsPlugins: [<absolute dist/index.mjs>], rules }` — the recommended rules at
their severities, or none with `{ recommended: false }` — for `extends` in an
oxlint.config.ts or in a shared config. It takes no settings and throws if
given one: oxlint never reads `settings` from an extended config (JSON or TS),
so an entryPoint passed through it would vanish; the project sets
settings.tailwindcss itself.
- A second build entry, src/config.ts, behind exports["./config"], importing
nothing at runtime from index: no shared chunk, dist/index.cjs is still
`module.exports = plugin`. The recommended rules are the static
src/recommended.ts, held to each rule's meta.docs.recommended by a test. The
function is exported by name and default, so the .d.cts matches the CJS
shape; index.mjs because the bare name resolves there (both register one
plugin).
- A relative entryPoint (and no-borrowed-component-styles' `components`)
anchors to every config name oxlint discovers — .oxlintrc.json(c),
oxlint.config.ts/.mts — not .oxlintrc.json only; never vite.config.*.
- Floors of oxlint.config.ts with object extends: oxlint 1.45.0 (1.43 rejects
objects; 1.44 was never published) on Node 22.18.0 (type stripping). A new CI
floors leg runs oxlint-floor-smoke.mjs's second phase there; docs-sync holds
/setup to it.
Tests: e2e config-helper with the real oxlint run WITHOUT NODE_PATH — /setup's
snippet (EN = ES) linted and type-checked with CJS and ESM consumers, a shared
config with the plugin only as its dependency, recommended: false, a nested
oxlint.config.ts anchoring its entryPoint, a setting failing where it's
written, the bare name alongside, the built package's exports and layout — and
two canaries for the oxlint behaviours the helper is shaped around. Loader
tests for the four config names; an old loader fails four of them.
Docs: /setup (EN/ES) "With oxlint.config.ts, or in a shared config"; the
anchoring text in /setup, /settings, /monorepo and no-borrowed-component-
styles; package README; CLAUDE.md. Bench identical.
Claude-Session: https://claude.ai/code/session_019vTh6S5A41M1HLkmk3FaM1
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #218.
Summary
A preset published as a package couldn't rely on
"oxlint-tailwindcss"injsPlugins, for two reasons:NODE_PATHhappens to reach a hoisted copy; a plainnode …/bin/oxlint(an editor,hoist=false) doesn't.oxlint-tailwindcss/configfixes that:tailwindcss()returns:{ jsPlugins: [<absolute dist/index.mjs>], rules }, with the recommended rules at their severities.{ recommended: false }registers the plugin alone.settingsfrom an extended config, in JSON or TS (verified, and pinned as a canary). The project setssettings.tailwindcssitself.src/config.ts,exports["./config"]) with nothing imported at runtime fromindex. No chunk is shared, anddist/index.cjsis stillmodule.exports = plugin. The recommended map is static and a test holds it equal to each rule'smeta.entryPoint(andno-borrowed-component-styles'components) now anchors to every config name oxlint discovers (.oxlintrc.json(c),oxlint.config.ts/.mts), not.oxlintrc.jsononly.extends; 1.44 doesn't exist) on Node 22.18.0 (type stripping). A new CI floors leg runs the smoke's second phase there, anddocs-syncholds/setupto it.Test plan
config-helper, using the real oxlint run withoutNODE_PATH:/setup's snippet (EN = ES), linted and type-checked, plus CJS and ESM consumers;recommended: false;oxlint.config.tsanchoring its entry point;oxlint-floor-smoke.mjs: 1.43.0 skips the helper phase; 1.45.0 and 1.87.0 pass it.lint:types,format:check, typecheck, build andpnpm test(3769 + 312); benchnpm test. The corpus and synthetic runs are identical to the baseline.interop.mjspasses.🤖 Generated with Claude Code
https://claude.ai/code/session_019vTh6S5A41M1HLkmk3FaM1