# code-inspector's farm and rsbuild examples pass a bundler name that is not their own

> A build plugin that makes a click on a page element open your editor with the cursor placed at that element's source location. It ships seven bundler integrations and seven framework integrations across a pnpm workspace, with the esbuild case requiring the caller to declare the environment.

**zh-lx/code-inspector** — 🚀 Click the dom to open your IDE and position the cursor at dom's source code location! 点击页面 dom 来打开 IDE 并将光标自动定位到源代码位置!

- Repository: https://github.com/zh-lx/code-inspector
- Website: https://inspector.fe-dev.cn
- Stars: 3,037 · Forks: 243
- Language: TypeScript
- License: MIT
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/zh-lx-code-inspector

## The whole feature is one sentence, and the package is not named after the repository

The README's entire description of what the tool does fits in one line: click the element on the page, and it automatically opens the code editor and positions the cursor at the source code of that element.

Everything else in the file is the integration surface, which is where the useful detail lives.

The naming has three layers. The repository is one name. The workspace root package is a second, and it is marked private at version zero point zero point one, which is the conventional placeholder for a workspace root that is never published. And the thing you install from the package registry is a third name, with a plugin suffix. The install commands all use that third name.

The documentation has two versions too. The default landing page is Chinese, and English sits under a path suffix on the same domain.

The interesting consequence is that the private zero version is the only version string in the tree. A reader who wants to know what version of the plugin they would install cannot learn it from this repository's manifest, and the project publishes no release tags to look up either.

What you install is the third name, added as a development dependency, with one command per package manager:

```
npm i code-inspector-plugin -D
# or
yarn add code-inspector-plugin -D
# or
pnpm add code-inspector-plugin -D
```

That the flag is a development dependency rather than a runtime one is the only guidance the file gives about when the plugin should be active, and it lines up with the rest: what it does, it does at build time and in a dev server.

What it is, though, is unambiguous: a build-time transform plus a development-server behaviour, wired into whichever bundler you already use.

## Seven bundlers, and two of the examples name a different bundler than their own

The support table lists seven bundlers: webpack, vite, rspack and rsbuild counted as one entry, farm, esbuild, turbopack and mako. Seven web framework groups follow, from vue through astro.

The configuration examples are where the table stops being a list. Each one is a collapsed block named after the tool, and most of them are the same shape: import the plugin, pass a bundler option, put the result in a plugins array.

Two are not.

The rsbuild example passes the bundler option as the rspack value, not as rsbuild, and nests the plugin inside a tools object under the rspack key. So a reader who assumes the option takes the name of the tool in front of them writes the wrong string.

The farm example is stranger. It passes the bundler option as the vite value, and places the result in an array named for vite plugins rather than farm's own plugin list.

That is defensible, because both tools sit on top of something else: rsbuild is a layer over rspack, and farm exposes a compatibility surface for vite plugins. But the README does not say so, and the option is presented identically in all seven blocks. The name of the option reads as the name of the tool in six blocks and as the underlying bundler in two.

## esbuild is the one bundler where the caller declares the environment

Six of the seven examples are static. The esbuild one is not, and it carries the only inline comment in the configuration section.

The esbuild example takes a second option, a function that returns whether this is a development build. The note beside it is in Chinese and it says the return value has to be judged by the caller from the environment: true for local development, false for a production build.

That is a real difference in the contract. Every other bundler gives the plugin enough context to tell a dev server from a production build, because the plugin is handed the bundler's own configuration object. The esbuild build call is not, so the plugin cannot work it out and the project pushes the judgement back to the user.

It also means the esbuild integration has a footgun that the others do not: a function that returns the wrong thing does not fail loudly. It quietly includes or excludes the instrumentation depending on which way the predicate is written, and the symptom would be a plugin that works locally and does nothing in a deployed build, or the reverse.

Two of the seven blocks also differ in module style: webpack, rspack, rsbuild, esbuild and vue-cli use the CommonJS require and a module export, while vite, farm, nuxt and the newer next.js cases use ES module imports. So the import line itself is not constant across the examples either.

## The next.js integration is written three times for three version ranges

The next.js block is the longest in the file and the only one split by version rather than by tool, and it is worth reading as a maintenance statement rather than as three snippets.

The first case, for versions up to and including 14, extends the webpack configuration function and pushes the plugin onto its plugin list with the webpack bundler value. The second, for a narrow range in the 15 series, uses an experimental block and hands the plugin to a turbo rules key with the turbopack value. The third, for later 15 releases, uses a top-level block instead of the experimental one, with the same value.

So the same framework needs the plugin in three different places depending on a version number, and the middle case is narrower than the two around it. That is a moving surface: a next.js upgrade can move the integration from one block to another with nothing else in the project changing.

Nuxt is split the same way, twice, with a different mechanism for each major version: a vite plugins array for the current line and an extend function on the build object for the previous one. The older vue-cli integration takes a third route again, walking a chainable webpack configuration and registering the plugin by name on it.

One more block, for umi.js, begins and is cut off at the heading in the text available here, so its configuration is not visible.

## The editor half of the feature is a separate project, pinned here exactly

The support heading promises three things: which compilers, which web frameworks and which editors. Two of them are listed. The third is not.

Instead of an editor list there are two links. One points at a readme in a different repository by the same author, and the other points at a page on the documentation site under a path about editors.

That separate repository is not incidental. It appears in the development dependencies of the workspace root at an exact version rather than a range, which is the only exactly pinned dependency visible in that block apart from one coverage package. So the code that actually launches the editor is an external project at a fixed version, and this repository's own version of it will not move on its own.

That arrangement has an upside and a downside. The upside is that editor support can be extended without touching the plugin, and one project can serve several tools from the same author. The downside is visible from the support table: the set of editors is not something you can read here, and the thing that determines it lives in a repository with its own release schedule.

The npm badge row also includes a download comparison chart, which is the one piece of the header that reports on usage rather than linking to a destination.

## postinstall runs a build, and the beta publish path skips the git checks

The workspace root's script block is the most revealing file in the repository, and three entries stand out.

The first is the install hook, which runs a build across every workspace package. A postinstall that builds is not unusual in a monorepo where the workspace packages depend on each other's output, but it means that installing this repository does work beyond fetching, and it happens before you have asked for anything.

The second is the pair of publish scripts. The main one runs the publish task across all packages. The beta variant runs a different task and passes a flag telling it not to perform git checks. So the stable publish path validates the repository state and the beta path deliberately does not, which is the usual reason to want a beta escape hatch and also the reason a beta can ship something the stable path would have refused.

The third is the version block. Five scripts call one node helper with different arguments: major, minor, patch, prod and beta. Four of those are ordinary bumps. The fifth sets a production version directly, which is a release action rather than a version bump, available as a one-line script to anyone with the repository.

Documentation has its own path: built from a separate workspace, zipped by a node script, and deployed by a shell script that the deploy script chains.

## Two test runners, a two-level end-to-end suite, and a shell block fenced as perl

Testing is split across two runners, which matches the two things this project has to check.

The unit side is a single script running the faster test runner with coverage enabled, configured by a config file at the root. The end-to-end side is a browser automation runner with its own config directory, and it is split into levels: one script runs a smoke test and another runs a locate test, both passing a name filter to the same runner.

Those two level names are the clearest statement of the project's priorities in the tests. A smoke test that the plugin loads and does not break the page is a different commitment from a locate test that a click lands the cursor in the right file, and the second is the feature.

There is a build step wired in front of the end-to-end run, so the suite runs against freshly built packages rather than the source tree.

Two smaller things. The repository holds a local demos directory as well as the seven hosted demos the README links, each hosted demo pointing at a specific starter template with the config file named in the link's query. And the install block, which contains three shell commands for three package managers, is fenced with a language tag for a different language entirely.

## Conclusion

code-inspector fits a front-end team that wants a click in the browser to land in the right file, and that has settled which bundler it uses. Three things to check before adopting it. The bundler option does not always take the name of the tool you are configuring, because two of the seven examples pass a different value, so copying the wrong example fails quietly. The editor half of the feature is not in this repository at all: the support table links out to a separate project by the same author, which is also an exactly pinned dependency here. And the integration surface is version-sensitive, since the next.js example is written three separate times for three version ranges and the nuxt example twice.

## FAQ

### What is code-inspector?

A build plugin that makes a click on a page element open your code editor with the cursor placed at that element's source location. The published package is `code-inspector-plugin`; the repository is a pnpm workspace whose root package is marked private at version 0.0.1, and the project publishes no release tags.

### Which bundlers and frameworks does code-inspector support?

Seven bundlers are listed, covering webpack, vite, rspack and rsbuild, farm, esbuild, turbopack and mako. Seven framework groups are listed, from vue2, vue3 and nuxt through react, next.js and umi, to preact, solid, qwik, svelte and astro. The editor list is not in the README; it links to a separate project by the same author, which is an exactly pinned development dependency here.

### How do I install code-inspector?

One command, three package managers, all adding it as a development dependency: `npm i code-inspector-plugin -D`, `yarn add code-inspector-plugin -D`, or `pnpm add code-inspector-plugin -D`. You then add it to your bundler configuration. The placement differs per bundler and, for next.js and nuxt, per framework version, so the per-bundler blocks in the README or the configuration page on the docs site are the part to read.

### what is code inspector

The phrase usually means a building or trade inspector, or an inspection role in a SAP code workflow, and neither is this project. Here it is a build plugin that locates a page element's source in an editor, published to the package registry as code-inspector-plugin.

## Sources

- [Issues](https://github.com/zh-lx/code-inspector/issues)
- [License: MIT](https://github.com/zh-lx/code-inspector/blob/main/LICENSE)
- [Project website](https://inspector.fe-dev.cn)
- [README](https://github.com/zh-lx/code-inspector/blob/main/README.md)
- [zh-lx/code-inspector on GitHub](https://github.com/zh-lx/code-inspector)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/zh-lx-code-inspector
