oxc-remove-attributes
v0.1.1
Published
Vite/Rolldown plugin that strips JSX attributes (e.g. data-testid) from production builds using oxc + magic-string. Drop-in replacement for @swc/plugin-react-remove-properties on Vite 8 / @vitejs/plugin-react (oxc).
Maintainers
Readme
oxc-remove-attributes
A Vite/Rolldown plugin that removes JSX attributes (e.g. data-testid) from production builds. Parses with oxc and emits accurate sourcemaps via magic-string.
Intended as a replacement for @swc/plugin-react-remove-properties after the move from @vitejs/plugin-react-swc to the oxc-based @vitejs/plugin-react in Vite 8, where no oxc equivalent of that SWC plugin exists.
Install
yarn add -D oxc-remove-attributesor
npm i --save-dev oxc-remove-attributesUsage
In vite.config.ts or vite.config.js:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { removeAttributes } from "oxc-remove-attributes";
export default defineConfig({
plugins: [react(), removeAttributes()],
});By default the plugin only runs during vite build, so data-testid attributes remain in dev and in vite build --mode test builds used by e2e suites.
Options
removeAttributes({
// Attribute names to remove (exact match).
attributes: ["data-testid"],
// File extensions to scan.
extensions: [".tsx", ".jsx"],
// When this plugin runs in the Vite pipeline.
enforce: "pre",
// Active in 'build', 'serve', or 'both'.
apply: "build",
});Strip multiple attributes
removeAttributes({
attributes: ["data-testid", "data-cy", "data-test"],
});Always active (incl. dev server)
removeAttributes({ apply: "both" });Limitations
The plugin operates on JSX attributes statically. It will not strip targets that arrive at runtime via a spread, e.g.:
const props = { "data-testid": "x" };
<div {...props} />;If you rely on the bundle being completely free of test IDs, either avoid spreading them or pair this plugin with an oxlint / eslint rule that forbids data-testid in the value side of a spread source.
Namespaced attributes (xlink:href, xml:lang, etc.) and component-prop attributes whose names don't match exactly are also untouched by design.
Prop-chain pass-through
The plugin matches attribute names exactly. A component that accepts a camelCase prop and forwards it to a DOM data-testid looks like this:
// Consumer
<Modal dataTestId="checkout-modal" />;
// Inside Modal.tsx
<div data-testid={dataTestId}>{children}</div>;With the default attributes: ['data-testid'], the DOM data-testid={dataTestId} is stripped (production DOM is clean), but the dataTestId prop is not — "checkout-modal" survives in the bundle as a JSX prop value even though it's never written to the DOM.
If you want to strip prop pass-through too, include both names:
removeAttributes({ attributes: ["data-testid", "dataTestId"] });License
ISC
