From 12132d3cdc11ba0fb215d78208c92547b6419b76 Mon Sep 17 00:00:00 2001 From: zthxxx Date: Fri, 7 Jul 2023 23:48:00 +0800 Subject: [PATCH 1/2] feat: compatible with rspack dev-server --- README.md | 155 ++++++++++++++++++----------- examples/nextjs/server.js | 2 - src/Inspector/utils/inspect.ts | 9 +- src/plugins/umi/react-inspector.ts | 2 +- src/plugins/vite/index.ts | 3 - src/plugins/webpack/middlewares.ts | 70 ++++++++++--- 6 files changed, 160 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index 8ece7531..59ef314c 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,9 @@ npm i react-dev-inspector Works with almost all react frameworks such as [Vite](https://github.com/vitejs/vite/tree/main/packages/plugin-react), [Next.js](https://nextjs.org/), + [Rspack](https://www.rspack.dev/), + [Umi4 / Umi3](https://umijs.org/), [Create React App](https://create-react-app.dev/), - [Umi3](https://umijs.org/), [Ice.js](https://ice.work/), or any other which use [@babel/plugin-transform-react-jsx-source](https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx-source) in builtin. @@ -68,8 +69,11 @@ export const Layout = () => { onClickElement={({ codeInfo }: InspectParams) => { if (!codeInfo?.absolutePath) return const { absolutePath, lineNumber, columnNumber } = codeInfo - // you can change the url protocol if you are using in Web IDE + window.open(`vscode://file/${absolutePath}:${lineNumber}:${columnNumber}`) + + // you can change the url protocol if you are using another IDE, like for WebStorm: + // window.open(`webstorm://open?file=${absolutePath}&line=${lineNumber}&column=${columnNumber}`) }} /> )} @@ -80,12 +84,14 @@ export const Layout = () => { ----- -Whether you use `vscode://`, `webstorm://` or otherwise, it solidifies in code. +Whether you use `vscode://`, `webstorm://`, or another protocol, it's hardcoded in the code. + +Sometime you want it **infer** which is the current local IDE you or your different team member are using now. -sometime you want it **infer** which is the current local IDE you are using now. +Sometimes, you might want it to **infer the current local IDE** that you or your team members are using. -But for generally infer current local IDE, **need some server-side configuration**. -At this time, follow those **TWO steps** below: +To generally infer the current local IDE, **server-side configuration is required**. +Follow the **TWO steps** below: ### 1. Add Inspector React Component @@ -106,9 +112,9 @@ export const Layout = () => { {}} - onClickElement={(inspect: InspectParams) => {}} + // keys={['control', 'shift', 'command', 'c']} + // onHoverElement={(inspect: InspectParams) => {}} + // onClickElement={(inspect: InspectParams) => {}} /> )} @@ -120,17 +126,21 @@ export const Layout = () => { ### 2. Set up Inspector Config -You should add: +In server side, You need to add: -- an inspector **babel plugin**, to inject source code location info - - `react-dev-inspector/plugins/babel` -- an server **api middleware**, to open local IDE +- an **server middleware**, to open local IDE - `import { launchEditorMiddleware } from 'react-dev-inspector/plugins/webpack'` +- an _OPTIONAL_ inspector **babel plugin**, to inject source code location info (_relative path_) + - `react-dev-inspector/plugins/babel` to your current project development config. -Such as add **babel plugin** into your `.babelrc` or webpack `babel-loader` config, -add **api middleware** into your `webpack-dev-server` config or other server setup. +Such as add **server middleware** into your `webpack-dev-server` config or other server setup, +add the **babel plugin** (optional) into your `.babelrc` or webpack `babel-loader` config. + +> Note: The `react-dev-inspector/plugins/babel` is **optional**. Most React frameworks/scaffolds already integrate the [@babel/plugin-transform-react-jsx-source](https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx-source) or an equivalent in `swc` to inject the **_absolute path_** for source code on React Fiber, +> +> while the `react-dev-inspector`'s plugin refining to inject the **_relative path_** on DOM for brevity and clarity to debug.
@@ -142,6 +152,7 @@ If your project happen to use vite / nextjs / create-react-app and so on, you ca - [#usage-with-vite2](https://github.com/zthxxx/react-dev-inspector#usage-with-vite2) - [#usage-with-next.js](https://github.com/zthxxx/react-dev-inspector#usage-with-nextjs) +- [#usage-with-rspack](https://github.com/zthxxx/react-dev-inspector#usage-with-rspack) - [#usage-with-create-react-app](https://github.com/zthxxx/react-dev-inspector#usage-with-create-react-app) - [#usage-with-umi3](https://github.com/zthxxx/react-dev-inspector#usage-with-umi3) - [#usage-with-umi2](https://github.com/zthxxx/react-dev-inspector#usage-with-umi2) @@ -149,28 +160,10 @@ If your project happen to use vite / nextjs / create-react-app and so on, you ca -#### raw webpack config +#### Raw Webpack Config Support webpack v4 and v5, examples see: -
-.babelrc.js
- -```js -// .babelrc.js -module.exports = { - plugins: [ - /** - * react-dev-inspector plugin, options docs see: - * https://github.com/zthxxx/react-dev-inspector#inspector-babel-plugin-options - */ - 'react-dev-inspector/plugins/babel', - ], -} -``` - -
-
webpack.config.ts
@@ -192,12 +185,12 @@ const config: Configuration = { } ``` -
+
-However, if you want more manully config with `webpack-dev-server`, here are some equivalent: +However, if you want more manually config with `webpack-dev-server`, here are some equivalent:
-webpack.config.ts
+webpack.config.ts (for webpack-dev-server)
```ts // webpack.config.ts @@ -208,7 +201,7 @@ const config: Configuration = { devServer: { /** * react-dev-inspector - dev server config - * for create-react-app@^5 + webpack-dev-server@^4.7 + * for webpack-dev-server@^4 */ setupMiddlewares: (middlewares, devServer) => { middlewares.unshift(launchEditorMiddleware) @@ -217,7 +210,7 @@ const config: Configuration = { /** * react-dev-inspector - dev server config - * for create-react-app@^4 + webpack-dev-server@^3 + * for webpack-dev-server@^3 */ before: (app, server, compiler) => { app.use(launchEditorMiddleware) @@ -228,10 +221,31 @@ const config: Configuration = { } ``` -
+ -#### usage with [Vite2](https://vitejs.dev) +
+.babelrc.js
+ +```js +// .babelrc.js +module.exports = { + plugins: [ + /** + * react-dev-inspector plugin, options docs see: + * https://github.com/zthxxx/react-dev-inspector#inspector-babel-plugin-options + */ + 'react-dev-inspector/plugins/babel', + ], +} +``` + +

+ + +#### Usage with [Vite2](https://vitejs.dev) + +compatible with vite@3 / vite@4. > example project see: https://github.com/zthxxx/react-dev-inspector/tree/master/examples/vite2 @@ -256,10 +270,10 @@ export default defineConfig({ }) ``` -
+
-#### usage with [Next.js](https://nextjs.org/) +#### Usage with [Next.js](https://nextjs.org/) use Next.js [Custom Server](https://nextjs.org/docs/advanced-features/custom-server) + [Customizing Babel Config](https://nextjs.org/docs/advanced-features/customizing-babel-config) @@ -272,7 +286,6 @@ use Next.js [Custom Server](https://nextjs.org/docs/advanced-features/custom-ser ... const { - queryParserMiddleware, launchEditorMiddleware, } = require('react-dev-inspector/plugins/webpack') @@ -285,7 +298,6 @@ app.prepare().then(() => { /** * react-dev-inspector configuration, two middlewares for nextjs */ - queryParserMiddleware, launchEditorMiddleware, /** Next.js default app handle */ @@ -308,7 +320,7 @@ app.prepare().then(() => { }) ``` -
+
package.json
@@ -321,7 +333,7 @@ app.prepare().then(() => { } ``` -
+
.babelrc.js
@@ -338,10 +350,36 @@ module.exports = { } ``` -
+
+ +#### Usage with [Rspack](https://www.rspack.dev) + + +
+rspack.config.ts
+ +```ts +import { defineConfig } from '@rspack/cli' +import { launchEditorMiddleware } from 'react-dev-inspector/plugins/webpack' + +export default defineConfig({ + devServer: { + /** + * react-dev-inspector server config for rspack + */ + setupMiddlewares(middlewares) { + middlewares.unshift(launchEditorMiddleware) + return middlewares + }, + }, +}) +``` + +

+ -#### usage with create-react-app +#### Usage with create-react-app create-react-app + [react-app-rewired](https://github.com/timarney/react-app-rewired) + [customize-cra](https://github.com/arackaf/customize-cra) example `config-overrides.js`: @@ -412,10 +450,10 @@ module.exports = { } ``` -
+
-#### usage with [Umi3](https://umijs.org/) +#### Usage with [Umi3](https://umijs.org/) > example project see: https://github.com/zthxxx/react-dev-inspector/tree/master/examples/umi3 @@ -438,10 +476,10 @@ export default defineConfig({ }) ``` -
+
-#### usage with [Umi2](https://v2.umijs.org) +#### Usage with [Umi2](https://v2.umijs.org)
.umirc.dev.ts
@@ -479,10 +517,10 @@ export default { } ``` -
+
-#### usage with [Ice.js](https://ice.work/) +#### Usage with [Ice.js](https://ice.work/)
build.json
@@ -496,7 +534,7 @@ export default { } ``` -
+
@@ -600,13 +638,14 @@ This package uses `react-dev-utils` to launch your local IDE application, but, w In fact, it uses an **environment variable** named **`REACT_EDITOR`** to specify an IDE application, but if you do not set this variable, it will try to open a common IDE that you have open or installed once it is certified. -For example, if you want it always open VSCode when inspection clicked, set `export REACT_EDITOR=code` in your shell. +For example, if you want it always open VSCode when inspection clicked, set `export REACT_EDITOR=code` in your shell config like `.bashrc` or `.zshrc`, don't forget restart shell or IDE to reload the updated environment variable.
#### VSCode -- install VSCode command line tools, [see the official docs](https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line) +- install VSCode command line tools, [follow the official docs](https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line), + you need to run the command: `>Shell Command: Install 'code' command in PATH` ![install-vscode-cli](./docs/images/install-vscode-cli.png) - set env to shell, like `.bashrc` or `.zshrc` diff --git a/examples/nextjs/server.js b/examples/nextjs/server.js index 3f142e2d..f8d5108e 100644 --- a/examples/nextjs/server.js +++ b/examples/nextjs/server.js @@ -1,7 +1,6 @@ const { createServer } = require('http') const next = require('next') const { - queryParserMiddleware, launchEditorMiddleware, } = require('react-dev-inspector/plugins/webpack') @@ -19,7 +18,6 @@ app.prepare().then(() => { /** * react-dev-inspector configuration two middlewares for nextjs */ - queryParserMiddleware, launchEditorMiddleware, /** Next.js default app handle */ diff --git a/src/Inspector/utils/inspect.ts b/src/Inspector/utils/inspect.ts index 87379d04..4cf5bf19 100644 --- a/src/Inspector/utils/inspect.ts +++ b/src/Inspector/utils/inspect.ts @@ -65,9 +65,14 @@ export const getCodeInfoFromDebugSource = (fiber?: Fiber): CodeInfo | undefined columnNumber: String(columnNumber ?? 1), /** - * fileName in debugSource is absolutely + * `fileName` in `_debugSource` is absolutely + * --- + * + * compatible with the incorrect `fileName: ""` by [rspack](https://github.com/web-infra-dev/rspack) */ - absolutePath: fileName, + absolutePath: fileName.match(/^<.*>$/) + ? fileName.replace(/^<|>$/g, '') + : fileName, } } diff --git a/src/plugins/umi/react-inspector.ts b/src/plugins/umi/react-inspector.ts index ed0ebb45..952fdeb0 100644 --- a/src/plugins/umi/react-inspector.ts +++ b/src/plugins/umi/react-inspector.ts @@ -28,7 +28,7 @@ export default function inspectorPlugin(api: IApi) { // @ts-ignore api.addBeforeBabelPlugins(() => [ [ - require.resolve('@react-dev-inspector/babel-plugin'), + require.resolve('react-dev-inspector/plugins/babel'), { cwd: inspectorConfig?.cwd, excludes: [ diff --git a/src/plugins/vite/index.ts b/src/plugins/vite/index.ts index a0447a12..6b4bb38f 100644 --- a/src/plugins/vite/index.ts +++ b/src/plugins/vite/index.ts @@ -1,14 +1,11 @@ import type { Plugin } from 'vite' import { - queryParserMiddleware, launchEditorMiddleware, } from '../webpack/middlewares' export const inspectorServer = (): Plugin => ({ name: 'inspector-server-plugin', configureServer(server) { - server.middlewares.use(queryParserMiddleware) - server.middlewares.use(launchEditorMiddleware) }, }) diff --git a/src/plugins/webpack/middlewares.ts b/src/plugins/webpack/middlewares.ts index d88f1cd1..ca7d091d 100644 --- a/src/plugins/webpack/middlewares.ts +++ b/src/plugins/webpack/middlewares.ts @@ -1,12 +1,21 @@ import path from 'path' import type { NextHandleFunction, IncomingMessage } from 'connect' import type { RequestHandler } from 'express' -import createReactLaunchEditorMiddleware from 'react-dev-utils/errorOverlayMiddleware' + +/** + * https://github.com/facebook/create-react-app/blob/v5.0.1/packages/react-dev-utils/launchEditorEndpoint.js + * used in https://github.com/facebook/create-react-app/blob/v5.0.1/packages/react-dev-utils/errorOverlayMiddleware.js#L14 + */ import launchEditorEndpoint from 'react-dev-utils/launchEditorEndpoint' +import createReactLaunchEditorMiddleware from 'react-dev-utils/errorOverlayMiddleware' -const reactLaunchEditorMiddleware: RequestHandler = createReactLaunchEditorMiddleware() +const reactLaunchEditorMiddleware: RequestHandler = createReactLaunchEditorMiddleware() +/** + * @deprecated no longer necessary to use `queryParserMiddleware` directly, + * which has been integrated into the `launchEditorMiddleware` + */ export const queryParserMiddleware: NextHandleFunction = (req: IncomingMessage & { query?: Object }, res, next) => { if (!req.query && req.url) { const url = new URL(req.url, 'https://placeholder.domain') @@ -17,22 +26,53 @@ export const queryParserMiddleware: NextHandleFunction = (req: IncomingMessage & export const launchEditorMiddleware: RequestHandler = (req, res, next) => { - if (req.url.startsWith(launchEditorEndpoint)) { + if (!req.url?.startsWith(launchEditorEndpoint)) { + return next() + } + + queryParserMiddleware(req, res, () => {}) + + if (!req.query.fileName) { + return next() + } + + if (!('REACT_EDITOR' in process.env)) { /** - * retain origin endpoint for backward compatibility <= v1.2.0 + * If not set `REACT_EDITOR` in environment variables, set default to `vscode`. + * - (`code` is cli command installed by `vscode`: `>Shell Command: Install 'code' command in PATH`) + * - link: https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line + * + * --- + * + * `REACT_EDITOR` env var is used in `react-dev-utils/launchEditor`, + * for launch editor(IDE) in backend of `REACT_EDITOR`. + * + * If not provide `REACT_EDITOR`, `react-dev-utils/launchEditor` will guess one editor(IDE) which user opened. + * + * They called "Auto-detect more common editors" -> (https://github.com/facebook/create-react-app/issues/2636) + * + * but sometimes the guess result is wrong, so we make it default to `vscode` for frontend developer. + * + * --- + * + * used in https://github.com/facebook/create-react-app/blob/v5.0.1/packages/react-dev-utils/launchEditor.js#L198 */ - if ( - // relative route used in `Inspector.tsx` `gotoEditor()` - req.url.startsWith(`${launchEditorEndpoint}/relative`) - && typeof req.query.fileName === 'string' - ) { - req.query.fileName = path.join(process.cwd(), req.query.fileName) - } - - reactLaunchEditorMiddleware(req, res, next) - } else { - next() + process.env.REACT_EDITOR = 'code' + } + + /** + * retain origin endpoint for backward compatibility <= v1.2.0 + */ + if ( + // relative route used in `Inspector.tsx` `gotoEditor()` relative path by + // react-dev-inspector's babel plugin + req.url.startsWith(`${launchEditorEndpoint}/relative`) + && typeof req.query.fileName === 'string' + ) { + req.query.fileName = path.join(process.cwd(), req.query.fileName) } + + reactLaunchEditorMiddleware(req, res, next) } /** From e70d64967a6db929a896e2167938d74c137b2526 Mon Sep 17 00:00:00 2001 From: zthxxx Date: Fri, 7 Jul 2023 23:52:00 +0800 Subject: [PATCH 2/2] release: update version to v1.9.0 --- CHANGELOG.md | 18 ++++++++++++++++++ package-lock.json | 7 ++----- package.json | 2 +- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6283f6be..9c3f7ced 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,24 @@ # Changelog +## [1.9.0](https://github.com/zthxxx/react-dev-inspector/compare/v1.8.6...v1.9.0) (2023-08-14) + +### feat + +* compatible with the incorrect `fileName: ""` by [rspack](https://www.rspack.dev/). +* integrate `queryParserMiddleware` into the `launchEditorMiddleware`, then mark `queryParserMiddleware` as deprecated. + +### docs + +* add explain for optional babel plugin +* add example config for rspack +* add example for webstorm url protocol + +### fix + +* fix incorrect resolve path in umi4 plugin + + ## [1.8.6](https://github.com/zthxxx/react-dev-inspector/compare/v1.8.1...v1.8.6) (2023-07-06) ### feat diff --git a/package-lock.json b/package-lock.json index 102a2182..5017b70d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "react-dev-inspector", - "version": "1.8.6", + "version": "1.9.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "react-dev-inspector", - "version": "1.8.6", + "version": "1.9.0", "license": "MIT", "workspaces": [ "examples/*" @@ -60,9 +60,6 @@ "webpack": "4.46.0", "webpack-chain": "6.5.1" }, - "engines": { - "node": ">=12.0.0" - }, "peerDependencies": { "react": ">=16.8.0" } diff --git a/package.json b/package.json index fe10c323..f062fd32 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-dev-inspector", - "version": "1.8.6", + "version": "1.9.0", "sideEffects": false, "description": "dev-tool for inspect react components and jump to local IDE for component code.", "workspaces": [