mirror of
https://github.com/oxc-project/oxc.git
synced 2026-09-14 19:36:11 +08:00
9fd3bd6605
Alternative to #18796. Part of #18610. ## Overview Add `@oxlint/plugins` package. `@oxlint/plugins` package has no dependency on `oxlint`, which solves the problem raised in https://github.com/oxc-project/oxc/pull/18796#discussion_r2751286894, and is also what we wanted in the end anyway. We don't actually want plugins packages to have to depend on `oxlint`. ## Differences from other Oxc packages This package is different from all our other packages, in that it's intended to work not only with Oxlint's ecosystem, but also with ESLint's ecosystem. `@oxlint/plugins` will be a *runtime* dependency of plugin packages that the community create, and they may want their plugin to be compatible with both Oxlint and ESLint - this package provides the `eslintCompatPlugin` function for exactly this purpose. Our aim is to allow plugin authors to migrate from ESLint's `create` API to Oxlint's `createOnce` API with minimum friction, and without breaking changes for their users: 1. Their plugin should remain compatible with ESLint. 2. They do not need to alter the versions of NodeJS they support (no change to `engines` field in `package.json`). 3. They can continue to publish their plugin as a CommonJS package, if that's the format they currently use. ## Package composition Due to these requirements, the make-up of `@oxlint/plugins` is different from our other packages: ### Dual Format This package is in "dual package" format, with both ESM and CommonJS entry points. ### Older NodeJS versions support This package supports NodeJS versions back to v12.22.0. https://github.com/oxc-project/oxc/blob/9938dc476f8533b7011af03cdbac328b0d00d344/npm/oxlint-plugins/package.json#L40-L42 This matches `engines` field in all ESLint 8.x.x releases: * 8.0.0: https://www.npmjs.com/package/eslint/v/8.0.0?activeTab=code * 8.57.1: https://www.npmjs.com/package/eslint/v/8.57.1?activeTab=code Therefore, `@oxlint/plugins` can be used by any plugin which supports ESLint 8 or later. Note: Download counts for ESLint 8 are still roughly equal to ESLint 9, even though v9 was released 2 years ago. #### Notes * Changing `target` in TSDown to `"node12"` does not result in any changes to built files. See 3rd commit in this PR. * `exports` field in `package.json` is supported (without experimental flag) from NodeJS v12.17.0 + v14.0.0. * `.cjs` file extension supported from NodeJS v12.0.0. ## Building the package This PR adds 2 extra builds to TSDown config, which generate the files for the package. `build.ts` script moves the files into `npm/oxlint-plugins` directory. Later on, we'll move the logic for moving the files into the CI release workflow, so we don't need to check the generated build files into Git. ## `@oxlint/plugins-dev` In #18610 we decided to also add an `@oxlint/plugins-dev` to contain `RuleTester`, so we can move that out of `oxlint` package. This PR *does not* add that package. I've skipped that for now as (a) it's trickier and (b) it's much less important.
2.0 KiB
2.0 KiB
@oxlint/plugins
Plugin utilities for Oxlint.
This package provides optional functions to assist in creating Oxlint JS plugins and rules.
Installation
npm install @oxlint/plugins
Usage
Define functions
Use definePlugin and defineRule if authoring your plugin in TypeScript for type safety.
import { definePlugin, defineRule } from "@oxlint/plugins";
const rule = defineRule({
create(context) {
return {
Program(node) {
// Rule logic here
},
};
},
});
export default definePlugin({
meta: { name: "oxlint-plugin-amazing" },
rules: { amazing: rule },
});
Types
This package also includes types for plugins and rules.
import type { Context, Rule, ESTree } from "@oxlint/plugins";
const rule: Rule = {
create(context: Context) {
return {
Program(node: ESTree.Program) {
// Rule logic here
},
};
},
};
ESLint compatibility
If your plugin uses Oxlint's alternative createOnce API,
use eslintCompatPlugin to convert the plugin so it will also work with ESLint.
import { eslintCompatPlugin } from "@oxlint/plugins";
const rule = {
createOnce(context) {
return {
Program(node) {
// Rule logic here
},
};
},
};
export default eslintCompatPlugin({
meta: { name: "oxlint-plugin-amazing" },
rules: { amazing: rule },
});
Node.js version
This package requires Node.js 12.22.0+, 14.17.0+, 16.0.0+, or later. This matches the minimum Node.js version required by ESLint 8.
This package provides both ESM and CommonJS entry points.
So a plugin which depends on @oxlint/plugins can be:
- Used with any version of Oxlint.
- Used with ESLint 8+.
- Published as either ESM or CommonJS.
Docs
For full documentation, see Oxlint JS Plugins docs.